forked from mirrors/jj
cli: automatically update Git refs and HEAD after command if collocated (#44)
This commit is contained in:
parent
9898547932
commit
63d1a87ef3
2 changed files with 34 additions and 10 deletions
|
@ -153,8 +153,8 @@ pub fn export_changes(
|
|||
let new_branches: HashSet<_> = new_view.branches().keys().cloned().collect();
|
||||
// TODO: Check that the ref is not pointed to by any worktree's HEAD.
|
||||
let mut active_branches = HashSet::new();
|
||||
if let Ok(head_ref) = git_repo.head() {
|
||||
if let Some(head_target) = head_ref.name() {
|
||||
if let Ok(head_ref) = git_repo.find_reference("HEAD") {
|
||||
if let Some(head_target) = head_ref.symbolic_target() {
|
||||
active_branches.insert(head_target.to_string());
|
||||
}
|
||||
}
|
||||
|
@ -190,9 +190,11 @@ pub fn export_changes(
|
|||
}
|
||||
}
|
||||
if detach_head {
|
||||
let current_git_head_ref = git_repo.head()?;
|
||||
let current_git_commit = current_git_head_ref.peel_to_commit()?;
|
||||
git_repo.set_head_detached(current_git_commit.id())?;
|
||||
if let Ok(head_ref) = git_repo.find_reference("HEAD") {
|
||||
if let Ok(current_git_commit) = head_ref.peel_to_commit() {
|
||||
git_repo.set_head_detached(current_git_commit.id())?;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (git_ref_name, new_target) in refs_to_update {
|
||||
git_repo.reference(&git_ref_name, new_target, true, "export from jj")?;
|
||||
|
|
|
@ -31,7 +31,7 @@ use std::{fs, io};
|
|||
|
||||
use clap::{crate_version, App, Arg, ArgMatches, SubCommand};
|
||||
use criterion::Criterion;
|
||||
use git2::Repository;
|
||||
use git2::{Oid, Repository};
|
||||
use itertools::Itertools;
|
||||
use jujutsu_lib::backend::{BackendError, CommitId, Timestamp, TreeValue};
|
||||
use jujutsu_lib::commit::Commit;
|
||||
|
@ -127,10 +127,6 @@ impl From<GitExportError> for CommandError {
|
|||
"Cannot export conflicted branch '{}'",
|
||||
branch_name
|
||||
)),
|
||||
GitExportError::BranchCheckedOut(branch_name) => CommandError::UserError(format!(
|
||||
"Cannot export branch '{}' because it's checked in the Git repo",
|
||||
branch_name
|
||||
)),
|
||||
GitExportError::InternalGitError(err) => CommandError::InternalError(format!(
|
||||
"Failed to export refs to underlying Git repo: {}",
|
||||
err
|
||||
|
@ -312,6 +308,29 @@ impl WorkspaceCommandHelper {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn export_git_refs_and_head(&mut self) -> Result<(), CommandError> {
|
||||
let repo = self.repo();
|
||||
let git_repo = repo.store().git_repo().unwrap();
|
||||
let current_git_head_ref = git_repo.find_reference("HEAD").unwrap();
|
||||
let current_git_commit_id = current_git_head_ref
|
||||
.peel_to_commit()
|
||||
.ok()
|
||||
.map(|commit| commit.id());
|
||||
git::export_refs(repo, &git_repo)?;
|
||||
let checkout_id = repo.view().checkout();
|
||||
let first_parent_id =
|
||||
repo.index().entry_by_id(checkout_id).unwrap().parents()[0].commit_id();
|
||||
if first_parent_id != *repo.store().root_commit_id() {
|
||||
if let Some(current_git_commit_id) = current_git_commit_id {
|
||||
git_repo.set_head_detached(current_git_commit_id)?;
|
||||
}
|
||||
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)?;
|
||||
git_repo.reset(new_git_commit.as_object(), git2::ResetType::Mixed, None)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn rebase_descendants(mut self, value: bool) -> Self {
|
||||
self.rebase_descendants = value;
|
||||
self
|
||||
|
@ -540,6 +559,9 @@ impl WorkspaceCommandHelper {
|
|||
}
|
||||
}
|
||||
}
|
||||
if self.working_copy_shared_with_git {
|
||||
self.export_git_refs_and_head()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue