Skip to content

Commit

Permalink
git sync: Build update record
Browse files Browse the repository at this point in the history
## Summary
* [X] Get branch pre-fetch heads
* [X] Build candidates from prefetch heads
* [X] Fetch from remotes
* [X] Get branch post-fetch heads
* [ ] Rebase
  * [X] Build old -> new map
  * [ ] transform descendants


## Details
Build a record of old branch heads mapped to the new branch heads.
This record will be used to derive the candidates that need
rebasing.

Issue: #1039
  • Loading branch information
essiene committed Nov 19, 2024
1 parent 7a487b0 commit 650d852
Showing 1 changed file with 50 additions and 2 deletions.
52 changes: 50 additions & 2 deletions cli/src/commands/git/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::fmt;

use clap_complete::ArgValueCandidates;
Expand Down Expand Up @@ -82,15 +84,22 @@ pub fn cmd_git_sync(

let guard = tracing::debug_span!("git.sync.pre-fetch").entered();
let prefetch_heads = get_branch_heads(tx.base_repo().as_ref(), &args.branch)?;
let _candidates = CandidateCommit::get(tx.repo(), &prefetch_heads)?;
let candidates = CandidateCommit::get(tx.repo(), &prefetch_heads)?;
drop(guard);

let guard = tracing::debug_span!("git.sync.fetch").entered();
git_fetch_all(ui, &mut tx, args.all_remotes)?;
drop(guard);

let guard = tracing::debug_span!("git.sync.post-fetch").entered();
let _postfetch_heads = get_branch_heads(tx.repo(), &args.branch)?;
let postfetch_heads = get_branch_heads(tx.repo(), &args.branch)?;
let update_record = UpdateRecord::new(
&tx,
&BranchHeads {
prefetch: &prefetch_heads,
postfetch: &postfetch_heads,
},
);
drop(guard);

let guard = tracing::debug_span!("git.sync.rebase").entered();
Expand Down Expand Up @@ -135,6 +144,45 @@ fn get_branch_heads(

Ok(commits)
}
fn set_diff(lhs: &[CommitId], rhs: &[CommitId]) -> Vec<CommitId> {
BTreeSet::from_iter(lhs.to_vec())
.difference(&BTreeSet::from_iter(rhs.to_vec()))
.cloned()
.collect_vec()
}

struct BranchHeads<'a> {
prefetch: &'a [CommitId],
postfetch: &'a [CommitId],
}

struct UpdateRecord {
old_to_new: BTreeMap<CommitId, CommitId>,
}

impl UpdateRecord {
fn new(tx: &WorkspaceCommandTransaction, heads: &BranchHeads) -> Self {
let new_heads = set_diff(heads.postfetch, heads.prefetch);
let needs_rebase = set_diff(heads.prefetch, heads.postfetch);

let mut old_to_new: BTreeMap<CommitId, CommitId> = BTreeMap::from([]);

for new in &new_heads {
for old in &needs_rebase {
if old != new && tx.repo().index().is_ancestor(old, new) {
old_to_new.insert(old.clone(), new.clone());
}
}
}

for (k, v) in &old_to_new {
let old = short_commit_hash(k);
let new = short_commit_hash(v);
tracing::debug!("rebase children of {old} to {new}");
}

UpdateRecord { old_to_new }
}
#[derive(Eq, Ord, PartialEq, PartialOrd)]
pub struct CandidateCommit {
parent: CommitId,
Expand Down

0 comments on commit 650d852

Please sign in to comment.