Refname ist mehrdeutig

Lesezeit: 8 Minuten

Benutzer-Avatar
Daniel Kaplan

Gestern habe ich einen Branch aus einem Branch erstellt, ihn zum Ursprung gepusht und wieder in den Master gemergt. Das kannst du hier sehen:

$ 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 

Ich füge irrelevante Dinge in diese Liste ein, damit ich nicht versehentlich etwas Relevantes herausschneide; Wie Sie sehen können, ist dieser gesamte Verlauf sequentiell. Hier ist alles in meiner Geschichte, die sich auf 1601 bezieht:

$ 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

Irgendwie, nach diesen Schritten, wann immer ich git co 1601es gibt mir diese Warnung:

$ git co 1601
warning: refname '1601' is ambiguous.
Already on '1601'
Your branch is up to date with 'origin/1601'.

Ich habe eine Weile gegoogelt und nach anderen gesucht, die dieses Problem hatten, aber keiner von ihnen scheint die gleiche Situation zu haben. Hier ist, was ich mir angesehen habe hat nicht geholfen:

  1. Git-Warnung: Refname „xxx“ ist mehrdeutig
  2. Git: Refname „master“ ist mehrdeutig
  3. git refname ‘origin/master’ ist mehrdeutig
  4. http://thesimplesynthesis.com/post/git-error-warning-refname-originbranch-name-is-ambiguous

Die folgende Ausgabe soll bei der Fehlersuche helfen:

$ git show-ref | grep 1601
137b74c8ff6807f07bb32ba0d2f76a3ba287e981 refs/heads/1601
137b74c8ff6807f07bb32ba0d2f76a3ba287e981 refs/remotes/origin/1601
$ git tag -l

$ git show-ref --heads --tags | grep 1601
137b74c8ff6807f07bb32ba0d2f76a3ba287e981 refs/heads/1601
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

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

FWIW, ich verwende Cygwin unter Windows.

Warum erhalte ich diese Warnung, wie werde ich sie los und wie verhindere ich sie in Zukunft?

  • Versuchen git checkout 1601 --. Wenn Sie eine Datei oder ein Verzeichnis mit dem Namen 1601 haben, wird dies die Mehrdeutigkeit beheben.

    – jthill

    13. Juni 2021 um 1:36 Uhr

  • @jthill das hatte keine Wirkung. Ich habe den Befehl und die Ausgabe in das OP eingefügt

    – Daniel Kaplan

    13. Juni 2021 um 2:09 Uhr

  • Es ist also nicht zweideutig mit einem versehentlich hinzugefügten Pfad, der Brute-Force-Refs-Matcher ist es git ls-remote . \*1601*.

    – jthill

    13. Juni 2021 um 3:24 Uhr

  • Die letzte Möglichkeit, die mir einfällt, ist, dass 1601 mit dem Präfix einer oder mehrerer IDs für Objekte im Repo übereinstimmt. sagen heads/1601 oder refs/heads/1601 um diese Möglichkeit auszuschließen, und ich denke git show hat den hilfreichsten Info-Dump als Reaktion auf Mehrdeutigkeiten, versuchen Sie es git show 1601 und sehen Sie, ob es alle Dinge auflistet, nach denen Sie vermutlich gefragt haben.

    – jthill

    13. Juni 2021 um 4:35 Uhr


Benutzer-Avatar
jthill

Ich kann dieses Verhalten erreichen, indem ich einem Zweig einen Namen gebe, der mit dem SHA1-Präfix eines Commits übereinstimmt.

$ 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'
$

Da Objekt-ID-Präfixe mit einer Länge von mindestens vier Ziffern legitime Möglichkeiten sind, auf Objekte zu verweisen, führt die Erstellung eines Ref-Namens, der auch eine vier- oder mehr lange Hex-Zeichenfolge ist, wahrscheinlich zu dieser Art von Mehrdeutigkeit. Also, tu das nicht. Wenn Sie etwas nummerieren möchten, fügen Sie eine Typenmarkierung hinzu, z bugfix/1601 oder so.

  • Wow! vielen Dank für all die Mühe, die Sie sich dafür gemacht haben. Why am I getting this warning, how do I get rid of it, and how do I prevent it in the future? Ich verstehe jetzt warum, ist der einzige Weg, es loszuwerden, meine Zweige umzubenennen und ein Zeichen darin einzufügen, das in einem Sha nicht gültig ist?

    – Daniel Kaplan

    13. Juni 2021 um 5:39 Uhr

  • @DanielKaplan Ich denke ja, oder Sie könnten Ihre Zweignamen auch auf 3 Zahlen anstelle von 4 verkürzen, da Sie mindestens 4 Zeichen benötigen, um auf eine Commit-ID zu verweisen. Ich bevorzuge im Allgemeinen sowieso aussagekräftigere Zweignamen, aber in Ihrem Fall sogar so etwas wie test-1600, build-1600, z1600oder was auch immer dort Sinn macht, würde das Problem lindern.

    – TTT

    13. Juni 2021 um 5:52 Uhr


  • Ich möchte diese Antwort wirklich akzeptieren, da Sie so viel Arbeit investiert haben. Darf es aktualisiert werden?

    – Daniel Kaplan

    13. Juni 2021 um 7:56 Uhr

  • Nur meine zwei Cent für den Filialnamen. Ich bevorzuge ein Suffix anstelle eines Präfixes, weil die automatische Vervollständigung damit besser funktioniert. Für meine Zweignamen verwende ich das folgende Muster <issue_number>-few_words_describing_the_issue. (Ich nehme das an 1600 ist eine Ausgabenummer oder etwas Ähnliches.)

    – GillesB

    18. Juni 2021 um 4:56 Uhr

Warum bekomme ich diese Warnung …

Wie Sie über die Antwort von jthill herausgefunden haben, liegt es daran 1601 stimmt mit dem Hash eines geeigneten Objekts überein.

Es gibt einige andere Möglichkeiten, denselben Fehler zu erhalten, einschließlich der Erstellung eines Zweig- und Tag-Namens mit derselben Schreibweise (z. B. git branch abc; git tag abc).

wie werde ich es los…

Verwenden Sie eindeutige Namen. Für Branch-vs-Tag bedeutet dies, dass Sie nicht denselben Namen wie einen Branch- und Tag-Namen verwenden; für Branch-or-Tag vs. Commit-Hash bedeutet dies, dass Commit-Hash-Namen vermieden werden, die hier vorkommen könnten. Wie TTT kommentierte, müssen Commit-Hash-Abkürzungen mindestens vier Zeichen enthalten, also abc ist als Verzweigungs- oder Tag-Name in Ordnung, obwohl alle drei Zeichen darin enthalten sind abc sind in Hash-IDs legitim.

Um zu sehen, ob ein Zweigname möglicherweise mit einer Hash-ID kollidiert, prüfen Sie, ob er vollständig aus Zeichen aus dem Satz besteht [0-9][a-f][A-F] und ist mindestens vier Zeichen lang. Fügen Sie in diesem Fall einige Zeichen hinzu, die außerhalb des Satzes liegen, oder kürzen Sie den Namen. Eine schnelle:

egrep '^[a-f]{4,}$' /usr/share/dict/words

taucht einige interessante Zweignamen auf, die es zu vermeiden gilt, wie z accede, aface, beaded, deedund facade. (Dies sind natürlich die Quellen verschiedener gefälschter Hash-IDs, die ich gerne als Beispiele verwende, wie z feedc0ffee, deadbeef, cafedadund so weiter – einige erfordern ein bisschen 11ce45e1 mit der Rechtschreibung.)

und wie verhindere ich das in zukunft?

Ein wirklich praktisches System ist es, Ihre Filialnamen zu systematisieren, um sie aufzunehmen / oder - oder so: zum Beispiel feature/c0ffee stößt nie auf solche Probleme.


1“Lizenz”, in etwas, das vage 1337-5p34k ähnelt.

Warum erhalte ich diese Warnung, wie werde ich sie los und wie verhindere ich sie in Zukunft?

Stellen Sie zunächst sicher, dass Sie es verwenden git switchnicht der alte veraltete und verwirrende Befehl git checkout.

Zweitens sogar mit git switcherhalten Sie diese Warnung (auch wenn Sie sich bereits in diesem Zweig befinden!):

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

Aber Einstellung core.warnAmbiguousRefs zu false würde diese Warnung eigentlich zunichte machen.

$ git -c core.warnAmbiguousRefs=false switch 29876e
Already on '29876e' 

  • Switch ist nur eine Alternative, es ist weder veraltet noch veraltet und höchstwahrscheinlich in keinem der älteren Handbücher / Artikel / Tutorials enthalten + hat keinen Nutzen für dieses Problem.

    – Peter Badida

    13. Juni 2021 um 9:09 Uhr


  • @PeterBadida Ich stimme zu, aber ich versuche immer, die neuen Schalter-/Wiederherstellungsbefehle über die Kasse zu stellen (die sowohl Zweige als auch Dateien berücksichtigen).

    – VonC

    13. Juni 2021 um 9:15 Uhr

Wenn du kennt dass ein Ref-Name ein Zweig oder ein Tag ist, können Sie der ID entweder voranstellen heads/ oder tags/. Das funktioniert also:

git checkout heads/1601

Gegeben <refname> Git durchsucht eine Liste von Orten. Dies ist die Liste gemäß der git help revisions Seite:

  1. Wenn $GIT_DIR/<refname> existiert, das meinen Sie (dies ist normalerweise nur nützlich für HEAD, FETCH_HEAD, ORIG_HEAD, MERGE_HEAD und CHERRY_PICK_HEAD);

  2. Andernfalls, refs/<refname> wenn es existiert;

  3. Andernfalls, refs/tags/<refname> wenn es existiert;

  4. Andernfalls, refs/heads/<refname> wenn es existiert;

  5. Andernfalls, refs/remotes/<refname> wenn es existiert;

  6. Andernfalls, refs/remotes/<refname>/HEAD wenn es existiert.

Also auch wenn Sie eine haben Zweig mit dem Namen tags/1601 die Mehrdeutigkeit kann aufgelöst werden, indem man sagt refs/heads/tags/1601.

1256550cookie-checkRefname ist mehrdeutig

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy