<commit_before>---
layout: post
title: find ancestor commits
category: intermediate
published: false
---

Ever seen this message when trying to delete a branch?

<pre>
$ 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'
</pre>

Since the branch you're currently on doesn't have the branch you want to delete merged in. This is one of the many ways that Git tries really hard not to lose your data for you. So, how would you find out if a given branch (or commit) is merged into your current branch without having to try and delete it?

The @git branch@ command has a few flags that will help out with this problem. The @--contains@ tag will figure out if a certain commit has been brought in yet into your branch. Perhaps you've got a commit SHA from a patch you thought you had applied, or you just want to check if commit for your favorite open source project that reduces memory usage by 75% is in yet.

<pre>
$ git log -1 tests
commit d590f2ac0635ec0053c4a7377bd929943d475297
Author: <NAME> <<EMAIL>>
Date:   Wed Apr 1 20:38:59 2009 -0400

    Green all around, finally.

$ git branch --contains d590f2
  tests
* master
</pre>

From these results we can see that commit @d590f2@ has been merged into the @tests@ and @master@ branch.

Back to the original conundrum: how to figure out if a branch has been merged in! The @--merged@ and @--no-merged@ flags can do just this for you. The former will tell you what branches have that "treeish":http://book.git-scm.com/4_git_treeishes.html merged in, while the latter will do the opposite.

In this case, our @docs@ branch is not fully merged into our @master@ branch:

<pre>
$ 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).
</pre>

If you're brave, you could use a combination of the @git rev-parse@ and @git rev-list@ to find if a commit is in the history of a given branch or not. I originally hacked this together until someone on the "#git IRC channel":http://gitready.com/beginner/2009/03/02/where-to-find-the-git-community.html let me know about the obvious solution in @git branch@. @rev-parse@ takes a treeish and converts it into the SHA it belongs to. @rev-list@ can print out commits in a myriad of different ways and deserves a tip all on its own.

<pre>
$ git rev-list master | grep $(git rev-parse docs)
$ git rev-list master | grep $(git rev-parse tests)
d590f2ac0635ec0053c4a7377bd929943d475297
</pre>

The first command returns nothing at all, since the @HEAD@ commit in @docs@ doesn't exist in the timeline for the @master@ branch yet. On the other had, grep finds the @HEAD@ commit for tests in @master@ as expected.

Hopefully this saves you some time when dealing with multiple branches and wondering if they've been merged in yet. If you have other suggestions for dealing with this situation, leave a comment!







<commit_msg>[de] Translated 2009-04-03-find-ancestor-commits<commit_after>---
layout: post
title: Vorfahren von Commits finden
category: intermediate
published: true
---

Schonmal diese Nachrichte beim Löschen eines Branches gesehen?

<pre>
$ 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'
</pre>

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.

<pre>
$ git log -1 tests
commit d590f2ac0635ec0053c4a7377bd929943d475297
Author: <NAME> <<EMAIL>>
Date:   Wed Apr 1 20:38:59 2009 -0400

    Green all around, finally.

$ git branch --contains d590f2
  tests
* master
</pre>

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":http://book.git-scm.com/4_git_treeishes.html 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:

<pre>
$ 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).
</pre>

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":http://de.gitready.com/beginner/2009/03/02/where-to-find-the-git-community.html 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.

<pre>
$ git rev-list master | grep $(git rev-parse docs)
$ git rev-list master | grep $(git rev-parse tests)
d590f2ac0635ec0053c4a7377bd929943d475297
</pre>

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.
{'fraction_non_alphanumeric': 0.06832390592438226, 'fraction_numerical': 0.030663888061923193, 'mean_word_length': 4.236944660950896, 'pattern_counts': {'":': 4, '<': 25, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '926469', 'n_tokens_mistral': 2204, 'n_tokens_neox': 2046, 'n_words': 1013}