I'd like to see what branch my actual branch I'm on is derived from. I already took a look at the log but it's so noisy and I want to get 100% sure to find the correct branch in this case.
This problem cannot be answered in every case. Branches are not persistent: you are free to move branches around. The reflog will allow you to see some history of the branch, but the reflog is only local and will be limited to 90 days (by default).
You can use git reflog <branch> to get the first occurrence of this branch in your repo:
$ git reflog branch | tail -n 1
03302d2 branch@{12}: branch: Created from HEAD
In this example, 03302d2 is the first commit of that branch.
Then, you can find the branches that the parent of this commit came from.
For example, you could do
$ git branch --contains 03302d2^
See the linked question for more sophisticated ways. But note again that this search is not complete and you may miss the "correct" branch.
The following is getting close, but see Limitations.
git branch --contains $(
git for-each-ref --format='%(refname)' refs/heads/ |
xargs git merge-base --fork-point)
We are using git merge-base --fork-point to obtain a fork point as a SHA-1. merge-base requires a branch name to check against. So you can ask what's the fork-point between master and my current branch fairly easy.
As we want to check against all branches we are using git for-each-ref --format='%(refname)' refs/heads/. We then get a SHA-1 back. In order to get a branch name we are using git branch --contains
There are quite a lot of limitations around that. It just gives you a good guess which branches a repository comes from, however for git it is hard to decide which branch something comes from. Take for example
o -- o
/ ^ branch-a
o -- X -- o -- o
\ ^ branch-b
o -- o -- o
^ branch-c
From which branch did branch-c come from? The commit marked as X i on both branches branch-a and branch-b. So it could have been from either of them.
Branches in Git are simple pointers to commits. Every ancestor of the commit that the branch pointed to is part of the branch: e.g.:
a -- b -- c -- d <master
\
d -- e <foo
a,b are part of both master and foo, while b, c, d are part of master. However branches are just names to pointers. We can just set a new name to d.
a -- b -- c -- d <master
\ ^bar
d -- e <foo
Now everything on master is also on bar. Branches aren't versioned so we cannot answer the question where branches pointed to at a certain point in time. We therefore cannot clearly decide where foo was branched from. Git offers a reflog that keeps track of branch movements but expires over time.
The only save thing to say in git is the fork-point as a sha-1, due to the nature of branches being mutable. You can however rely on git merge-base --fork-point returning a SHA1 which is the actual fork-point.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With