Git: Erstellen Sie einen Zweig aus nicht bereitgestellten / nicht festgeschriebenen Änderungen auf dem Master

991

Kontext: Ich arbeite am Master und füge eine einfache Funktion hinzu. Nach ein paar Minuten merke ich, dass es nicht so einfach war und es hätte besser sein sollen, in einer neuen Niederlassung zu arbeiten.

Das passiert mir immer und ich habe keine Ahnung, wie ich zu einem anderen Zweig wechseln und all diese nicht festgeschriebenen Änderungen mitnehmen soll, wenn ich den Hauptzweig sauber lasse. Ich hätte git stash && git stash branch new_branchdas einfach erreichen wollen, aber das bekomme ich:

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ echo "hello!" > testing 

~/test $ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git stash
Saved working directory and index state WIP on master: 4402b8c testing
HEAD is now at 4402b8c testing

~/test $ git status
# On branch master
nothing to commit (working directory clean)

~/test $ git stash branch new_branch
Switched to a new branch 'new_branch'
# On branch new_branch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (db1b9a3391a82d86c9fdd26dab095ba9b820e35b)

~/test $ git s
# On branch new_branch
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

~/test $ git checkout master
M   testing
Switched to branch 'master'

~/test $ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   testing
#
no changes added to commit (use "git add" and/or "git commit -a")

Wissen Sie, ob es eine Möglichkeit gibt, dies zu erreichen?

Knoopx
quelle
1
Obwohl es eine einfachere Lösung für Ihr Problem gibt, können Sie angeben, in welchem ​​Ergebnis Sie von dem gewünschten Ergebnis abweichen?
Gauthier
2
Wenn Sie die obigen oder die Antworten unten ausführen, werden die nicht festgeschriebenen Änderungen sowohl für den Master als auch für den neuen Zweig vorgenommen. Ich möchte sie nur in der neuen Filiale haben, damit ich den Master
auschecken
1
siehe meine bearbeitete Antwort. Sie müssen Ihre lokalen Änderungen in der neuen Verzweigung festschreiben, wenn Sie einen sauberen Master auschecken möchten. Lokale Änderungen sind nur die Unterschiede zwischen dem aktuellen HEAD und Ihren Dateien auf der Festplatte. Diese Änderungen an lokalen Dateien sind nicht versioniert. Sie müssen git anweisen, sie irgendwo zu speichern, wenn Sie sie später abrufen möchten.
Gauthier

Antworten:

1207

Keine Notwendigkeit zu verstauen.

git checkout -b new_branch_name

berührt Ihre lokalen Änderungen nicht. Es wird nur der Zweig aus dem aktuellen HEAD erstellt und der HEAD dort festgelegt. Also ich denke, das ist was du willst.

--- Bearbeiten, um das Ergebnis des Checkout-Masters zu erklären ---

Sind Sie verwirrt, weil checkout masterIhre Änderungen nicht verworfen werden?

Da die Änderungen nur lokal sind, möchte git nicht, dass Sie sie zu leicht verlieren. Beim Ändern des Zweigs überschreibt git Ihre lokalen Änderungen nicht. Das Ergebnis von Ihnen checkout masterist:

M   testing

Dies bedeutet, dass Ihre Arbeitsdateien nicht sauber sind. git hat den HEAD geändert, aber Ihre lokalen Dateien nicht überschrieben. Aus diesem Grund zeigt Ihr letzter Status immer noch Ihre lokalen Änderungen an, obwohl Sie aktiviert sind master.

Wenn Sie die lokalen Änderungen wirklich verwerfen möchten, müssen Sie das Auschecken mit erzwingen -f.

git checkout master -f

Da Ihre Änderungen nie festgeschrieben wurden, würden Sie sie verlieren.

Versuchen Sie, zu Ihrer Zweigstelle zurückzukehren, Ihre Änderungen festzuschreiben und den Master erneut auszuchecken.

git checkout new_branch
git commit -a -m"edited"
git checkout master
git status

Sie sollten Mnach dem ersten Auschecken eine Nachricht erhalten, aber nicht mehr nach dem checkout masterund git statussollten keine geänderten Dateien anzeigen.

--- Bearbeiten, um Verwirrung über das Arbeitsverzeichnis (lokale Dateien) zu beseitigen ---

Als Antwort auf Ihren ersten Kommentar sind lokale Änderungen nur ... gut, lokal. Git speichert sie nicht automatisch, Sie müssen es anweisen, um sie für später zu speichern. Wenn Sie Änderungen vornehmen und diese nicht explizit festschreiben oder speichern, werden sie von git nicht versioniert. Wenn Sie HEAD ( checkout master) ändern , werden die lokalen Änderungen nicht überschrieben, da sie nicht gespeichert wurden.

Gauthier
quelle
32
Das Verwirrende dabei ist, dass in der Manpage von git angegeben wird, dass git checkout"Dateien im Arbeitsbaum aktualisiert werden, um mit der Version im Index oder dem angegebenen Baum übereinzustimmen." Dies setzt voraus, dass Ihre Änderungen in Ihrem Dateisystem danach GEGANGEN sind . Ohne eine Chance, sie zurückzubekommen. Selbst wenn Sie sagen, dass dies nicht der Fall ist, hinterlässt dies immer noch ein sehr schlechtes Gefühl. Ich vertraue dem überhaupt nicht . Entweder ist die Dokumentation wirklich schlecht oder das Standardverhalten von git ist wirklich gefährlich. Man sollte sich nicht auf eine „automagische“ Heuristik verlassen müssen, um zu erkennen, dass Sie in diesem Fall Ihre Änderungen nicht verlieren möchten.
Evi1M4chine
16
Wenn Sie ein Commit auschecken, das Ihre lokalen Änderungen überschreibt (wenn der Verlauf zwischen dem aktuellen Commit und dem Ziel-Commit Ihre lokal geänderten Dateien berührt), lehnt git ab. Nur wenn checkoutdies nicht mit Ihren lokalen Änderungen in Konflikt steht, funktioniert das Auschecken und lässt die lokalen Änderungen in Ruhe. Ich verstehe das schlechte Gefühl, auf der Manpage sollte vielleicht "Updates unveränderter Dateien im Arbeitsbaum" stehen. Git hingegen macht es nicht zu einfach, lokale Änderungen zu verlieren. git checkoutEntweder lassen Sie Ihre lokalen Änderungen alleine oder lehnen es ab, wenn ein Konflikt vorliegt.
Gauthier
1
Nun, wie würde ich in eine andere Filiale auschecken, ohne die lokalen Änderungen dort zu übernehmen?
レ ッ ク ス
5
@ Alex git checkout <other_branch> -f. Sie verlieren Ihre lokalen Änderungen ohne Vorwarnung.
Gauthier
2
@ Evi1M4chine Der erste. Die Dokumentation ist wirklich schlecht.
Qwertie
62

Versuchen:

git stash
git checkout -b new-branch
git stash apply
Grant Limberg
quelle
6
Ist das etwas anderes, als 'git checkout -b new-branch' alleine zu machen?
Adrian Mouat
Ich glaube nicht, dass es war, als die Antwort ursprünglich geschrieben wurde, aber ich könnte mich irren. Leider habe ich aufgrund meiner Arbeitsumstände in den letzten Jahren Perforce verwendet, sodass ich die Genauigkeit jetzt nicht bestätigen kann.
Grant Limberg
6
Oder anstelle der letzten beiden Schritte: Git Stash Branch New-Branch
Rethab
1
Git Stash ist nicht mehr erforderlich
Kory
Wenn Sie einen bereits vorhandenen Zweig haben, in dem Sie all Ihre Daten ablegen möchten, ist stash für mich sinnvoll: (eventuell git fetch --all; um den Remote-Zweig auf den Ursprung zu bringen) git stash; git checkout <existierende-zweig>; Git Stash anwenden;
Paolof76
24

Zwei Dinge, die Sie tun können:

git checkout -b sillyname
git commit -am "silly message"
git checkout - 

oder

git stash -u
git branch sillyname stash@{0}

( git checkout -<- Der Bindestrich ist eine Verknüpfung für den vorherigen Zweig, in dem Sie sich befanden.)

( git stash -u<- -ubedeutet, dass auch nicht bereitgestellte Änderungen erforderlich sind)

Pylinux
quelle
7

Wenn Sie den GitHub Windows-Client (wie ich) verwenden und nicht festgeschriebene Änderungen vorgenommen haben, die Sie in einen neuen Zweig verschieben möchten, können Sie einfach über den GitHub-Client einen neuen Zweig erstellen. Es wechselt zum neu erstellten Zweig und behält Ihre Änderungen bei.

Geben Sie hier die Bildbeschreibung ein

Tod Birdsall
quelle
Dadurch werden die Änderungen vor dem Erstellen des neuen Zweigs gespeichert, sodass sie nicht beibehalten werden (Version 223 unter Mac OS)
Fernando Gallego,
2

Wenn Sie möchten, dass Ihre aktuellen nicht festgeschriebenen Änderungen am aktuellen Zweig in einen neuen Zweig verschoben werden, erstellen Sie mit dem folgenden Befehl einen neuen Zweig und kopieren Sie die nicht festgeschriebenen Änderungen automatisch.

git checkout -b branch_name

Dadurch wird aus Ihrem aktuellen Zweig ein neuer Zweig erstellt (vorausgesetzt, er ist Master), die nicht festgeschriebenen Änderungen kopiert und zum neuen Zweig gewechselt.

Übernehmen Sie Ihre Änderungen in den neuen Zweig.

git commit -m "First commit"

Da ein neuer Zweig erstellt wird, müssen Sie den Upstream festlegen, bevor Sie ihn an Remote senden. Verwenden Sie den folgenden Befehl, um den Upstream einzustellen und auf Remote zu schieben.

git push --set-upstream origin feature/feature/NEWBRANCH

Sobald Sie diesen Befehl drücken, wird auf der Fernbedienung ein neuer Zweig erstellt und Ihr neuer lokaler Zweig auf die Fernbedienung verschoben.

Wenn Sie nun Ihre nicht festgeschriebenen Änderungen aus dem Hauptzweig entfernen möchten, verwenden Sie:

git checkout master -f

Dadurch werden alle nicht festgeschriebenen lokalen Änderungen beim Auschecken verworfen.

Einzelgänger
quelle
Wie unterscheidet sich diese Antwort von der akzeptierten?
Kometen
Obwohl es einige Überschneidungen mit der akzeptierten Antwort gibt, bietet dies eine einfache Schritt-für-Schritt-Anleitung und enthält auch die Vorgänge, die zum Remote-Push eines neuen Zweigs erforderlich sind. Einfach, klar und nützlich.
Kjartan
Diese Antwort ist klar und hat mir sehr geholfen.
Vadim
0

Wenn Sie im neuesten GitHub- Client für Windows nicht festgeschriebene Änderungen vorgenommen haben und einen neuen Zweig erstellen möchten.
Sie werden aufgefordert, genau mit diesem Szenario umzugehen:

Geben Sie hier die Bildbeschreibung ein

Gleiches gilt, wenn Sie einfach auch den Zweig wechseln.

Jerry Dodge
quelle