Git-Rebase-Zweig mit allen übergeordneten Zweigen (oder abhängigen Unterzweigen)

Lesezeit: 5 Minuten

Benutzeravatar von knittl
gestrickt

Ist es möglich, einen Branch mit allen übergeordneten Branches mit Git zu rebasen? (Ich denke, “übergeordnete Zweige” ist die richtige Form, die hier verwendet werden sollte. Abhängig von Ihrer Sichtweise können Sie sie auch als abhängige Unterzweige bezeichnen. Wenn Sie jedoch den übergeordneten Zeigern der Commits folgen, gelangen Sie zu diesen Zweigen, also meiner Meinung nach ist fair, sie “Elternzweige” zu nennen).

Ich verwende Branches oft als schnelle/änderbare Tags/Checkpoints, um bestimmte Commits zu markieren. Alle übergeordneten Branches/Eltern-Referenzen sind vollständig in den zu rebasierenden Branch eingeschlossen; Es gibt keine Commits nur in den übergeordneten Zweigen.

* master
*
* featureA-finished
*
* origin/master

Jetzt will ich rebase -i master auf zu origin/master um den Commit zu ändern/umzuformulieren featureA-finished^

Nach git rebase -i --onto origin/master origin/master masterich möchte im Grunde, dass die Geschichte lautet:

* master
*
* featureA-finished
* (changed/reworded)
* origin/master

aber was ich bekomme ist:

* master
*
* (same changeset as featureA-finished)
* (changed/reworded)
| * featureA-finished
|.* (original commit i wanted to edit)
* origin/master

Gibt es einen Ausweg, oder stecke ich damit fest, alle übergeordneten Branches – genauer gesagt die Branch-Labels – auf den neuen, rebasierten Commits neu zu erstellen?

Diese Frage hängt mit dem Rebasing eines Zweigs einschließlich aller seiner untergeordneten Elemente zusammen, unterscheidet sich aber dennoch stark davon.

  • Du könntest statt Abzweigungen verwenden git notes um Ihre Commits zu markieren – diese werden bei Rebases automatisch mitkopiert, glaube ich. (Es ist eine neue Funktion, daher benötigen Sie die neueste Version) kernel.org/pub/software/scm/git/docs/git-notes.html

    – Kaskabel

    17. Juni 2010 um 13:50 Uhr

  • Sehen Sie auch, wie ich eine ganze Unterhistorie umbasieren würde – mehrere Zweige, mit einigen Verknüpfungen zwischen ihnen, die sich aus der Zusammenführung ergeben. Der unangenehme Teil dieser Lösung ist die Notwendigkeit, die Topic-Branch-Refs anschließend auf die neuen rebasierten Commits zurückzusetzen.

    – imz – Ivan Zakharyaschev

    14. März 2012 um 22:07 Uhr

Benutzeravatar von RobM
RobM

Laut Git Objektmodell Wenn Sie nur die Metadaten eines Commit (dh Commit-Nachricht) ändern, aber nicht die zugrunde liegenden Daten (“Baum(e)”), die darin enthalten sind, bleibt sein Baum-Hash unverändert.

Abgesehen von der Bearbeitung einer Commit-Nachricht führen Sie auch einen Rebase durch, der die Tree-Hashes jedes Commits in Ihrem Verlauf ändert, da alle Änderungen daraus gezogen werden origin/master wirkt sich auf die Dateien in Ihrem neu geschriebenen Verlauf aus: was bedeutet, dass sich einige der Dateien (Blobs) geändert haben, auf die Ihr Commit verweist.

Es gibt also keine kugelsichere Möglichkeit, das zu tun, was Sie wollen.

Das heißt, ein Commit bearbeiten mit rebase -i ändert normalerweise den Zeitstempel und Autor des Commits nicht, sodass Sie dies verwenden könnten, um Ihre Commits vor und nach einer Rebase-Operation eindeutig zu identifizieren.

Sie müssten ein Skript schreiben, das alle Verzweigungsstartpunkte gegen diese „timestamp:author“-Kennung aufzeichnet, bevor Sie eine Rebase durchführen, und dann die umgeschriebenen Commits mit derselben „timestamp:author“-ID finden und den Branch darauf rebasen.

Leider habe ich jetzt keine Zeit, dieses Skript selbst zu schreiben, also kann ich Ihnen nur viel Glück wünschen!

Bearbeiten: Sie können die E-Mail-Adresse und den Zeitstempel des Autors abrufen unter:

$ git log --graph --all --pretty=format:"%h %ae:%ci"
* 53ca31a [email protected]:2010-06-16 13:50:12 +0100
* 03dda75 [email protected]:2010-06-16 13:50:11 +0100
| * a8bb03a [email protected]:2010-06-16 13:49:46 +0100
| * b93e59d [email protected]:2010-06-16 13:49:44 +0100
|/
* d4214a2 [email protected]:2010-06-16 13:49:41 +0100

Und Sie können eine Liste der Zweige für jeden dieser Zweige basierend auf ihrem Commit-Hash erhalten:

$ git branch --contains 03dda75
* testbranch

Achten Sie auf mehrere Branches pro Commit, den gemeinsamen Vorfahren d4214a2 gehört beiden Sparten an!

Benutzeravatar von knittl
gestrickt

Sieht so aus, als ob diese Funktion langsam in Git Einzug hält. rebase wird die Option erhalten --rebase-refs was genau das tun wird, was meine ursprüngliche Antwort gefragt hat. Für die vorgeschlagene Patch-Serie siehe den Thread rebase: Befehl “ref” und Optionen –rewrite-{refs,heads,tags} auf gmane.


Aktualisierung 2022:

Die Option --update-refs ist endlich in Git v2.38.0 gelandet, das jetzt genau das kann, was vor mehr als 12 Jahren in der Ausgangsfrage gestellt wurde 🙂

Diese Funktion wurde mit Commit zusammengeführt 3d8e3dc4fc22fe41f8ee1184f085c600f35ec76f im August. Hurra!

  • Schade, dass dies anscheinend nicht in Git angekommen ist: Ich habe ein solches Feature in der aktuellen Dokumentation (Manpage) für git-rebase nicht gesehen! (git-1.7.9.3)

    – imz – Ivan Zakharyaschev

    14. März 2012 um 22:10 Uhr

Ich bin mir nicht sicher, wie genau du darauf gekommen bist, aber:

git branch -f (same changeset as featureA-finished)

sollte ausreichen, um Ihren zurückzusetzen featureA-finished Zweig mit der richtigen Geschichte.

  • ja, das meinte ich mit »Neuerstellen der Zweige auf den neuen rebasierten Commits«. Ich weiß, dass es so möglich ist, aber es wird schon bei drei Zweigen sehr umständlich

    – Strickl

    28. April 2010 um 18:19 Uhr

  • @knittl: interessant. Ein detaillierteres Protokolldiagramm dieser Zweige davor und danach könnte hier hilfreich sein.

    – VonC

    28. April 2010 um 18:46 Uhr

  • Stellen Sie sich einfach den gleichen Graphen mit 15 Commits vor, wobei jeder zweite Commit FeatureA-beendet, FeatureB-beendet, FeatureC-beendet usw. ist.

    – Strickl

    28. April 2010 um 19:11 Uhr

Benutzeravatar von Walter Mundt
Walter Mundt

Was ich raten würde, ist zu rebase featureA-finished auf zu origin/master erste. Führen Sie dann den Umformulierungsschritt durch. Danach rebasieren master auf zu featureA-finished. Dadurch erhalten Sie das gewünschte Endergebnis.

Beachten Sie, dass Sie verwenden müssen -i auf beiden Rebases und müssen möglicherweise alle Commits aus dem Original löschen featureA-finshed unten in der zweiten rebase. Wenn Sie wollten, könnten Sie ein Skript schreiben, das dies beseitigt, indem Sie den Zwischenzweig speichern und diesen als Basis für eine Rebase verwenden --onto die neue Version. Es könnte sogar eine Folge solcher “Unterzweige” handhaben, wenn Sie es richtig geschrieben haben. Wenn Sie Hilfe brauchen, kann ich versuchen, einen herauszuschlagen.

1440130cookie-checkGit-Rebase-Zweig mit allen übergeordneten Zweigen (oder abhängigen Unterzweigen)

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy