Bedeutung der doppelten Striche an der Git-Kasse

274

Was bedeuten die doppelten Striche vor dem Dateinamen in diesem git-Befehl?

git checkout --ours -- path/to/file.txt
git checkout --theirs -- path/to/file.txt

Sind sie obligatorisch? Ist es gleichbedeutend mit

git checkout --ours path/to/file.txt
git checkout --theirs path/to/file.txt
mottalrd
quelle
24
Es ist ein Shell-Ausdruck. Siehe unix.stackexchange.com/questions/11376/…
iltempo
15
@iltempo: Bei Git ist das etwas anders. Bei Git wird der Baum von den Pfaden getrennt, wenn Bäume und Pfade möglicherweise gleich aussehen.
Dietrich Epp
@Dietrich_Epp. Aha. Danke fürs klarstellen.
Iltempo
Auch dokumentiert in stackoverflow.com/a/1192194/6309
VonC
3
Es ist ein Duplikat, aber dieses Duplikat ist zumindest durch die Abfrage 'git double dash' googleable.
Dorn

Antworten:

376

Angenommen, ich habe eine Datei mit dem Namen path/to/file.txtin meinem Git-Repository und möchte Änderungen daran rückgängig machen.

git checkout path/to/file.txt

Angenommen, die Datei heißt master...

git checkout master

Hoppla! Das hat stattdessen die Zweige gewechselt. Das --trennt den Baum, den Sie auschecken möchten, von den Dateien, die Sie auschecken möchten.

git checkout -- master

Es hilft uns auch, wenn ein Freako eine Datei mit dem Namen " -fRepository" hinzugefügt hat :

git checkout -f      # wrong
git checkout -- -f   # right

Dies ist in git-checkout: Argument Disambiguation dokumentiert .

Dietrich Epp
quelle
12
Dies gilt für viele Bash-Befehle, nicht nur für Git-Befehle, ja?
NHDaly
40
@NHDaly: Ja, das stimmt. Ein Hinweis zur Terminologie: "Bash" hat nur wenige Befehle (vielleicht 20 oder so), die meisten Befehle sind separate Programme von Bash. Es ist tatsächlich Teil des POSIX-Standards, --mit dem Optionen von anderen Argumenten getrennt werden können. Sie sehen es also in Befehlen wie cpund mv(die nicht Teil von Bash sind).
Dietrich Epp
6
Irgendeine Idee, warum diese Syntax in der checkoutBefehlsdokumentation nicht richtig beschrieben wird ?
TanguyP
4
@DietrichEpp An mehreren Stellen wird es wie ein möglicher Parameter für den checkoutBefehl aufgelistet , aber nirgends erklärt die Dokumentation, was es tut oder warum es verwendet wird ... was mich letztendlich hierher gebracht hat.
Chris
7
@DietrichEpp Richtig, aber nachdem ich die Syntax (und die Beispiele) gelesen hatte, bevor ich zu Stack Overflow kam, verstand ich immer noch nicht, warum man sie verwenden wollte oder nicht --. Als jemand, der nicht aus einem Linux-Hintergrund stammt, ist es nicht offensichtlich, was das bewirkt. Für mich schien es eine git-spezifische Syntax zu sein, ohne Beschreibung ihres funktionalen Zwecks. Ich denke, es wäre besser, eine kurze Beschreibung wie die anderen Optionen oder zumindest einen Link zu einer Linux-Manpage zu haben .
Chris
109

Der doppelte Bindestrich "-" bedeutet "Ende der Befehlszeilenflags", dh er weist den vorhergehenden Befehl an, nicht zu versuchen, zu analysieren, was nach den Befehlszeilenoptionen kommt.

timmcliu
quelle
2
Aus Gründen der Klarheit gitbedeutet dies mehr als dies, da es auch bedeutet, dass das Argument nach dem --kein Verzweigungsname sein kann und das vorhergehende Argument implizit --kein Dateipfad sein kann.
Gem Taylor
0

Beachten Sie, dass Sie seit Git 2.5 (Q2 2015) kein ' --' benötigen würden , wenn Ihr Argument Platzhalter ( *) enthält.

Eine Heuristik, die der git <cmd> <revs> <pathspec>Befehlszeilenkonvention hilft, falsch eingegebene Pfade abzufangen, besteht darin, sicherzustellen, dass alle Nicht-Rev-Parameter im späteren Teil der Befehlszeile Namen der Dateien im Arbeitsbaum sind. Dies bedeutet jedoch, dass dies git grep $str -- \*.cimmer der Fall sein muss eindeutig mit " --", weil niemand vernünftig eine Datei erstellen wird, deren Name buchstäblich Sternchen-Punkt-Sehen ist.

Git 2.5 verliert die Heuristik, um zu deklarieren, dass der Benutzer mit einer Platzhalterzeichenfolge wahrscheinlich beabsichtigt hat, uns eine Pfadspezifikation zu geben .

git checkout 'a*'
# same as
git checkout -- 'a*'

Siehe Commit 28fcc0b (02. Mai 2015) von Duy Nguyen ( nguyenlocduy) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 949d167 , 19. Mai 2015)

pathspec: Vermeiden Sie die Notwendigkeit von " --", wenn Platzhalter verwendet werden

Wenn " --" in der Befehlszeile fehlt und ein Befehl sowohl Umdrehungen als auch Pfade annehmen kann, ist die Idee, wenn ein Argument sowohl als erweiterter SHA-1 als auch als Pfad angesehen werden kann, " --" erforderlich ist oder git sich weigert, fortzufahren.
Es ist derzeit implementiert als:

  • (1) Wenn ein Argument rev ist, darf es im Arbeitsbaum nicht existieren
  • (2) sonst muss es im Arbeitsbaum existieren
  • (3) sonst ist " --" erforderlich.

Diese Regeln funktionieren für Literalpfade, aber wenn es sich um eine nichtliterale Pfadspezifikation handelt, muss der Benutzer fast immer " --" hinzufügen, da dies fehlschlägt (2) und (1) wirklich selten erfüllt wird ( *.czum Beispiel " ", (1) wird erfüllt, wenn ein Verweis mit dem Namen " *.c") vorhanden ist.

Dieser Patch ändert die Regeln ein wenig, indem er berücksichtigt, dass eine gültige ( *) Platzhalterpfadspezifikation "im Arbeitsbaum vorhanden" ist.
Die Regeln werden:

  • (1) Wenn ein Argument eine Umdrehung ist, muss es entweder im Arbeitsbaum vorhanden sein oder keine gültige Platzhalterpfadspezifikation sein.
  • (2) Andernfalls ist es entweder im Arbeitsbaum vorhanden oder eine Platzhalterpfadspezifikation
  • (3) sonst ist " --" erforderlich.

Mit den neuen Regeln wird " --" die meiste Zeit nicht benötigt, wenn Platzhalterpfadspezifikationen beteiligt sind.


Mit Git 2.26 (Q1 2020) wurde die Disambiguierungslogik zur Unterscheidung von Revisionen und Pfadspezifikationen so angepasst, dass Backslash-Escap-Glob-Sonderzeichen in der Regel "Platzhalter sind Pfadspezifikationen" nicht berücksichtigt werden.

Siehe Commit 39e21c6 (25. Januar 2020) von Jeff King ( peff) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 341f8a6 , 12. Februar 2020)

verify_filename(): Behandle Backslashes in der Regel "Platzhalter sind Pfadspezifikationen"

Berichtet von: David Burström
Unterzeichnet von: Jeff King

Commit 28fcc0b71a ( pathspec: Vermeiden Sie die Notwendigkeit von " --", wenn Platzhalter verwendet werden, 2015-05-02) zulässig:

git rev-parse '*.c'

ohne den Doppelstrich.

Die Regel, nach der nach Platzhaltern gesucht wird, sucht jedoch nach Glob-Specials.
Dies ist zu liberal, da dies bedeutet, dass ein Muster, das keinen Platzhalterabgleich durchführt, wie " a\b", als Pfadspezifikation betrachtet wird.

Wenn Sie eine solche Datei auf der Festplatte haben, ist dies vermutlich das, was Sie wollten.
Wenn Sie dies nicht tun, sind die Ergebnisse verwirrend: Anstatt " there's no such path a\b" zu sagen , akzeptieren wir es stillschweigend als Pfadspezifikation, die sehr wahrscheinlich mit nichts übereinstimmt (oder zumindest nicht mit dem, was Sie beabsichtigt haben).
Ebenso a\*berweitert das Suchen nach Pfad " " die Suche überhaupt nicht; es würde nur einen einzigen Eintrag finden, " a*b".

Durch dieses Festschreiben wird die Regel nur dann ausgelöst, wenn globale Metazeichen die Suche erweitern würden. In beiden Fällen wird nun ein Fehler gemeldet (Sie können --natürlich immer noch mit " " unterscheiden; wir verschärfen nur die DWIM-Heuristik).

( DWIM: Tu was ich meine )

Beachten Sie, dass wir die ursprüngliche Funktion in 28fcc0b71a überhaupt nicht getestet haben .
Dieser Patch testet also nicht nur diese Eckfälle, sondern fügt auch einen Regressionstest für das vorhandene Verhalten hinzu.

VonC
quelle