git stash -> Zusammengeführte Änderungen mit aktuellen Änderungen zusammenführen

185

Ich nahm einige Änderungen an meiner Niederlassung vor und stellte fest, dass ich vergessen hatte, einige andere notwendige Änderungen an dieser Niederlassung vorgenommen zu haben. Was ich möchte, ist eine Möglichkeit, meine versteckten Änderungen mit den aktuellen Änderungen zusammenzuführen.

Gibt es eine Möglichkeit, dies zu tun?

Es ist eher der Einfachheit halber, dass ich schließlich aufgab und zuerst meine aktuellen Änderungen, dann meine versteckten Änderungen festlegte, aber ich hätte es vorgezogen, sie mit einem Schlag einzubringen.

Bemis
quelle
Wahrscheinlich Duplikat von stackoverflow.com/q/1360712/72178
ks1322
Joshuas Antwort sollte die akzeptierte Antwort sein. Dieser Stackoverflow-Beitrag ist der erste Google-Link für diese Frage. Geben Sie die richtige Antwort ins Internet!
Jérôme

Antworten:

270

Ich habe gerade festgestellt, dass, wenn Ihre nicht festgeschriebenen Änderungen zum Index hinzugefügt werden (dh "inszeniert", mit git add ...), git stash apply(und vermutlich git stash pop) tatsächlich eine ordnungsgemäße Zusammenführung durchgeführt wird. Wenn es keine Konflikte gibt, bist du golden. Wenn nicht, lösen Sie sie wie gewohnt mit git mergetooloder manuell mit einem Editor.

Um klar zu sein, ist dies der Prozess, über den ich spreche:

mkdir test-repo && cd test-repo && git init
echo test > test.txt
git add test.txt && git commit -m "Initial version"

# here's the interesting part:

# make a local change and stash it:
echo test2 > test.txt
git stash

# make a different local change:
echo test3 > test.txt

# try to apply the previous changes:
git stash apply
# git complains "Cannot apply to a dirty working tree, please stage your changes"

# add "test3" changes to the index, then re-try the stash:
git add test.txt
git stash apply
# git says: "Auto-merging test.txt"
# git says: "CONFLICT (content): Merge conflict in test.txt"

... was wahrscheinlich das ist, wonach Sie suchen.


tl; dr

git addZuerst ausführen .

Joshua Warner
quelle
8
Solch ein Hack, aber hey, es funktioniert und scheint der einzige Weg zu sein, dies zu tun. Ich wünschte es gäbe git stash apply --forceoder so.
Matt Kantor
12
Eigentlich ist es kein Hack - es ist eine Verbesserung gegenüber dem, was Sie wollen, da Sie leicht zu den Änderungen im Index zurückkehren können.
Hoffmanc
2
Wow, ist dieses Verhalten wirklich von Git beabsichtigt?
edi9999
9
Ich glaube nicht, dass irgendetwas jemals von Git "beabsichtigt" wurde. Meine Vermutung ist mittlerweile, dass alles, was ein Idiot tut, dies zufällig tut.
Profpatsch
5
Dies ist die perfekte Lösung. Ich habe gerade git add ., git stash applyund dann git resetdas Versteck meine Arbeit Änderungen zu übernehmen und merge ohne verpflichtet zu müssen.
Stephen Smith
69

Laufen git stash popoder git stash applyist im Wesentlichen eine Zusammenführung. Sie hätten Ihre aktuellen Änderungen nicht festschreiben müssen, es sei denn, die im Stash geänderten Dateien werden auch in der Arbeitskopie geändert. In diesem Fall hätten Sie diese Fehlermeldung gesehen:

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

In diesem Fall können Sie den Stash nicht in einem Schritt auf Ihre aktuellen Änderungen anwenden. Sie können die Änderungen festschreiben, den Stash anwenden, erneut festschreiben und diese beiden Festschreibungen mit quetschen, git rebasewenn Sie wirklich keine zwei Festschreibungen wünschen, aber das kann mehr Ärger sein, als es wert ist.

Brandan
quelle
1
Ich habe diese Nachricht erhalten - die Änderungen stehen nicht in Konflikt, sondern teilen dieselben Dateien, etwa unter Verwendung von Stashes / Applys?
Bemis
1
Entschuldigung, das habe ich mit "Konflikte zusammenführen" gemeint, aber das war eine schlechte Wortwahl. Ich denke, dass die Fehlermeldung ziemlich endgültig ist: Wenn die in der Arbeitskopie geänderten Dateien auch im Stash geändert werden, können Sie den Stash nicht anwenden. Ich habe meine Antwort mit einer möglichen Problemumgehung aktualisiert.
Brandan
3
Ich würde dies nicht in allen Fällen als Antwort betrachten. Möglicherweise haben Sie nur einen Teil einer Reihe von Änderungen in einer bestimmten Datei gespeichert, weil Sie während der Entwicklung etwas testen wollten. Möglicherweise möchten Sie den aktuellen Inhalt der Datei zu diesem Zeitpunkt (oder überhaupt nicht) festschreiben, da es sich um WIP handelt. Es ist ein echtes Problem mit Git, dass versteckte Änderungen nicht in Ihrem aktuellen Zweig zusammengeführt werden können
Thomas Watson
21
Joshua Warners Antwort sollte die richtige sein. Um einen Stash zusammenzuführen, stellen Sie Ihre Änderungen bereit, wenden Sie den Stash an, behandeln Sie Konflikte und heben Sie dann (falls gewünscht) Ihre Änderungen auf.
Vroo
4
"Sie können die Änderungen festschreiben, den Stash anwenden, erneut festschreiben und diese beiden Festschreibungen mit git rebase quetschen, wenn Sie wirklich keine zwei Festschreibungen wünschen, aber das kann mehr Ärger sein, als es wert ist." Stattdessen können Sie Folgendes tun: Übernehmen Sie die Änderungen, wenden Sie den Stash an und dann git commit --amend.
gabe
26

Was ich möchte, ist eine Möglichkeit, meine versteckten Änderungen mit den aktuellen Änderungen zusammenzuführen

Hier ist eine weitere Option:

git stash show -p|git apply
git stash drop

git stash show -pzeigt den Patch des zuletzt gespeicherten Stashs an. git applywird es anwenden. Nachdem die Zusammenführung abgeschlossen ist, kann der zusammengeführte Stash mit gelöscht werden git stash drop.

ks1322
quelle
1
Vielen Dank dafür - ich weiß nicht, warum git stash popdies nicht nur in Fällen geschieht, in denen die Zusammenführung sauber gilt ...
Iguananaut
Erweiterte Version: git stash show -p --no-color | git apply --3way( --3way= bei fehlerhaftem Patch auf 3-Wege-Zusammenführung zurückgreifen).
DmitrySandalov
Aber git stash show -pschafft ein Diff zwischen dem gebunkert Inhalt und das Commit zurück , wenn der Vorrat Eintrag zum ersten Mal erstellt wurde . Dies würde also die vom OP vorgenommenen Änderungen an der Arbeitsdatei überschreiben.
Paul F. Wood
Warum überschreiben? Das mit erzeugte Diff git stash show -pwird von zusammengeführt git apply, wenn es möglich ist, auf Konflikte zu verzichten.
ks1322
1

Die Art und Weise, wie ich das mache, ist dann git addzuerst git stash apply <stash code>. Es ist der einfachste Weg.

user3856437
quelle
3
Wie ist das nicht eine exakte Kopie der akzeptierten Antwort?
RomainValeri
0

Wie von @Brandan vorgeschlagen, musste ich Folgendes tun, um herumzukommen

error: Your local changes to the following files would be overwritten by merge:
       file.txt
Please, commit your changes or stash them before you can merge.
Aborting

Folgen Sie diesem Prozess:

git status  # local changes to `file`
git stash list  # further changes to `file` we want to merge
git commit -m "WIP" file
git stash pop
git commit -m "WIP2" file
git rebase -i HEAD^^  # I always use interactive rebase -- I'm sure you could do this in a single command with the simplicity of this process -- basically squash HEAD into HEAD^
# mark the second commit to squash into the first using your EDITOR
git reset HEAD^

Und Sie haben die Möglichkeit, die lokalen Änderungen vollständig zusammenzuführen file, um weitere Arbeiten / Aufräumarbeiten durchzuführen oder ein einziges gutes Commit durchzuführen. Wenn Sie wissen, dass der zusammengeführte Inhalt filekorrekt ist, können Sie eine passende Nachricht schreiben und überspringen git reset HEAD^.

Knickum
quelle
0

Vielleicht ist es nicht die schlechteste Idee, (über Difftool) aus ... ja ... einem Zweig zusammenzuführen!

> current_branch=$(git status | head -n1 | cut -d' ' -f3)
> stash_branch="$current_branch-stash-$(date +%yy%mm%dd-%Hh%M)"
> git stash branch $stash_branch
> git checkout $current_branch
> git difftool $stash_branch
Frank-Rene Schäfer
quelle
0

Sie können leicht

  1. Übernehmen Sie Ihre aktuellen Änderungen
  2. Entstauen Sie Ihren Vorrat und lösen Sie Konflikte
  3. Änderungen aus dem Stash festschreiben
  4. Soft-Reset zum Festschreiben, von dem Sie kommen (letztes korrektes Festschreiben)
Finelf
quelle
-1

Eine andere Möglichkeit besteht darin, einen weiteren "Git-Stash" der lokalen nicht festgeschriebenen Änderungen vorzunehmen und dann die beiden Git-Stashes zu kombinieren. Leider scheint Git keine Möglichkeit zu haben, zwei Verstecke einfach zu kombinieren. Eine Möglichkeit besteht also darin, zwei .diff-Dateien zu erstellen und beide anzuwenden - zumindest ist dies kein zusätzliches Commit und erfordert keinen zehnstufigen Prozess: |

Gewusst wie: https://stackoverflow.com/a/9658688/32453

Rogerdpack
quelle
Es verwandelt das Problem der Anwendung eines Diff in ein Problem der Anwendung zweier Differenzen. Darüber hinaus beinhaltet die akzeptierte Lösung kein Commit, sondern nur eine Phase, und es handelt sich nur um einen einzelnen Befehl (git add). (Ich bin nicht der Downvoter.)
Eike
Zumindest für mich fühlt es sich einfacher an, weniger Voodoo-Magie ... Prost!
Rogerdpack