Refname 不明确

Dan*_*lan 34 git

昨天,我从一个分支创建了一个分支,将其推送到原点,然后将其合并回 master。你可以在这里看到:

$ history |less
 8358  git co master
 8359   commit # shortcut that adds all and commits
 8360  push # shortcut that `git push`'s
 8361  git lg # shortcut that logs my output
 8362  git co 1600
 8363  git co -b 1601
 8364  npm run test
 8365  npm run test
 8366  npm run test
 8367  npm run test
 8368  npm run test
 8369  npm run test
 8370  npm run test
 8371  npm run test
 8372  npm run test
 8373  npm run test
 8374  npm run test
 8375  npm run test
 8376  npm run test
 8377  ./release.sh
 8378  ./release.sh
 8379  commit
 8380  push
 8381      git push --set-upstream origin 1601
 8382  git lg
 8383  git co master
 8384  git merge --no-ff -
 8385  git st
 8386  commit 
 8387  push 
Run Code Online (Sandbox Code Playgroud)

我在这个列表中包含了不相关的东西,所以我不会意外地删掉一些相关的东西;如您所见,所有这些历史都是连续的。以下是我历史上所有与 1601 相关的内容:

$ history |less
 8358  git co master
 8359   commit # shortcut that adds all and commits
 8360  push # shortcut that `git push`'s
 8361  git lg # shortcut that logs my output
 8362  git co 1600
 8363  git co -b 1601
 8364  npm run test
 8365  npm run test
 8366  npm run test
 8367  npm run test
 8368  npm run test
 8369  npm run test
 8370  npm run test
 8371  npm run test
 8372  npm run test
 8373  npm run test
 8374  npm run test
 8375  npm run test
 8376  npm run test
 8377  ./release.sh
 8378  ./release.sh
 8379  commit
 8380  push
 8381      git push --set-upstream origin 1601
 8382  git lg
 8383  git co master
 8384  git merge --no-ff -
 8385  git st
 8386  commit 
 8387  push 
Run Code Online (Sandbox Code Playgroud)

不知何故,在这些步骤之后,无论何时git co 1601,它都会给我这个警告:

$ history | grep 1601
 1601  npm run test
 8363  git co -b 1601
 8381      git push --set-upstream origin 1601
 8438  git co 1601
 8445  git co 1601
 8446  git show-ref 1601
 8447  history | grep 1601
 8449  git show-ref | grep 1601
 8458  git show-ref --heads --tags | grep 1601
 8460  history | grep 1601
 8461  history | grep (1601|merge)
 8462  history | grep -p (1601|merge)
 8464  history | grep -E (1601|merge)
 8466  history | grep -E -e (1601|merge)
 8467  history | grep -E -e \(1601|merge\)
 8468  history | grep -E -e '(1601|merge)'
 8469  history | grep -E -e '(1601|merge|master)'
 8470  history | grep -E -e '(1601|1601|merge|master)'
 8472  history | grep -E -e '(1601|1601|merge|master)'
 8474  history | grep -E -e '(1601|1601|merge|master)'
 8480  history | grep 1601
Run Code Online (Sandbox Code Playgroud)

我已经在谷歌上搜索了一段时间,寻找其他有这个问题的人,但他们似乎都没有同样的情况。这是我看过的没有帮助的内容:

  1. Git 警告:refname 'xxx' 不明确
  2. Git:refname 'master' 不明确
  3. git refname 'origin/master' 不明确
  4. http://thesimplesynthesis.com/post/git-error-warning-refname-originbranch-name-is-ambiguous

以下输出有助于排除故障:

$ git co 1601
warning: refname '1601' is ambiguous.
Already on '1601'
Your branch is up to date with 'origin/1601'.
Run Code Online (Sandbox Code Playgroud)
$ git show-ref | grep 1601
137b74c8ff6807f07bb32ba0d2f76a3ba287e981 refs/heads/1601
137b74c8ff6807f07bb32ba0d2f76a3ba287e981 refs/remotes/origin/1601
Run Code Online (Sandbox Code Playgroud)
$ git tag -l

Run Code Online (Sandbox Code Playgroud)
cat .git/config
# this is the only place where it mentions 1601
[branch "1601"]
        remote = origin
        merge = refs/heads/1601

$ cat .git/config | grep 1601
[branch "1601"]
        merge = refs/heads/1601

Run Code Online (Sandbox Code Playgroud)
$ git show-ref --heads --tags | grep 1601
137b74c8ff6807f07bb32ba0d2f76a3ba287e981 refs/heads/1601
Run Code Online (Sandbox Code Playgroud)
cat .git/config
# this is the only place where it mentions 1601
[branch "1601"]
        remote = origin
        merge = refs/heads/1601

$ cat .git/config | grep 1601
[branch "1601"]
        merge = refs/heads/1601

Run Code Online (Sandbox Code Playgroud)
$ git checkout 1601 --
warning: refname '1601' is ambiguous.
Already on '1601'
Your branch is up to date with 'origin/1601'.
Run Code Online (Sandbox Code Playgroud)
$ git ls-remote . \*1601*
beea6ee68d6fe6b4f5222c0efe0e206e23af993c        refs/heads/1601
beea6ee68d6fe6b4f5222c0efe0e206e23af993c        refs/remotes/origin/1601
Run Code Online (Sandbox Code Playgroud)
$ git show 1601 # this only shows one log message
warning: refname '1601' is ambiguous.
commit beea6ee68d6fe6b4f5222c0efe0e206e23af993c (HEAD -> 1601, origin/1601)
...
Run Code Online (Sandbox Code Playgroud)

FWIW,我在 Windows 上使用 cygwin。

为什么我会收到此警告,如何摆脱它,以及如何在将来防止它?

jth*_*ill 49

我可以通过为分支提供与提交的 SHA1 前缀匹配的名称来获得此行为。

$ git rev-list @ | egrep '^[0-9]{4}'
7802d6937673dbff4d26dc906c714a054c9e883e
81070af68e1b254c7f36eccb1261050a5a4a133a
7537dac08fd165845b6300f32c19a52fc7fa7299
$ git branch 7802
$ git branch 9999
$ git checkout 7802
warning: refname '7802' is ambiguous.
Switched to branch '7802'
$ git checkout 9999
Switched to branch '9999'
$
Run Code Online (Sandbox Code Playgroud)

由于对象 id 前缀至少有四位数字是引用对象的合法方式,因此将引用名称设为四位或更多长的十六进制字符串很可能会产生这种歧义。所以,不要那样做。如果你想给一些东西编号,包括一个类型标记,像bugfix/1601什么的。

  • @DanielKaplan 我认为是的,或者,您也可以将分支名称缩短为 3 个数字而不是 4 个,因为您需要至少 4 个字符来引用提交 ID。无论如何,我通常更喜欢更具描述性的分支名称,但就您而言,即使是像“test-1600”、“build-1600”、“z1600”或任何有意义的名称,也会缓解问题。 (6认同)
  • 哇!感谢您为此付出的一切努力。“为什么我会收到此警告,如何摆脱它,以及如何在将来防止它?”我现在明白为什么,摆脱它的唯一方法是重命名我的分支并在其中添加一个字符这在sha中无效吗? (2认同)

tor*_*rek 14

为什么我会收到此警告...

正如您通过jthill's answer 发现的那样,这是因为1601匹配了一些合适的对象的哈希值。

还有一些其他方法可以获得相同的错误,包括创建具有相同拼写的分支和标记名称(例如,git branch abc; git tag abc)。

我该如何摆脱它...

使用明确的名称。对于 branch-vs-tag,这意味着不要使用与分支和标签名称相同的名称;对于分支或标签与提交哈希,这意味着避免此处可能出现的提交哈希名称。正如TTT 评论的那样,提交哈希缩写必须至少包含四个字符,因此abc即使abc在哈希 ID 中所有三个字符都是合法的,也可以作为分支或标记名称。

要查看分支名称是否可能与哈希 ID 冲突,请检查它是否完全由集合中的字符组成,[0-9][a-f][A-F]并且长度至少为四个字符。如果是这样,请添加一些字符集之外的字符,或缩短名称。快速:

egrep '^[a-f]{4,}$' /usr/share/dict/words
Run Code Online (Sandbox Code Playgroud)

会出现一些有趣的分支名称以避免出现,例如accede, aface, beaded, deed, 和facade。(这些当然是我喜欢作为例子,如使用各种假散列ID的来源feedc0ffeedeadbeefcafedad,等等-一些需要比特11ce45e1与拼写。)

以及我将来如何防止它?

一个非常方便的系统是系统化的分支名称,包括/-或东西:例如,feature/c0ffee从来没有运行到这样的问题。


1 “许可证”,有点类似于 1337-5p34k。


Von*_*onC 5

为什么我会收到此警告,如何摆脱它,以及如何在将来防止它?

首先,确保使用git switch,而不是旧的过时且令人困惑的 git checkout 命令

其次,即使使用git switch,您也会收到警告(即使您已经在该分支上!):

vonc@vclp MINGW64 ~/git/test (29876e)
$ git switch -- 29876e
warning: refname '29876e' is ambiguous.
Already on '29876e'
Run Code Online (Sandbox Code Playgroud)

但是设置core.warnAmbiguousRefsfalse实际上会消除该警告。

$ git -c core.warnAmbiguousRefs=false switch 29876e
Already on '29876e' 
Run Code Online (Sandbox Code Playgroud)

  • Switch 只是一种替代方案,它并没有过时,也没有被弃用,而且很可能不存在于任何旧的手册/文章/教程中+对这个问题的好处为零。 (5认同)

A.H*_*.H. 5

如果您知道ref-name 是一个分支或一个标签,您可以在 id 前加上heads/tags/。所以这有效:

git checkout heads/1601
Run Code Online (Sandbox Code Playgroud)

鉴于<refname>Git 搜索位置列表。这是根据git help revisions页面的列表:

  1. 如果$GIT_DIR/<refname>存在,那就是你的意思(这通常只对HEAD, FETCH_HEAD, ORIG_HEAD,MERGE_HEAD和有用CHERRY_PICK_HEAD);

  2. 否则,refs/<refname>如果存在;

  3. 否则,refs/tags/<refname>如果存在;

  4. 否则,refs/heads/<refname>如果存在;

  5. 否则,refs/remotes/<refname>如果存在;

  6. 否则,refs/remotes/<refname>/HEAD如果它存在。

因此,即使您有一个带有名称的分支tags/1601也可以通过说refs/heads/tags/1601.

  • 问题是关于“checkout”,而不是“switch”。移动这个球门柱对任何人都没有帮助,因为有人可能认为“switch”是解决方案的一部分。但“checkout”和“switch”都有同样的问题。 (2认同)