git ready

Lerne Git Commit für Commit
von Nick Quaranto, Übersetzung von Nico Gulden

Pull mit Rebase

eingetragen am 11 Feb 2009

Git-Anwender sind sich hoffentlich bewußt, dass ein git pull ein git fetch zum Herunterladen der Daten aus einem entfernten Repository durchführt und dann git merge aufruft, um die empfangenen Änderungen mit dem aktuellen Arbeitszweig zusammenzuführen. Das mag jedoch nicht immer die beste Wahl sein. Du kannst die Änderungen ebenso mittels rebase einpflegen, das um ein vielfaches sauberer ist. Das kann einfach durch die Option --rebase des Pull-Befehls erreicht werden, ungefähr so:

git pull --rebase <remote name> <branch name>

Aber warum ist das nützlich? Manchmal ist es einfacher, den Inhalt von Upstream eben nicht einzupflegen, sondern deine Arbeit auf die eingehenden Änderungen erneut anzuwenden. Für Langzeitänderungen ist ein Merge wahrscheinlich besser. Aber für kleinere Änderungen wird die Historie mittels Rebase sauberer bleiben. Nehmen wir an, ich möchte Rebase anstelle von Merge verwenden, um ein paar Upstream-Änderungen aus dem Hauptrepository von jekyll in meinen Fork zu übertragen. Das Repository sieht aktuell ungefähr so aus:

Zu Demonstrationszwecken habe ich mojombos Master ausgecheckt, so dass du sehen kannst, dass es hier ein paar Commits gibt, die mein Master-Zweig nicht hat: (Die drei Commits, die bei ‘mojombo’ beginnen und bis ‘mojombo/master’ gehen, sind nicht in der obigen Grafik)

So, holen wir die Änderungen mit Rebase von mojombos entferntem Repository in seinem Master-Zweig: (Warnungen wurden entfernt)

$ git pull --rebase mojombo master
From git://github.com/mojombo/jekyll
 * branch            master     -> FETCH_HEAD
 First, rewinding head to replay your work on top of it...

Applying: Making rake test happy on 1.8.7
Applying: Starting on yaml categories
Applying: Adding support for setting post categories...
Applying: Added publish flag to posts, not preventing... 
Applying: Making sure that posts flagged as published...
Applying: Adding explanations for new YAML front matter...
Applying: Removing some bad formatting in the README

Jetzt schauen wir wieder auf die Historie des Master-Zweigs:

Du kannst sehen, dass meine Arbeit (alles von der Bezeichnung ‘mojombo’ und aufwärts) schon auf der Arbeit in mojombos Repository aufsetzt. Großartig! Was ist aber der Unterschied zu einem normalen Pull? Wir finden es heraus.

$ git reset --hard origin/master
HEAD is now at 60709da Removing some bad formatting in the README

$ git pull mojombo master
From git://github.com/mojombo/jekyll
 * branch            master     -> FETCH_HEAD
Merge made by recursive.
 VERSION.yml    |    2 +-
 jekyll.gemspec |    7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

Zuerst habe ich das Repository zu seinem ursprünglichen Zustand zurück gesetzt und dann habe ich einen normalen Pull ausgeführt. Da es ein Merge ist, erscheint es auch als solcher:

Du kannst nun sehen, dass die Upstream-Änderungen übernommen worden sind. Ein neuer Commit verdeutlicht, dass ein Merge stattgefunden hat. Manchmal möchte man die Historie genau so gestalten, aber eben nicht immer. Es ist dir überlassen, wie du deine Historie aufbaust. Wenn du immer Rebase anstatt Merge mit git pull ausführen möchtest, hilft dir dieser Tip weiter. Er zeigt, welche Konfigurationsoptionen gesetzt werden müssen.