Frage Warum sagt GIT nach der Zusammenführung "Schon aktuell", aber die Unterschiede zwischen den Zweigen bestehen immer noch?


Ich arbeitete ursprünglich im Zweig 'newfeature' und wurde dringend gebeten, einen Fehler im Live-Zweig zu beheben. Ich habe einen Zweig namens generalmaintenance erstellt, den Job erledigt und bin dann zum Entwickeln und Zusammenführen gewechselt. Ich möchte nun zum Zweig 'newfeature' zurückkehren und die Änderungen, die ich zuvor in den fusionierten, zusammenführen.

Als ich zu 'newfeature' wechselte und in 'develop' fusionierte, gab es Konflikte in 3 Dateien.

Ich bekam ein Gewirr, das die Konflikte löste, und entschied mich schließlich, den "Revert" -Befehl im "Team" -Menü von Aptana Studio 3 (das ist meine IDE) zu verwenden. Ich habe damit gerechnet, dass mir das vor der Zusammenführung wieder einfällt, was es anscheinend getan hat.

Wie auch immer, wenn ich wieder "entwickle", heißt es, Already-up-to-date, aber wenn Dateien zwischen den beiden Zweigen verglichen werden, sind sie sehr unterschiedlich und die Änderungen, die ich in dem anderen Zweig hinzugefügt habe, werden nicht zusammengeführt.

Wie werde ich jetzt die beiden Zweige zusammenführen?


24
2018-04-01 01:43


Ursprung


Antworten:


Wiederherstellen von Zusammenführungen und Zurücksetzen von Zusammenführungen

Meine Vermutung ist, dass Sie tatsächlich sind  Already-up-to-date.

Das Problem ist, dass git rückgängig machen macht die Zusammenführung nicht rückgängig, es macht nur die Änderungen rückgängig, die die Zusammenführung mit sich gebracht hat. Wenn Sie einen Zusammenführungs-Commit erstellen, kombinieren Sie die Commit-Historien dieser beiden Zweige.

Zusammenführen

     develop
        |
A---B---C
 \       \
  E---F---M
          |
      newfeature

Im obigen Fall develop ist in verschmolzen newfeaturedas Erstellen der M verpflichten. Wenn du laufen würdest git log newfeature Sie würden alle Zusagen aus beiden Branchen sehen, jedoch aus der Perspektive der newfeature Verzweigung, alle diese Änderungen wurden von der durchgeführt M verpflichten.

Zurückkehren

Das git revert Der Befehl entfernt keine Commits, stattdessen erstellt er einen neuen Commit, der die vom Commit enthaltenen Änderungen rückgängig macht. Zum Beispiel, wenn Sie ein Commit mit diesem Unterschied hatten ...

-This is the old sentence.
+This is ne new sentence.

Wenn dies wieder rückgängig gemacht wurde, würde der Befehl zum Zurücksetzen ein neues Commit erzeugen, das nur das entgegengesetzte diff ausführt, es dreht einfach die Zeichen um.

-This is ne new sentence.
+This is the old sentence.

Dies ist sehr nützlich, um Schäden zu beheben, die durch Commits verursacht werden, die andere Entwickler bereits haben. Es bewegt die Geschichte vorwärts, anstatt die Geschichte zu verändern.

Zusammenführungen wiederherstellen

Im Kontext einer Nicht-Fastforward-Zusammenführung kann dies jedoch einen unerwünschten Effekt haben.

     develop
        |
A---B---C
 \       \
  E---F---M---W
              |
         newfeature

Angenommen, W ist ein Reversion-Commit, können Sie sehen, wie es läuft git log newfeature wird immer noch alle commits aus der entwicklungsbranche enthalten. Dadurch werden zusätzliche Merges von develop wird nicht funktionieren, weil nichts in Ihrer Filiale fehlt.

Verwenden Git zurückgesetzt anstatt zurückzusetzen.

In der Zukunft möchten Sie möglicherweise die Verwendung in Betracht ziehen git reset --hard <ref> (woher <ref> ist der Commit-Hash der Zusammenführung), um eine Zusammenführung rückgängig zu machen, wenn diese Zusammenführung nicht mit anderen Entwicklern geteilt wurde. Im obigen Beispiel, nachdem Merge-Commit erstellt wurde M, den Befehl ausführen git reset --hard F würde folgendes ergeben.

     develop
        |
A---B---C
 \       \
  E---F---M
      |
  newfeature

Wie Sie sehen können, löscht diese Technik das Commit nicht aus, da einige Leute dazu neigen, zu denken, es bewegt Ihren Zweig einfach zurück zu dem von Ihnen ausgewählten Commit. Wenn du jetzt rennst git log newfeatureDu würdest nur Commit erhalten F, E, und A. Jetzt ist die Zusammenführung tatsächlich von Ihrem Zweigverlauf verschwunden, so dass ein späteres erneutes Zusammenführen versucht develop wird keine Probleme verursachen.

Diese Methode ist nicht ohne Komplikationen. Erkenne, dass du jetzt Geschichte veränderst, also wenn newfeature Zweig wurde nach der M Merge wurde gemacht, dann wird Git glauben, du bist einfach veraltet und sag dir, dass du rennen musst git pull. Wenn Sie nur an dieser entfernten Niederlassung arbeiten, dann fühlen Sie sich frei force-push - git push -f <remote> <branch>. Dies hat den gleichen Effekt wie das Zurücksetzen, aber auf den entfernten Zweig.

Wenn diese Verzweigung von mehreren Entwicklern benutzt wird, die schon jetzt davon abgerückt wären - dann ist das eine schlechte Idee. Das ist der Grund git revert ist nützlich, weil es Änderungen rückgängig macht, ohne den tatsächlichen Verlauf zu ändern.

Die Verwendung von Zurücksetzen auf den Verlauf ist wirklich nur eine Option für Commits, die nicht geteilt wurden.

Die Lösung - Umkehrung der Umkehrung.

Wenn das Zusammenführungs-Commit bereits freigegeben wurde, ist wahrscheinlich der beste Ansatz zu verwenden git revert auf dieser Zusammenführung. Wie bereits erwähnt, können Sie den Zweig jedoch nicht einfach wieder zusammenführen und erwarten, dass alle Änderungen aus diesem Zweig erneut angezeigt werden. Die Antwort besteht darin, das Zurücksetzen-Commit rückgängig zu machen.

Sagen wir, du hast etwas an der Arbeit gemacht develop Verzweigen Sie, nachdem Sie die Zusammenführung verehrt haben newfeature. Deine Geschichte würde ungefähr so ​​aussehen.

         develop
            |
A---B---C---D
 \       \
  E---F---M---W
              |
         newfeature

Wenn Sie zusammenführen develop in newfeature Jetzt würdest du nur bekommen D weil es das einzige Commit ist, das nicht schon Teil der Geschichte der newfeature Ast. Was Sie auch tun müssen, ist das zurückzusetzen W verpflichten - git revert W sollte den Trick tun, gefolgt von git merge develop.

                 develop
                    |
A---B---C-----------D
 \       \           \
  E---F---M---W---M---G
                      |
                 newfeature

Dies stellt alle Änderungen wieder her, die durch den ursprünglichen Merge-Commit vorgenommen wurden - die tatsächlich von C und B aber wurden zurückversetzt Wbringt es dann hinein D über einen neuen Zusammenführungs-Commit G Ich würde empfehlen, die Zurücksetzung zurückzusetzen Vor Zusammenführen in den letzten Änderungen zu developIch vermute, dass es in dieser Reihenfolge eine geringere Chance hat, Konflikte auszulösen.

TL; DR

Durch das Zurücksetzen wird ein "Zurücksetzen-Commit" erstellt. Wenn Sie eine Zurücksetzung rückgängig machen möchten, müssen Sie den Befehl revert für die Zurückkehr-Überschreibung ausführen, die beim ersten Zurücksetzen erstellt wurde. Es sollte leicht zu finden sein, git neigt dazu, automatisch Rückgaben zu kommentieren, so dass sie mit dem Wort "Reverted" beginnen.

git revert <commit>


50
2018-04-01 04:33