Skip to content

Commit

Permalink
git: Refactor reset_head to share set_git_head_target call
Browse files Browse the repository at this point in the history
This shares some common code to both the root and the non-root case, and
provides easier access to `mut_repo` in the function - as
`set_git_head_target` mutably borrows `mut_repo`.

This will be used for a cleaner implementation of #3767.
  • Loading branch information
mlcui-corp committed May 28, 2024
1 parent a075a5c commit ebd1370
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions lib/src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -928,14 +928,20 @@ pub fn reset_head(
wc_commit: &Commit,
) -> Result<(), git2::Error> {
let first_parent_id = &wc_commit.parent_ids()[0];
let first_parent;
if first_parent_id != mut_repo.store().root_commit_id() {
let first_parent = RefTarget::normal(first_parent_id.clone());
first_parent = RefTarget::normal(first_parent_id.clone());
let git_head = mut_repo.view().git_head();
let new_git_commit_id = Oid::from_bytes(first_parent_id.as_bytes()).unwrap();
let new_git_commit = git_repo.find_commit(new_git_commit_id)?;
if git_head == &first_parent {
// `HEAD@git` already points to the correct commit, so we only need to reset
// the Git index. Only do so if it is non-empty (i.e. a user used `git add`).
if git_head != &first_parent {
git_repo.set_head_detached(new_git_commit_id)?;
}

let skip_reset = if git_head == &first_parent {
// `HEAD@git` already points to the correct commit, so we only need to
// reset the Git index. We can skip the reset if the Git index is empty
// (i.e. `git add` was never used).
// In large repositories, this is around 2x faster if the Git index is empty
// (~0.89s to check the diff, vs. ~1.72s to reset), and around 8% slower if
// it isn't (~1.86s to check the diff AND reset).
Expand All @@ -944,15 +950,15 @@ pub fn reset_head(
None,
Some(git2::DiffOptions::new().skip_binary_check(true)),
)?;
if diff.deltas().len() == 0 {
return Ok(());
}
diff.deltas().len() == 0
} else {
git_repo.set_head_detached(new_git_commit_id)?;
mut_repo.set_git_head_target(first_parent);
false
};
if !skip_reset {
git_repo.reset(new_git_commit.as_object(), git2::ResetType::Mixed, None)?;
}
git_repo.reset(new_git_commit.as_object(), git2::ResetType::Mixed, None)?;
} else {
first_parent = RefTarget::absent();
// Can't detach HEAD without a commit. Use placeholder ref to nullify the HEAD.
// We can't set_head() an arbitrary unborn ref, so use reference_symbolic()
// instead. Git CLI appears to deal with that. It would be nice if Git CLI
Expand All @@ -970,8 +976,8 @@ pub fn reset_head(
index.clear()?; // or read empty tree
index.write()?;
git_repo.cleanup_state()?;
mut_repo.set_git_head_target(RefTarget::absent());
}
mut_repo.set_git_head_target(first_parent);
Ok(())
}

Expand Down

0 comments on commit ebd1370

Please sign in to comment.