97

Pretend I branched from my master branch to a topic branch, and then I did a few commits on my topic branch. Is there a command that tells me the commit hash on the master branch that my topic branch originated from?

Ideally, I wouldn't have to know how many commits I've made ( trying to avoid HEAD^5 ).

I've googled and SO'd around and can't seem to land on the answer. Thanks!

brycemcd
  • 4,343
  • 3
  • 26
  • 29
  • http://stackoverflow.com/questions/2706797/git-finding-what-branch-a-commit-came-from can be a start, even though it is not *exactly* your question. – VonC Oct 22 '10 at 16:41
  • @VonC thanks for the link, not quite what I want but it's a good start – brycemcd Oct 22 '10 at 17:01

6 Answers6

86

You can use git reflog show --no-abbrev <branch name>. It will output all changes made to the branch, including it's creation, for example (I created branch xxx from master branch):

bdbf21b087de5aa2e78a7d793e035d8bd9ec9629 xxx@{0}: branch: Created from master

Note that this is not very reliable as reflog records can expire (90 days by default), and it seems like there is no 100% reliable way to do this.

max
  • 33,369
  • 7
  • 73
  • 84
  • 5
    Both `reflog` and `merge-base` outputs first commit before intermediate merge. I have 10-15 intermediate merges in my branch and I couldn't find a reliable way how to get the first commit in this branch. – puchu Mar 15 '18 at 17:42
86

use git merge-base master your-branch to find the best common ancestor between two branches (usually the branching point).

isherwood
  • 58,414
  • 16
  • 114
  • 157
knittl
  • 246,190
  • 53
  • 318
  • 364
  • 43
    @Bryce: do note that if you do some intermediate merges, this is going to give you the most recent common ancestor, not necessarily the first branching point. – Cascabel Oct 22 '10 at 18:01
  • This no longer seems to work. I just get the usage information: `usage: git merge-base [-a|--all] ...`. I'm guessing that adding `HEAD` to the above command would give the right answer. – Burhan Ali May 23 '14 at 16:37
  • Is there an option for short has output? git merge-base mast my_branch | git rev-parse --short HEAD – David Sopko Aug 08 '16 at 18:17
  • 3
    @DavidSopko: not sure what you mean? Does `git rev-parse --short $(git merge-base master my_branch)` work? – knittl Aug 08 '16 at 18:37
  • Yes @knittl that's it. Thanks! – David Sopko Aug 11 '16 at 14:54
  • 1
    It doesn't work if a branch was merged to master. Then it will show merge commit. – Ilia Shakitko May 01 '17 at 17:49
  • I'm getting a point that is quite far along my branch. Could be because I had rebased. :( – Adrian Dec 12 '18 at 22:31
9

The only 100% reliable way to do this is to tag the beginning of your branch when you create it. The accepted answer will not work if you merge commits back to the branch you originated your new branch from. This is sometimes done for example if you are creating a stabilizing release branch and want to merge back your fixes you find during release testing back to master. A common thing to do. If you know you will never merge commits from your new branch back to the originating branch then the accepted answer will work.

Rick Wildes
  • 141
  • 2
  • 4
  • This answer could be better if it provided some command line snippets showing how to tag the branch. Perhaps even an alias that does it automatically? – Yordan Grigorov Feb 28 '23 at 12:43
1

If branches of interest are not yet merged, just like everyone says:

  • git merge-base branch1 branch2

If you've merged your branches (e.g. topic and master, merged either way):

  • Find where the last merge happened (that's what all the current answers suggest)
    • git merge-base topic master
    • gives you sha-of-last-merge
  • Find the two (in theory, possibly more) commits that were used for the merge:
    • git rev-list --parents -n 1 sha1-of-last-merge
    • gives you sha-of-last-merge sha-of-parent-1 sha-of-parent-2
    • we're interested in the last two
  • Take those two SHA1s of parents and repeat the process:
    • git merge-base sha-of-parent-1 sha-of-parent-2
    • if you didn't have intermediate merges, this will give you the commit where the branch was first created
    • otherwise you have to keep repeating
      • the worst part here is that there's no way to know when to stop other than looking at commit messages or apply other heuristics. If you're lucky you will eventually arrive at a commit on master than only has a single parent - thet's a natural stopping point. However, if you started your topic branch from a commit on master that had several parents (i.e. a merge commit), then no luck. Need heuristics / common sense / other knowledge.
Dmitry Avtonomov
  • 8,747
  • 4
  • 32
  • 45
0

This will show you the first commit on topic:

git rev-list topic ^master | tail -n 1

This will show the commit that the branch started from, i.e. the fork point:

git rev-parse "$(git rev-list topic ^master | tail -n 1)^"

These also work in the case where you have merged master into topic since creating the topic branch. It assumes that topic started from master.


Explanation:

git rev-list topic ^master

Lists all commits on topic that are not reachable from master.

| tail -n 1

Then takes the last of those commits.

git rev-parse <rev>^

Prints the first parent of <rev>.

steinybot
  • 5,491
  • 6
  • 37
  • 55
0

The only generic way I found so far.

git reflog show --no-abbrev $(git branch --show-current) | grep "branch: Created from" | awk '{print $1;}'
Mircea Sirghi
  • 310
  • 1
  • 6