git: extract function that resets Git HEAD

I'll add a workaround for the root parent issue #1495 there. We can pass in
the wc parent id instead of the wc_commit object, but we might want to use
wc_commit.id() to generate a unique placeholder ref name.
This commit is contained in:
Yuya Nishihara 2023-10-03 19:11:55 +09:00
parent c0fbe6d238
commit 7ccbc0424c
2 changed files with 22 additions and 10 deletions

View File

@ -27,7 +27,7 @@ use std::time::SystemTime;
use clap::builder::{NonEmptyStringValueParser, TypedValueParser, ValueParserFactory};
use clap::{Arg, ArgAction, ArgMatches, Command, FromArgMatches};
use git2::{Oid, Repository};
use git2::Repository;
use indexmap::IndexSet;
use itertools::Itertools;
use jj_lib::backend::{BackendError, ChangeId, CommitId, MergedTreeId, ObjectId};
@ -43,7 +43,7 @@ use jj_lib::id_prefix::IdPrefixContext;
use jj_lib::matchers::{EverythingMatcher, Matcher, PrefixMatcher, Visit};
use jj_lib::merged_tree::{MergedTree, MergedTreeBuilder};
use jj_lib::op_heads_store::{self, OpHeadResolutionError, OpHeadsStore};
use jj_lib::op_store::{OpStore, OpStoreError, OperationId, RefTarget, WorkspaceId};
use jj_lib::op_store::{OpStore, OpStoreError, OperationId, WorkspaceId};
use jj_lib::operation::Operation;
use jj_lib::repo::{
CheckOutCommitError, EditCommitError, MutableRepo, ReadonlyRepo, Repo, RepoLoader,
@ -849,14 +849,7 @@ impl WorkspaceCommandHelper {
) -> Result<(), CommandError> {
if let Some(wc_commit_id) = mut_repo.view().get_wc_commit_id(self.workspace_id()) {
let wc_commit = mut_repo.store().get_commit(wc_commit_id)?;
let first_parent_id = wc_commit.parent_ids()[0].clone();
if first_parent_id != *mut_repo.store().root_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.set_head_detached(new_git_commit_id)?;
git_repo.reset(new_git_commit.as_object(), git2::ResetType::Mixed, None)?;
mut_repo.set_git_head_target(RefTarget::normal(first_parent_id));
}
git::reset_head(mut_repo, git_repo, &wc_commit)?;
} else {
// The workspace was removed (maybe the user undid the
// initialization of the workspace?), which is weird,

View File

@ -26,6 +26,7 @@ use tempfile::NamedTempFile;
use thiserror::Error;
use crate::backend::{BackendError, CommitId, ObjectId};
use crate::commit::Commit;
use crate::git_backend::GitBackend;
use crate::op_store::{BranchTarget, RefTarget, RefTargetOptionExt};
use crate::repo::{MutableRepo, Repo};
@ -675,6 +676,24 @@ fn update_git_ref(
Ok(())
}
/// Sets `HEAD@git` to the parent of the given working-copy commit and resets
/// the Git index.
pub fn reset_head(
mut_repo: &mut MutableRepo,
git_repo: &git2::Repository,
wc_commit: &Commit,
) -> Result<(), git2::Error> {
let first_parent_id = &wc_commit.parent_ids()[0];
if first_parent_id != mut_repo.store().root_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.set_head_detached(new_git_commit_id)?;
git_repo.reset(new_git_commit.as_object(), git2::ResetType::Mixed, None)?;
mut_repo.set_git_head_target(RefTarget::normal(first_parent_id.clone()));
}
Ok(())
}
#[derive(Debug, Error)]
pub enum GitRemoteManagementError {
#[error("No git remote named '{0}'")]