it-swarm.com.de

Ein Git-Merge-Commit neu erstellen

Nehmen Sie den folgenden Fall an:

Ich habe einige Arbeit in einem Themenzweig und jetzt bin ich bereit, mich wieder mit dem Master zu verbinden:

* eb3b733 3     [master] [Origin/master]
| * b62cae6 2   [topic]
|/  
* 38abeae 1

Ich führe die Zusammenführung vom Master aus, löse die Konflikte und jetzt habe ich:

*   8101fe3 Merge branch 'topic'  [master]
|\  
| * b62cae6 2                     [topic]
* | eb3b733 3                     [Origin/master]
|/  
* 38abeae 1

Nun, die Zusammenführung hat mich einige Zeit gekostet, also mache ich einen weiteren Abruf und bemerke, dass der entfernte Master-Zweig neue Änderungen aufweist:

*   8101fe3 Merge branch 'topic'  [master]
|\  
| * b62cae6 2                     [topic]
| | * e7affba 4                   [Origin/master]
| |/  
|/|   
* | eb3b733 3
|/  
* 38abeae 1

Wenn ich versuche, "git rebase Origin/master" von master auszuführen, muss ich alle Konflikte erneut lösen und verliere auch die Zusammenführungsverpflichtung:

* d4de423 2       [master]
* e7affba 4       [Origin/master]
* eb3b733 3
| * b62cae6 2     [topic]
|/  
* 38abeae 1

Gibt es eine saubere Möglichkeit, das Zusammenführungs-Commit neu zu formulieren, so dass am Ende eine Geschichte wie die, die ich unten zeige, endet?

*   51984c7 Merge branch 'topic'  [master]
|\  
| * b62cae6 2                     [topic]
* | e7affba 4                     [Origin/master]
* | eb3b733 3
|/  
* 38abeae 1
141
jipumarino

Hier gibt es zwei Möglichkeiten.

Eine ist, eine interaktive Rebase durchzuführen und das Zusammenführungs-Commit zu bearbeiten, die Zusammenführung manuell zu wiederholen und die Rebase fortzusetzen. 

Eine andere Möglichkeit besteht darin, die -p-Option für git rebase zu verwenden, die im Handbuch wie folgt beschrieben wird: "Statt Zusammenführungen zu ignorieren, versuchen Sie, sie neu zu erstellen." Diese Frage erklärt es weiter: Was genau macht gits "rebase --preserve-merges" (und warum?)

101
siride

Ok, das ist eine alte Frage und sie hat bereits die Antwort von @siride akzeptiert, aber diese Antwort war in meinem Fall nicht genug, da --preserve-merges Sie zwingt, alle Konflikte ein zweites Mal zu lösen. Meine Lösung basiert auf der Idee von @Tobi B , jedoch mit genauen Schritt-für-Schritt-Befehlen

Wir beginnen mit einem solchen Zustand anhand eines Beispiels in der Frage:

*   8101fe3 Merge branch 'topic'  [HEAD -> master]
|\  
| * b62cae6 2                     [topic]
| |
| | * f5a7ca8 5                   [Origin/master]
| | * e7affba 4
| |/  
|/|   
* | eb3b733 3
|/  
* 38abeae 1

Beachten Sie, dass wir 2 Commits vor dem Master haben, also würde die Kirschpickung nicht funktionieren.

  1. Zuerst erstellen wir die richtige Geschichte, die wir wollen:

    git checkout -b correct-history # create new branch to save master for future
    git rebase -s ours -p Origin/master
    

    -p bedeutet --preserve-merges, wir verwenden es, um unser Merge-Commit in der Historie zu speichern -s ours bedeutet --strategy=ours, wir verwenden es, um alle Zusammenführungskonflikte zu ignorieren, da uns egal ist, welche Inhalte in diesem Merge-Commit enthalten sind jetzt.

    Die Geschichte wird so aussehen (Master ignorieren):

    *   51984c7 Merge branch 'topic'  [HEAD -> correct-history]
    |\  
    | * b62cae6 2                     [topic]
    * | f5a7ca8 5                     [Origin/master]
    * | e7affba 4
    * | eb3b733 3
    |/  
    * 38abeae 1
    
  2. Lassen Sie uns jetzt den richtigen Index erhalten.

    git checkout master # return to our master branch
    git merge Origin/master # merge Origin/master on top of our master
    

    Möglicherweise treten hier einige zusätzliche Zusammenführungskonflikte auf. Dies sind jedoch nur Konflikte von Dateien, die zwischen 8101fe3 und f5a7ca8 geändert wurden, enthalten jedoch keine bereits aufgelösten Konflikte von topic.

    Der Verlauf sieht folgendermaßen aus (ignoriert den korrekten Verlauf):

    *   94f1484 Merge branch 'Origin/master'  [HEAD -> master]
    |\  
    * | f5a7ca8 5                   [Origin/master]
    * | e7affba 4
    | *   8101fe3 Merge branch 'topic'
    | |\  
    | | * b62cae6 2                     [topic]
    |/ /
    * / eb3b733 3
    |/  
    * 38abeae 1
    
  3. Die letzte Stufe besteht darin, unsere Branche mit korrekter Historie und Branche mit korrektem Index zu kombinieren

    git reset --soft correct-history
    git commit --amend
    

    Wir verwenden reset --soft, um unseren Zweig (und den Verlauf) auf den korrekten Verlauf zurückzusetzen, aber den Index und den Arbeitsbaum so belassen, wie er ist. Dann verwenden wir commit --amend, um unser Merge-Commit, das früher einen falschen Index hatte, mit unserem guten Index von Master umzuschreiben. 

    Am Ende werden wir einen solchen Status haben (beachten Sie eine andere ID des Top Commits):

    *   13e6d03 Merge branch 'topic'  [HEAD -> master]
    |\  
    | * b62cae6 2                     [topic]
    * | f5a7ca8 5                     [Origin/master]
    * | e7affba 4
    * | eb3b733 3
    |/  
    * 38abeae 1
    
15
Ivan Naydonov

Angesichts der Tatsache, dass ich gerade einen Tag verloren hatte, als ich versuchte, dies herauszufinden, und tatsächlich mit Hilfe eines Kollegen eine Lösung gefunden hatte, dachte ich, ich sollte einsteigen.

Wir haben eine große Codebasis und müssen zwei Filialen bearbeiten, die gleichzeitig stark modifiziert werden. Es gibt einen Hauptzweig und einen Nebenzweig, wenn Sie welche haben.

Während ich den sekundären Zweig mit dem Hauptzweig zusammenführe, wird die Arbeit im Hauptzweig fortgesetzt, und wenn ich fertig bin, kann ich meine Änderungen nicht pushen, da sie nicht kompatibel sind.

Ich muss daher mein "Zusammenführen" "rebasieren".

So haben wir es endlich geschafft: 

1) Notieren Sie den SHA. Beispiel: c4a924d458ea0629c0d694f1b9e9576a3ecf506b

git log -1

2) Erstellen Sie die richtige Historie, aber die Zusammenführung wird unterbrochen.

git rebase -s ours --preserve-merges Origin/master

3) notieren Sie die SHA. Beispiel: 29dd8101d78

git log -1

4) Setzen Sie sich jetzt wieder auf den vorherigen Bereich zurück

git reset c4a924d458ea0629c0d694f1b9e9576a3ecf506b --hard

5) Führen Sie nun den aktuellen Master in Ihrem Arbeitszweig zusammen

git merge Origin/master
git mergetool
git commit -m"correct files

6) Jetzt, da Sie die richtigen Dateien, aber den falschen Verlauf haben, holen Sie sich den richtigen Verlauf über Ihre Änderung mit:

git reset 29dd8101d78 --soft

7) Und dann - ändern Sie die Ergebnisse in Ihrer ursprünglichen Zusammenführungsverpflichtung

git commit --amend

Voila!

3
Claude Peloquin

Es sieht so aus, als würden Sie Ihre erste Zusammenführung entfernen. Sie können folgendermaßen vorgehen:

git checkout master      # Let's make sure we are on master branch
git reset --hard master~ # Let's get back to master before the merge
git pull                 # or git merge remote/master
git merge topic

Das würde dir geben, was du willst.

1
Antoine Pelisse
  • Aus Ihrer Zusammenführungsverpflichtung
  • Cherry-Pick die neue Änderung, die einfach sein sollte
  • kopiere deine Sachen
  • wiederholen Sie die Zusammenführung und lösen Sie die Konflikte, indem Sie einfach die Dateien aus Ihrer lokalen Kopie kopieren.
0
Tobi B