git ready

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

Vorfahren von Commits finden

eingetragen am 03 Apr 2009

Schonmal diese Nachrichte beim Löschen eines Branches gesehen?

$ git branch -d docs
error: The branch 'docs' is not an ancestor of your current HEAD.
If you are sure you want to delete it, run 'git branch -D docs'

Der gegenwärtige Branch beinhaltet den zu löschenden Branch nicht, weil er noch nicht gemerged wurde. Die Nachricht zeigt, wie hartnäckig Git sich darum kümmert, dass keine Daten verloren gehen. Wie kann man also herausfinden, ob ein gegebener Branch (oder Commit) in den aktuellen Branch gemerged wurde, ohne einen Löschversuch zu unternehmen?

Der git branch Befehl hat ein paar Optionen, die bei der Lösung dieses Problems helfen. Die Option --contains findet heraus, ob ein bestimmter Commit bereits in den aktuellen Branch eingebracht wurde. Vielleicht gibt es einen Commit-Hash von einem Patch, bei dem angenommen wurde, er sei bereits eingebracht. Oder man möchte herausfinden, ob der Commit für das Open Source Lieblingsprojekt, das den Speicherverbrauch um 75% senkt, bereits übernommen wurde.

$ git log -1 tests
commit d590f2ac0635ec0053c4a7377bd929943d475297
Author: Nick Quaranto <nick@quaran.to>
Date:   Wed Apr 1 20:38:59 2009 -0400

    Green all around, finally.

$ git branch --contains d590f2
  tests
* master

Das Ergebnis zeigt, dass der Commit d590f2 in die Branches tests und master übernommen wurde.

Zurück zu unserem anfänglichen Rätsel: Wie findet man heraus, ob ein Branch bereits gemerged wurde? Die Optionen --merged und --no-merged kümmern sich genau darum. Die erste Option verrät, in welche Branches der treeish bereits gemerged wurde. Die zweite Option verrät genau das Gegenteil, welche Branches den treeish noch nicht gemerged haben.

In diesem Fall, unser docs Branch ist nicht vollständig in den master Branch gemerged:

$ git branch --merged docs
  docs

$ git branch --no-merged docs
  config
* master
  tests

$ git branch -d docs
error: The branch 'docs' is not an ancestor of your current HEAD.
If you are sure you want to delete it, run 'git branch -D docs'.

$ git branch -D docs
Deleted branch docs (884583c).

Wenn du mutig bist, könntest du eine Kombination aus git rev-parse und git rev-list verwenden, um herauszufinden, ob ein Commit in der Historie eines gegebenen Branches vorhanden ist oder nicht. Ich hatte mir das so bereits zusammengehackt, bis mich jemand im #git IRC Channel auf die offensichtliche Lösung mit git branch brachte. rev-parse nimmt den treeish und konvertiert ihn in den dazu gehörigen SHA-Hash. rev-list kann Commits in Myriaden von unterschiedlichen Wegen ausgeben und verdient einen eigenen Tipp.

$ git rev-list master | grep $(git rev-parse docs)
$ git rev-list master | grep $(git rev-parse tests)
d590f2ac0635ec0053c4a7377bd929943d475297

Der erste Befehl gibt gar nichts zurück, weil der HEAD Commit aus dem docs Branch noch nicht in der Historie des @master@Branches existiert. Andererseits findet grep wie erwartet den HEAD Commit aus dem tests Branch im master Branch.

Hoffentlich spart dir das etwas Zeit, wenn du mit mehreren Branches hantierst und dich fragst, ob die Branches bereits gemerged wurden. Wenn du andere Vorschläge für den Umgang mit solchen Situationen hast, hinterlasse einen Kommentar.