Another way would be to use git log and grep . This will produce one line of output if commit def456 is an ancestor of commit abc123, or no output otherwise.
git merge-base finds best common ancestor(s) between two commits to use in a three-way merge. One common ancestor is better than another common ancestor if the latter is an ancestor of the former. A common ancestor that does not have any better common ancestor is a best common ancestor, i.e. a merge base.
Multiple people can work on the same branch at the same time. When you pull (or have the other person push) their changes to you git will merge the changes together resulting in a branch with both of your changes.
git merge-base --is-ancestor <commit1> <commit2>
There is more than one way to find the answer to this. The simplest is to use
git merge-base --is-ancestor <possible-ancestor-commit> <commit>
From the documentation for git merge-base
:
--is-ancestor
Check if the first
<commit>
is an ancestor of the second<commit>
, and exit with status 0 if true, or with status 1 if not. Errors are signaled by a non-zero status that is not 1.
...
notationAnother option is to use git log
and use triple dot notation ...
to tell Git to output the set union of the child commits, minus the set intersection. Basically, it tells you how a set of commits have diverged from each other:
$ git log --oneline --graph --left-right \
--first-parent --decorate <commit1>...<commit2>
The above command will show you commits that are reachable from commit1
or commit2
, but not both, i.e. C1 UNION C2 - C1 INTERSECTION C2, in terms of set operations.
If neither commit is a parent of the other, you'll see the child commits of both, but if one is an ancestor of the other, you'll only see the output for the descendant commit, since the ancestor is contained in the path of the descendant, and is thus excluded from the output.
You can read more about git log
and triple dot notation from the following resources:
git-rev-list(1) seems like it could be used to answer this. Another way is to simply attach temporary branch labels to the commits you want to test, and then use the --contains
option for git branch
:
git branch --contains <commit-to-test>
The output will be all branches that contain the commit somewhere in their commit tree, so by using a temporary branch on the other commit, you can see if the commit you're testing is an ancestor.
From the documentation:
--contains [<commit>]
Only list branches which contain the specified commit (HEAD if not specified).
The following shell script might do the trick:
if git rev-list $SHA1 | grep -q $SHA2 ; then echo "$SHA2 is ancestor of $SHA1"
elif git rev-list $SHA2 | grep -q $SHA1 ; then echo "$SHA1 is ancestor of $SHA2"
else echo "$SHA1 unrelated to $SHA2" ; fi
Or, to neatly wrap it up into a git alias:
git config --global alias.related '!function git_related() { if git rev-list $1 | grep -q $2 ; then echo "$2 is ancestor of $1" ; elif git rev-list $2 | grep -q $1 ; then echo "$1 is ancestor of $2" ; else echo "$1 unrelated to $2" ; fi } ; git_related $1 $2'
if (( $(git rev-list $1..$2|wc -l) == 0 )); then echo "$2 is ancestor of $1"
elif (( $(git rev-list $2..$1|wc -l) == 0 )); then echo "$1 is ancestor of $2"
else echo "$1 and $2 are unrelated"
fi
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