Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find merge commit which include a specific commit

Tags:

git

People also ask

Can I merge specific commit?

Find the common ancestor between the master and a-good-feature branches. Create a new branch from that ancestor, we'll call this new branch patch. Cherry pick one or more commits into this new patch branch. Merge the patch branch into both the master and a-good-feature branches.

How do you check commit is merge commit?

To see the merge commit's message and other details, use git show-merge with the same arguments.

How do I find a specific commit in git?

If you have the hash for a commit, you can use the git show command to display the changes for that single commit. The output is identical to each individual commit when using git log -p .


Add this to your ~/.gitconfig:

[alias]
    find-merge = "!sh -c 'commit=$0 && branch=${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'"
    show-merge = "!sh -c 'merge=$(git find-merge $0 $1) && [ -n \"$merge\" ] && git show $merge'"

Then you can use the aliases like this:

# current branch
git find-merge <SHA-1>
# specify master
git find-merge <SHA-1> master

To see the merge commit's message and other details, use git show-merge with the same arguments.

(Based on Gauthier's answer. Thanks to Rosen Matev and javabrett for correcting a problem with sort.)


Your example shows that the branch feature is still available.

In that case h is the last result of:

git log master ^feature --ancestry-path

If the branch feature is not available anymore, you can show the merge commits in the history line between c and master:

git log <SHA-1_for_c>..master --ancestry-path --merges

This will however also show all the merges that happened after h, and between e and g on feature.


Comparing the result of the following commands:

git rev-list <SHA-1_for_c>..master --ancestry-path

git rev-list <SHA-1_for_c>..master --first-parent

will give you the SHA-1 of h as the last row in common.

If you have it available, you can use comm -1 -2 on these results. If you are on msysgit, you can use the following perl code to compare:

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/'  file1 file2

(perl code from http://www.cyberciti.biz/faq/command-to-display-lines-common-in-files/ , which took it from "someone at comp.unix.shell news group").

See process substitution if you want to make it a one-liner.


git-get-merge will locate and show the merge commit you're looking for:

pip install git-get-merge
git get-merge <SHA-1>

The command follows the children of the given commit until a merge into another branch (presumably master) is found.


That is, to summarize Gauthier's post:

perl -ne 'print if ($seen{$_} .= @ARGV) =~ /10$/' <(git rev-list --ancestry-path <SHA-1_for_c>..master) <(git rev-list --first-parent <SHA-1_for_c>..master) | tail -n 1

EDIT: because this uses process substitution "<()", it is not POSIX compatible, and it may not work with your shell. It works with bash or zsh though.