83

I got back on an old project and I ran the nice git status to figure out what was going on and I noticed way too many branches! I want to do some housekeeping before starting to work on this again but I'm not sure which branch comes from which..

E.G. Does "branchA" derive from "develop"? Does "branchB" derive from "master" or "branchA"??

How can I answer the sample questions above?

codeforester
  • 39,467
  • 16
  • 112
  • 140
Marsellus Wallace
  • 17,991
  • 25
  • 90
  • 154
  • possible duplicate of [Git: Finding what branch a commit came from](http://stackoverflow.com/questions/2706797/git-finding-what-branch-a-commit-came-from) – Cascabel Mar 27 '12 at 23:43
  • The possible duplicate is really a bit flimsy - it could be exactly what you want for some branches, but probably doesn't cover everything. Probably should've just linked to it, sorry. – Cascabel Mar 27 '12 at 23:44
  • 1
    This cannot be done. If you want to know anything about your branches git is not the right tool. Branches (in git) are ephemeral and thus highly unreliable. A graphical tool can give you hints but no answer. – Thomas Sep 14 '17 at 12:58

9 Answers9

50

git merge-base shows the commit that is the common ancestor of two branches.

Simple usage: git merge-base <branch> <branch> shows the common commit of the two branches.

technocrat
  • 3,513
  • 5
  • 25
  • 39
patthoyts
  • 32,320
  • 3
  • 62
  • 93
  • See http://git-scm.com/docs/git-merge-base As it states, you provide two commit ids for comparison. So if you have master and devel branch in some project, `git merge-base master devel` will tell you the commit that is the common ancestor of these two branches. – patthoyts Aug 28 '14 at 12:37
  • 1
    This command only returns a commit-hash. For futher information eg: **git log -1 commit-hash** ? – grenix May 06 '21 at 09:59
27

There's no canonical answer for this, since branches are simply pointers to certain commits in a DAG. For instance, master and foo could be pointing at the same commit; if you then create a branch from foo, it's effectively the same as creating a branch from master.

That said, if you visualize the commit graph (via gitk or some other graphical history tool), you can get a general sense of where the branch points are in the commit graph, versus where various branch pointers are pointing.

Amber
  • 507,862
  • 82
  • 626
  • 550
  • If you use git's "grafts" you can create cycles so that it's no longer a DAG. Apparently this is bad. :-) (Not surprisingly ... although it should mostly "just work" anyway, not that I have tried it.) I suspect you can also create cycles with `filter-branch`, not that I have tried that either. Straighforward merge seems to reject attempts to create cycles, at least. – torek Mar 27 '12 at 21:53
24

If you are already on a branch then you can get the commit that is the point where it forked from another branch, say master, like this:

git merge-base --fork-point master

Then fetch the commit message with git show <commit-id>. If you got no commit ids then this branch did not come from that.

For example I'm not sure if I forked from dev or master:

$ git checkout my-branch
$ git merge-base --fork-point master
$ git merge-base --fork-point dev
1770f75fa178df89a40ddc5f13ecd6bc597c17df
$ git show 1770f75fa178df89a40ddc5f13ecd6bc597c17df
commit 1770f75fa178df89a40ddc5f13ecd6bc597c17df (origin/popup-stack-12, dev)
Merge: 37f79cf f8a9795
Author: Superman <super@example.com>
Date:   Sun Mar 29 23:14:40 2020 +0000
...

I forked this branch from dev.

John Mee
  • 50,179
  • 34
  • 152
  • 186
Cory Klein
  • 51,188
  • 43
  • 183
  • 243
8

The command line git executable also has the ability to display a rudimentary tree of branching and merging, use the --graph option to git log. You can do all sorts of nice enhancements to it with the other options. Try these on for size:

simplest:

git log --graph

nice:

git log --graph --decorate --simplify-by-decoration --color --oneline --date=local

the full monty:

git log --graph --decorate --simplify-by-decoration --color --oneline --date=local --pretty=format:'%C(auto) %h %d %C(reset)%s (%C(cyan)%ad %ae%C(reset))'
smonff
  • 3,399
  • 3
  • 36
  • 46
Walt Howard
  • 7,676
  • 1
  • 16
  • 11
7

As others mentioned, there's no canonical answer, but git reflog can help in some cases by showing your local git history:

a1b2c3d4 (HEAD -> my_current_working_branch) HEAD@{0}: pull origin master: Merge made by the 'recursive' strategy.
aaaa1111 (origin/my_current_working_branch) HEAD@{1}: commit: Added bar
def123aa (forgotten_branch) HEAD@{2}: checkout: moving from forgotten_branch to my_current_working_branch

In this case I can see I branched from forgotten_branch to my_current_working_branch, and merged master in.

It won't always give you the information you're looking for, but can help in certain situations.

JerkyTreats
  • 507
  • 6
  • 10
2

Stick to a naming convention and spare yourself all the confusion.

When creating a branch from master - lets say, to implement an email feature - you can name it master_emailfeature. Then if you need to create a sub-branch from this branch to implement ssl for emails then you can name it master_emailfeature_sslandtls.

This makes it clear which branch was created from which just by looking at the branch's name.

Basil Musa
  • 8,198
  • 6
  • 64
  • 63
2

You can use a graphical tree viewer, I'm using gitg to view branches and diffs, although I'm using the command line for the real work most of the time.

Not_a_Golfer
  • 47,012
  • 14
  • 126
  • 92
2

If you are working on Windows or Linux (with GUI), just install the beautiful git-extensions. They can visualize you the branch / merges tree perfectly fine.

http://code.google.com/p/gitextensions/downloads/detail?name=GitExtensions207.zip&can=4&q=

Greetings,

Mario Fraiß
  • 1,095
  • 7
  • 15
1

If you want to figure out which remote branch your local branch derived from, this command can shed some light.

git remote show origin

Scroll down until you see "Local branches configured for 'git pull':" and underneath that, a list of all your local branches are displayed and the remote branch each will merge with.