ok/jj
1
0
Fork 0
forked from mirrors/jj

cli: automatically update Git refs and HEAD after command if collocated (#44)

This commit is contained in:
Martin von Zweigbergk 2021-12-04 17:54:06 -08:00
parent 9898547932
commit 63d1a87ef3
2 changed files with 34 additions and 10 deletions

View file

@ -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,10 +190,12 @@ 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()?;
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")?;
}

View file

@ -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(())
}
}