forked from mirrors/jj
git: simplify import_head() as it doesn't have to process multiple head commits
This commit is contained in:
parent
fc114ef217
commit
8a67191d25
2 changed files with 28 additions and 40 deletions
|
@ -516,51 +516,35 @@ pub fn import_head(mut_repo: &mut MutableRepo) -> Result<(), GitImportError> {
|
||||||
let git_repo = git_backend.git_repo();
|
let git_repo = git_backend.git_repo();
|
||||||
|
|
||||||
let old_git_head = mut_repo.view().git_head();
|
let old_git_head = mut_repo.view().git_head();
|
||||||
let changed_git_head = if let Ok(head_git_commit) = git_repo.head_commit() {
|
let new_git_head_id = if let Ok(oid) = git_repo.head_id() {
|
||||||
let head_commit_id = CommitId::from_bytes(head_git_commit.id().as_bytes());
|
Some(CommitId::from_bytes(oid.as_bytes()))
|
||||||
let new_head_target = RefTarget::normal(head_commit_id);
|
|
||||||
(*old_git_head != new_head_target).then_some(new_head_target)
|
|
||||||
} else {
|
} else {
|
||||||
old_git_head.is_present().then(RefTarget::absent)
|
None
|
||||||
};
|
};
|
||||||
|
if old_git_head.as_resolved() == Some(&new_git_head_id) {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
// Bulk-import all reachable Git commits to the backend to reduce overhead of
|
// Import new head
|
||||||
// table merging and ref updates.
|
if let Some(head_id) = &new_git_head_id {
|
||||||
let index = mut_repo.index();
|
let index = mut_repo.index();
|
||||||
let missing_head_ids = changed_git_head
|
if !index.has_id(head_id) {
|
||||||
.iter()
|
git_backend.import_head_commits([head_id]).map_err(|err| {
|
||||||
.flat_map(|target| target.added_ids())
|
GitImportError::MissingHeadTarget {
|
||||||
.filter(|&id| !index.has_id(id));
|
id: head_id.clone(),
|
||||||
let heads_imported = git_backend.import_head_commits(missing_head_ids).is_ok();
|
err,
|
||||||
|
}
|
||||||
// Import new remote heads
|
|
||||||
let mut head_commits = Vec::new();
|
|
||||||
let get_commit = |id| {
|
|
||||||
// If bulk-import failed, try again to find bad head or ref.
|
|
||||||
if !heads_imported && !index.has_id(id) {
|
|
||||||
git_backend.import_head_commits([id])?;
|
|
||||||
}
|
|
||||||
store.get_commit(id)
|
|
||||||
};
|
|
||||||
if let Some(new_head_target) = &changed_git_head {
|
|
||||||
for id in new_head_target.added_ids() {
|
|
||||||
let commit = get_commit(id).map_err(|err| GitImportError::MissingHeadTarget {
|
|
||||||
id: id.clone(),
|
|
||||||
err,
|
|
||||||
})?;
|
})?;
|
||||||
head_commits.push(commit);
|
|
||||||
}
|
}
|
||||||
|
// It's unlikely the imported commits were missing, but I/O-related
|
||||||
|
// error can still occur.
|
||||||
|
store
|
||||||
|
.get_commit(head_id)
|
||||||
|
.and_then(|commit| mut_repo.add_head(&commit))
|
||||||
|
.map_err(GitImportError::InternalBackend)?;
|
||||||
}
|
}
|
||||||
// It's unlikely the imported commits were missing, but I/O-related error
|
|
||||||
// can still occur.
|
|
||||||
mut_repo
|
|
||||||
.add_heads(&head_commits)
|
|
||||||
.map_err(GitImportError::InternalBackend)?;
|
|
||||||
|
|
||||||
// Apply the change that happened in git since last time we imported refs.
|
mut_repo.set_git_head_target(RefTarget::resolved(new_git_head_id));
|
||||||
if let Some(new_head_target) = changed_git_head {
|
|
||||||
mut_repo.set_git_head_target(new_head_target);
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -107,10 +107,14 @@ impl RefTarget {
|
||||||
RefTarget { merge }
|
RefTarget { merge }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the underlying value if this target is non-conflicting.
|
||||||
|
pub fn as_resolved(&self) -> Option<&Option<CommitId>> {
|
||||||
|
self.merge.as_resolved()
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns id if this target is non-conflicting and points to a commit.
|
/// Returns id if this target is non-conflicting and points to a commit.
|
||||||
pub fn as_normal(&self) -> Option<&CommitId> {
|
pub fn as_normal(&self) -> Option<&CommitId> {
|
||||||
let maybe_id = self.merge.as_resolved()?;
|
self.as_resolved()?.as_ref()
|
||||||
maybe_id.as_ref()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if this target points to no commit.
|
/// Returns true if this target points to no commit.
|
||||||
|
|
Loading…
Reference in a new issue