4

So I have some git repository:

git init
echo "Recipes" > README
git add README

Then I make a branch called "beef" to store all my steak recipes:

git checkout -b beef

A while goes by and then someone makes a commit:

GIT_AUTHOR_DATE='Tue Jan 1 00:00:00 2019 -0400' \
GIT_COMMITTER_DATE='Tue Jan 1 00:00:00 2019 -0400' \
GIT_COMMITTER_NAME='Chef' \
GIT_COMMITTER_EMAIL='<chef@localhost>' \
GIT_AUTHOR_NAME='Chef' \
GIT_AUTHOR_EMAIL='<chef@localhost>' \
git commit -m "New recipe:00100011000001010000000010100000"
git checkout -b master

Uh oh... the commit hash starts with beef! [1] Now, every time I want to switch to my beef branch, I get this annoying message: warning: refname 'beef' is ambiguous.

Worse yet, if I clone the repository elsewhere and try to checkout the beef branch for the first time, I instead end up with a detached head on the beef commit! Of course I can workaround this by doing git checkout --track origin/beef instead of just git checkout beef, but now I need to tell everybody who uses my project about this special workaround.

So, long story short, my question is: I have a branch that is ambiguous with a git commit prefix. How can I tell git once-and-for-all that when I say beef I always want to refer to the branch, not the commit? Ideally this should work for anyone who downloads the repository, but even a fix that just works locally would be nice.

Restrictions:

  • I can't rename/delete the branch. Other people use this project and they expect the branch to be there and to be named beef.
  • I can't amend/remove the offending commit because it has already been pushed to master in a shared repo.
  • I don't really want a temporary workaround like the one mentioned in this question that I'll have to type every time I use the beef branch, I want a way to resolve this problem once and for all.

[1] I spent way too long trying to make that commit have a reproducible hash starting with beef... But yes this is derived from an example I saw in a real repository (branch name changed to protect the innocent).

Flight Odyssey
  • 2,267
  • 18
  • 25
  • 2
    Rename the branch and live happily ever after. – eftshift0 Aug 15 '19 at 03:49
  • @eftshift0 Sure, but (1) I'm not the only person using this repo, I can't just go willy-nilly renaming branches. (2) The branch name does actually provide a meaningful description of its contents, ideally I would like to keep it instead of changing it to something silly like `beef1` or `not-beef` – Flight Odyssey Aug 15 '19 at 03:57
  • 2
    Basically, you can't. This is an argument for putting a non-hexadecimal-character letter into every branch name. (But you *can* use the name `cab` as it's only 3 letters. It's names like `beef`, `cafe`, `babe`, `bead`, `face`, `decade`, and so on that are off limits. You can put hyphens into some, such as the branch whose name commands you to Be Fab(ulous). :-) ) – torek Aug 15 '19 at 04:12
  • Use a branch naming style that cannot conflict with a hash. `feature/beef`, `issue/beef`, `fix/beef`, `refactor/beef`. – Schwern Aug 15 '19 at 08:42

1 Answers1

2

There does not seem to be easy fix for now.

I have checked that setting core.abbrev to an higher number (like 8 or 10 or ... above your branch name length) does not prevent the warning.

It is possible the Git 2.23 command git switch will alleviate the issue, since it only switches branches (while git restore would restore a tree content, and would therefore still be affected, since a tree can be referenced by a commit or a branch)

I just tested it: that warning remains, but at least, you can only switch to branches, so no confusion is possible.


Note: as I mention in "How would Git handle a SHA-1 collision on a blob?", you can use bradfitz/gitbrute to force a commit to a particular SHA1 prefix.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250