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

git: do not import/export local branch named "HEAD"

Git CLI rejects it (though the data model would probably work fine with
"HEAD" branch.) This ensures that HEAD@git in JJ world is not an exported
branch named "HEAD".
This commit is contained in:
Yuya Nishihara 2023-07-11 13:40:03 +09:00
parent c1b87d4721
commit 79955d9cb3
2 changed files with 12 additions and 3 deletions

View file

@ -40,7 +40,8 @@ pub enum GitImportError {
fn parse_git_ref(ref_name: &str) -> Option<RefName> {
if let Some(branch_name) = ref_name.strip_prefix("refs/heads/") {
Some(RefName::LocalBranch(branch_name.to_string()))
// Git CLI says 'HEAD' is not a valid branch name
(branch_name != "HEAD").then(|| RefName::LocalBranch(branch_name.to_string()))
} else if let Some(remote_and_branch) = ref_name.strip_prefix("refs/remotes/") {
remote_and_branch
.split_once('/')
@ -59,7 +60,7 @@ fn parse_git_ref(ref_name: &str) -> Option<RefName> {
fn to_git_ref_name(parsed_ref: &RefName) -> Option<String> {
match parsed_ref {
RefName::LocalBranch(branch) => Some(format!("refs/heads/{branch}")),
RefName::LocalBranch(branch) => (branch != "HEAD").then(|| format!("refs/heads/{branch}")),
RefName::RemoteBranch { branch, remote } => {
(branch != "HEAD").then(|| format!("refs/remotes/{remote}/{branch}"))
}

View file

@ -1243,6 +1243,8 @@ fn test_export_partial_failure() {
let target = RefTarget::Normal(commit_a.id().clone());
// Empty string is disallowed by Git
mut_repo.set_local_branch("".to_string(), target.clone());
// Branch named HEAD is disallowed by Git CLI
mut_repo.set_local_branch("HEAD".to_string(), target.clone());
mut_repo.set_local_branch("main".to_string(), target.clone());
// `main/sub` will conflict with `main` in Git, at least when using loose ref
// storage
@ -1250,6 +1252,7 @@ fn test_export_partial_failure() {
assert_eq!(
git::export_refs(mut_repo, &git_repo),
Ok(vec![
RefName::LocalBranch("HEAD".to_string()),
RefName::LocalBranch("".to_string()),
RefName::LocalBranch("main/sub".to_string())
])
@ -1257,6 +1260,7 @@ fn test_export_partial_failure() {
// The `main` branch should have succeeded but the other should have failed
assert!(git_repo.find_reference("refs/heads/").is_err());
assert!(git_repo.find_reference("refs/heads/HEAD").is_err());
assert_eq!(
git_repo
.find_reference("refs/heads/main")
@ -1272,9 +1276,13 @@ fn test_export_partial_failure() {
mut_repo.remove_local_branch("main");
assert_eq!(
git::export_refs(mut_repo, &git_repo),
Ok(vec![RefName::LocalBranch("".to_string())])
Ok(vec![
RefName::LocalBranch("HEAD".to_string()),
RefName::LocalBranch("".to_string())
])
);
assert!(git_repo.find_reference("refs/heads/").is_err());
assert!(git_repo.find_reference("refs/heads/HEAD").is_err());
assert!(git_repo.find_reference("refs/heads/main").is_err());
assert_eq!(
git_repo