How to get the original branch?

Asked

Viewed 2,963 times

10

Whenever I create a branch X, I create it from another. How to know which branch I created the branch from X?

  • 1

    I was going to answer but this matter of Soen there are many alternatives. better not limit one for you =p

1 answer

6


This is a translation/adaptation of the answers of this question by Soen, following the recommendations of the Help Center on the translation of content into Portuguese.


The commits of Git form a DAG (acronym for "Directed Acyclic Graph"). The branches are just Labels ("names"/"surnames") that point to commits specific to this graph. Therefore, the relationship between two branches different can vary with time, but the relationship between two commits does not change. Ex:

---o---1  <- foo
        \
         2---3---7  <- bar
              \
               4
                \
                 5---6  <- baz

Looking at this history, it seems that baz was created from an old version of branch bar. But what if we erase bar?

---o---1  <- foo
        \
         2---3
              \
               4
                \
                 5---6  <- baz

Now it seems that baz was created from foo. But the ancestors of baz haven’t changed, we just removed the label bar (and the commit 7 disappears from the history because it is not possible to reach it by any branch existing - it is called dangling commit).

But what if we add a new label to commit 4?

---o---1  <- foo
        \
         2---3
              \
               4  <- quux
                \
                 5---6  <- baz

Now it seems that baz was created from quux. Again, the ancestors haven’t changed, just the Labels.

Anyway, if the question we want to answer is "the commit 6 is a descendant of the commit 3?" (assuming that 3 and 6 are names of commits valid), so the answer is "yes", independent of branches baz and quux exist.

Now if the question is "from which branch baz was created?", there is no reliable way to know. In the above example, it could be foo, of quux or a branch that has already been erased. You could even check the date of creation of foo or quux, to try to find out if they already existed when baz was created, or in the case of a branch that was erased, check in the reflog if he existed at that time. But it’s not as simple a process as you can see in the respective links.


Another way to attack this problem is to change it to: "find the commit closest to my branch current one belonging to another branch, and tell me that branch that’s the one".

The command is:

git show-branch -a \
| grep '\*' \
| grep -v `git rev-parse --abbrev-ref HEAD` \
| head -n1 \
| sed 's/.*\[\(.*\)\].*/\1/' \
| sed 's/[\^~].*//'

It works that way:

  1. Shows a history of all commits, including branches remote
  2. Ancestors of commit are indicated by an asterisk, so we ignore the rest.
  3. Also ignore the commits of branch current.
  4. The first result will be the branch nearest ancestor. Ignore other results.
  5. The names of branches are shown [in square brackets]. Ignore the square brackets, and everything outside them.
  6. Sometimes the name of branch possesses ~# or ^# to indicate how many commits there are among the branches involved. We are also ignoring this.

For example, if we have this history:

 A---B---D  <- master
      \
       \
        C---E---I  <- develop
             \
              \
               F---G---H  <- topic

By rotating it from the commit H, the answer will be develop, and rotate from I, the result will be master. Remembering that the result may vary with time, as branches are being created or erased.

Code available in this gist.


If you want, you can also create a alias for the above command. Just add to your .gitconfig:

[alias]
    parent = "!git show-branch -a | grep '*' | grep -v \"$(git rev-parse --abbrev-ref HEAD)\" | head -n1 | sed 's/.*\\[\\(.*\\)\\].*/\\1/' | sed 's/[\\^~].*//' #"

Then just turn around:

git parent

If you want to know which commit is the common ancestor of two branches, can do something like:

git merge-base topic develop

The result will be the commit E (the common ground between the branches develop and topic). It may not be the ideal answer, but it already gives some hints that maybe the branch was created from there.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.