Rebasing aus dem Versteck, seltsames Ergebnis

9

Ich frage das nur aus Neugier. Es gibt andere Möglichkeiten, mit dieser Art von Situation im wirklichen Leben umzugehen, aber ich finde das folgende Verhalten von git ein bisschen seltsam.

Zusammenfassung: Verstecke erzeugen hinter dem Vorhang zwei Commits, von denen einer den Index und der andere die nicht hinzugefügten Bearbeitungen enthält. Wenn wir Letztere auschecken und versuchen, sie zu rebasen, bekommen wir irgendwie nur die Änderungen aus dem Index. Warum ist das so?

Detailliertes Beispiel folgt:

Zuerst machen wir einen Repo mit einem Commit, dann einem weiteren Edit, der zum Index hinzugefügt wird, dann einem weiteren Edit, der nicht zum Index hinzugefügt wird, und dann stash:

%Vor%

So git stash scheint sowohl den Index als auch die nicht hinzugefügte Bearbeitung als Commits mit eigenen Hashes abzuspeichern (in meinem Fall 965c986 für den Index und 5c00fc0 für die nicht hinzugefügten Bearbeitungen).

Bearbeiten Sie nun eine neue Datei und committen Sie:

%Vor%

So sehen nun alle Commits aus:

%Vor%

Sagen wir, wir wollen nun die verdeckten Änderungen vornehmen und sie mit dem zweiten Commit kombinieren. Es gibt andere Möglichkeiten, dies zu tun (wie git stash apply , aber was ist, wenn wir den Stash bereits bereinigt und dann das Commit aus dem Reflog gegraben haben), aber versuchen wir es einfach mit:

%Vor%

Aber jetzt ist die resultierende Datei a.txt nur:

%Vor%

Dies ist der gesamte Graph:

%Vor%

Es sieht also so aus, dass, obwohl wir Commit 5c00fc0 ausgecheckt haben, die Rebase nur die Änderungen aus dem Commit 965c986 übernommen hat, d. h. die Bearbeitungen, die beim Verstecken im Index waren. Aber was auch immer in 5c00fc0 war wurde ignoriert.

Frage: Warum ist das so? Gibt es eine vernünftige Erklärung für dieses Verhalten? Oder sollte dies als Fehler angesehen werden?

    
Sampo Smolander 25.07.2013, 04:46
quelle

3 Antworten

1

Es ergibt sich, dass git nur (standardmäßig) Merge-Commits ignoriert, wenn ein Rebasing durchgeführt wird. Und das Stashing erzeugt den WIP-Commit und den Index-Commit, und der WIP-Commit ist ein Merge, da er sowohl den Index-Commit als auch den c8af537 als Eltern hat.

Nichts mit Verstauen als solcher zu tun.

    
Sampo Smolander 26.07.2013, 00:52
quelle
0

Ich bin heute Morgen über dieses Problem gestolpert, nachdem ich zufällig in einer GUI-App ein Versteck gelöscht hatte. Am Anfang habe ich versucht, wie andere es zu tun, weil das natürlich ist. Dann habe ich mit duckduckgo gesucht und gefunden, aber keine wirkliche Lösung. Also habe ich es etwas härter versucht und kam auf folgendes:

Angenommen, wir haben die folgenden Zweige / Referenzen:

  • dropstash zeigt auf das künstliche Merge Commit mit dem gewünschten Inhalt
  • parentOfStash zeigt dabei auf das ursprüngliche Basis-Commit Ex-Stash-Zweig

Dann können wir einfach tun:

  1. git checkout parentOfStash
  2. git cherry-pick -m 1 dropedStash

Wobei -m 1 git sagt, dass einer der Vorfahren Mainline sein soll. Ta da! Viel Spaß mit: -)

    
FredCooke 07.12.2014 23:19
quelle
-1

Massive Bearbeitung meiner ursprünglichen Antwort.

Ich habe etwas in den Code eingetaucht und einige Tests durchgeführt und ich habe das Problem gefunden. Wenn du deinen kopflosen Zweig rebst, machst du einen Master. Der Rebase-Befehl überprüft den Kopf des Zweigs, den Sie zurückbuchen, der in diesem Fall den Stash nicht enthält. Versuchen Sie es stattdessen:

%Vor%

Sie sollten etwas wie:

sehen %Vor%

Hinweis: Wenn Sie sich in einem losgelösten Kopfzustand befinden, aber git rebase master ausführen, wird es gemäß meinen Tests Ihren Kopf auf den Master-Kopf setzen. Sie hätten git rebase 5c00fc0 machen können und die gleichen Ergebnisse erzielt wie bei der Verzweigung.

    
Ilion 25.07.2013 07:08
quelle

Tags und Links