Git-Änderungszweig, wenn eine gleichnamige Datei vorhanden ist

76

Ich habe in meinem Git Repo eine Datei namens xyz. Zufälligerweise habe ich auch einen Zweig namens xyz. Derzeit bin ich auf Master, aber ich möchte auschecken, um xyz zu verzweigen. Der zu verwendende Befehl ist einfach

$ git checkout xyz

Dies würde jedoch die Datei xyzauf den aktuellen HEAD auschecken. Wie würde ich meine Filiale in Filiale ändern xyz?

venky
quelle

Antworten:

114

Wie durch Commit a047faf (Git 1.8.4.3+) veranschaulicht, können Sie auch Folgendes versuchen:

git checkout xyz --

(Hinweis: Die Fehlermeldung wird mit Git 2.21, Q1 2019 klarer. )

Das würde klar machen, dass der xyzTeil ein Zweig oder ein Commit ist, während alles danach --ein Pfad sein muss (hier wird kein Pfad angegeben). Weitere Informationen finden Sie hier zur Doppelbindestrich-Konvention .

Wenn Sie es ohne das ' --' versuchen , funktioniert dies möglicherweise nicht oder nicht, wie in " Warum erstellt Git Checkout <remote_branchname>keinen neuen Tracking-Zweig? " Gezeigt :

git checkout name tut:

  • Wenn es sich um einen lokalen Zweig oder einen expliziten Remote-Zweig handelt, wechseln Sie zu diesem.
  • Wenn es sich um einen verfolgten Pfad handelt, setzen Sie ihn zurück
  • Wenn es sich um einen Remote-Zweig handelt, erstellen Sie einen Tracking-Zweig und wechseln Sie zu diesem.

Und sein Verhalten ist nicht immer dasselbe. Daher das ' --', um eine klare Begriffsklärung zu liefern.


Update August 2019, Git 2.23+

git checkoutist zu verwirrend und wird ersetzt durch:

  • git switch: Bedeutung git switch xyzfunktioniert auch, wenn Sie eine Datei haben xyz,
  • git restore: Bedeutung git restore xyzfunktioniert auch, wenn Sie einen Zweig haben xyz.

Außerdem, wie ich in " Warum ist mein Git-Repo in einen getrennten HEAD-Status eingetreten? " Erkläre , gibt es keinen unerwarteten getrennten HEAD mehr.

VonC
quelle
Bessere Lösung, IMO: stackoverflow.com/a/9537923/1096596
BobbyA
@ BobbyA Ich habe die Antwort mit einer noch besseren Antwort aktualisiert
VonC
5

Während die Lösung von VonC funktioniert, kann ich mich nie an die Syntax erinnern, daher verwende ich normalerweise eine Low-Tech-Lösung:

$ (cd somedir && git checkout my-branch)

Oder wenn Sie keine Unterverzeichnisse haben:

$ (cd .git && git -C .. checkout my-branch)

Es ist leichter zu merken und es funktioniert ;-)

Martin Tournoij
quelle
0

Git 2.21 (Q1 2019, 4+ Jahre später) wird die Fehlermeldung klären und Vorschläge machen

" git checkout frotz" ( ohne einen von mir ursprünglich vorgeschlagenen Doppelstrich ) vermeidet Mehrdeutigkeiten, indem sichergestellt wird, dass ' frotz' nicht gleichzeitig als Revision und als Pfad interpretiert werden kann .

Diese Sicherheit wurde aktualisiert, um auch einen eindeutigen Fernverfolgungszweigfrotz in einer Fernbedienung zu überprüfen , wenn beim Dimmen ein lokaler Zweig frotzaus einem Fernverfolgungszweigfrotz von einer Fernbedienung erstellt wird.

Hinweis: "dwim" (unten verwendet) ist "tun, was ich meine" , wenn ein Computersystem versucht, vorauszusehen, was Benutzer beabsichtigen, und triviale Fehler automatisch korrigiert, anstatt die expliziten, aber möglicherweise falschen Eingaben der Benutzer blind auszuführen.

Siehe Commit be4908f (13. November 2018) von Nguyễn Thái Ngọc Duy ( pclouds) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 8d7f9db , 04. Januar 2019)

checkout: eindeutige Dwim-Tracking-Zweige und lokale Dateien

Wenn Checkout-Dwim in Commit 70c9ac2 hinzugefügt wird , ist es nur auf Dwim beschränkt, wenn bestimmte Bedingungen erfüllt sind, und greift ansonsten auf das Standard-Checkout-Verhalten zurück.

Es stellt sich heraus, dass ein Zurückfallen verwirrend sein kann.

Eine der Bedingungen, um sich zu wenden

git checkout frotz

zu

git checkout -b frotz origin/frotz

ist, dass frotznicht als Datei existieren darf.

Aber wenn der Benutzer erwartet, dass " git checkout frotz" der Zweig erstellt wird " frotz" und es zufällig eine Datei mit dem Namen " frotz" gibt, hilft es nicht, dass der Inhalt der Datei " " stillschweigend zurückgesetzt frotzwird .
Dies wird in der Git-Mailingliste gemeldet und an anderer Stelle sogar als Beispiel für "Git ist schlecht" verwendet .

Wir versuchen normalerweise, das Richtige zu tun, aber wenn es mehrere "richtige Dinge" zu tun gibt, ist es am besten, es dem Benutzer zu überlassen, zu entscheiden.

Überprüfen Sie diesen Fall und bitten Sie den Benutzer, Folgendes zu unterscheiden:

  • " git checkout -- foo" wird den Pfad "foo" auschecken
  • " git checkout foo --" wird dwim und Zweig erstellen " foo" 6

Für Benutzer, die dwim nicht möchten, verwenden Sie --no-guess. In diesem speziellen Fall ist es nutzlos, weil " git checkout --no-guess foo --" einfach fehlschlägt.
Aber es könnte von Skripten verwendet werden.

Die Manpagegit checkout enthält vorerst:

--no-guess:

Versuchen Sie nicht, einen Zweig zu erstellen, wenn ein gleichnamiger Remote-Tracking-Zweig vorhanden ist.


Vor Git 2.26 (Q1 2020) ist " git checkout X" nicht korrekt fehlgeschlagen, wenn Xes sich nicht um einen lokalen Zweig handelt, sondern es konnten mehrere Remote-Tracking-Zweige benannt werden (dh als Ausgangspunkt für die Erstellung eines entsprechenden lokalen Zweigs gedimmt werden) korrigiert.

Siehe Commit fa74180 , Commit 2957709 (30. Dezember 2019) von Alexandr Miloslavskiy ( SyntevoAlex) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit d0e70cd , 05. Februar 2020)

checkout: Datei in mehrdeutigen Tracking-Zweigen nicht zurücksetzen

Unterzeichnet von: Alexandr Miloslavskiy

Zum besseren Verständnis sind hier die vorhandenen guten Szenarien aufgeführt:

  1. Haben Sie keine Datei ' foo', keine lokale Verzweigung ' foo' und eine einzelne entfernte Verzweigung ' foo' 2. git checkout fooerstellt eine lokale Verzweigung foo, siehe Commit 70c9ac2 oben , hier beschrieben .

und

  1. Haben Sie eine Datei ' foo', keine lokale Verzweigung ' foo' und eine einzelne Remote-Verzweigung ' foo' 2. git checkout foowird sich beschweren, siehe Commit be4908f oben

Dieser Patch verhindert das folgende Szenario:

  1. Haben Sie eine Datei ' foo', keine lokale Verzweigung ' foo' und mehrere entfernte Verzweigungen ' foo' 2. git checkout foowird erfolgreich ... Inhalt der Datei zurücksetzen foo!

Das heißt, das Hinzufügen einer weiteren Fernbedienung ändert plötzlich das Verhalten erheblich. Dies ist bestenfalls eine Überraschung und kann im schlimmsten Fall vom Benutzer unbemerkt bleiben.
Siehe Commit be4908f oben , das einige reale Beschwerden enthält.

Nach meinem Verständnis hat Fix in Commit be4908f oben ( hier besprochen ) den Fall mehrerer Fernbedienungen übersehen, und das gesamte Verhalten des Zurücksetzens auf das Zurücksetzen von Dateien war nie beabsichtigt:

  • Commit 70c9ac2 oben führt das unerwartete Verhalten ein.
    Zuvor gab es einen Fallback von Not-a-Ref zu Pathspec. Dies ist ein vernünftiger Fallback.
    Danach gibt es einen weiteren Fallback von Ambiguous-Remote zu Pathspec.
    Ich verstehe, dass es ein Versehen mit Kopieren und Einfügen war.
  • Commit be4908f oben fügt hinzu, die()wenn zwischen Zweig und Datei Mehrdeutigkeiten bestehen.
    Der Fall mehrerer Tracking-Zweige wird anscheinend übersehen.

Das neue Verhalten: Wenn es keinen lokalen Zweig und mehrere Remote-Kandidaten gibt, die()versuchen Sie einfach nicht, die Datei zurückzusetzen, ob sie vorhanden ist (verhindert Überraschungen) oder nicht (verbessert die Fehlermeldung) .


Mit Git 2.30 (Q1 2021) lernte " git checkout" ( man ) , die checkout.guessKonfigurationsvariable zu verwenden und die --[no-]guessOption " " entsprechend zu aktivieren / deaktivieren .

Siehe Commit 64f1f58 (07. Oktober 2020) und Commit ef09e7d (06. Oktober 2020) von Denton Liu ( Denton-L) .
(Zusammengeführt von Junio ​​C Hamano - gitster- in Commit 0e41cfa , 27. Oktober 2020)

checkout: lernen zu respektieren checkout.guess

Unterzeichnet von: Denton Liu

Das aktuelle Verhalten von git checkout/switchist das, --guessdas derzeit standardmäßig aktiviert ist.
Einige Benutzer möchten jedoch möglicherweise nicht, dass dies automatisch geschieht.
Anstatt Benutzer zu zwingen, --no-guessjedes Mal manuell anzugeben , bringen Sie diesen Befehlen die checkout.guessKonfigurationsvariable bei, mit der Benutzer ein Standardverhalten festlegen können.

Bringen Sie dem Abschlussskript bei, die neue Konfigurationsvariable zu erkennen und die DWIM- Logik zu deaktivieren, wenn sie auf false gesetzt ist.

git configenthält jetzt in seiner Manpage :

checkout.guess

Gibt den Standardwert für die Option --guessoder --no-guessin git checkoutund an git switch. Siehe git switchund git checkout.

git checkoutenthält jetzt in seiner Manpage :

--guessist das Standardverhalten. Verwenden Sie --no-guessdiese Option, um es zu deaktivieren.

Das Standardverhalten kann über die checkout.guessKonfigurationsvariable eingestellt werden.

git switchenthält jetzt in seiner Manpage :

Das Standardverhalten kann über die checkout.guessKonfigurationsvariable eingestellt werden.

VonC
quelle
-3

Du liegst falsch. Der Zweig xyz wird ausgecheckt.

Um eine Datei auszuchecken, müssen Sie den Befehl verwenden git checkout -- xyz. Git erlaubt Ihnen nur eine Verknüpfung für Dateien, wenn es keinen Zweig mit demselben Namen gibt.

Siehe git checkout --helpfür Details.

Alexey Ten
quelle
9
Warum sollte ich die Frage stellen, wenn es nicht passiert? Ich passiert mir. Im Allgemeinen lautet die Antwort beim Auschecken eines Zweigs, Switched to branch 'xyz'aber in meinem Fall gab es keine Antwort. Welches ist das übliche Szenario beim Auschecken einer Datei. Ich habe auch die Ausgabe von gesehen, um git branch -vazu dem Schluss zu kommen, dass keine solche Änderung stattgefunden hat.
Venky