Mikulas Dite
Mikulas Dite

Reputation: 7941

Generate git diff from a list of commits

Given a range of commits such as

b9dc80c commit msg 1 #530
88a4d3c another commit
1010bce commit msg 2 #530
040ac6d commit msg 3 #530
6b72683 another commit
ed17416 another commit
f49bbbd commit msg 4 #530

I would like to see diff of all changes in commits with #530. So far, I have all the appropriate hashes in a convinient format.

git log --oneline | grep #530 | awk -F" " '{print $1}' | xargs echo
# b9dc80c 1010bce 040ac6d f49bbbd

Can I somehow "merge" these commits into a one diff? That is, merge in memory, without actually affecting the original repository. I know I can cherry pick those commits in a separate branch and diff that, but that is too complicated.

The use case is that I want to see all changes with the ticket id specified.

example:

echo a > file
git add file && git commit "first"
echo b > file
git add file && git commit "second #XX"
echo a > file
git add file && git commit "third #XX"
the-special-command

with the "diff" I had in mind, "comparing" #XX commits should give empty output rather than two separate changes to file.

Upvotes: 4

Views: 1221

Answers (3)

Jan Hudec
Jan Hudec

Reputation: 76266

There are two options:

  • Script the merge-the-commits-to-temporary-branch dance.
  • Use combinediff command from patchutils package.

Edit: You can simplify the "log | grep" with log --grep and ask it for just hashes with --format.

Upvotes: 1

twalberg
twalberg

Reputation: 62379

Here's a slightly different approach:

git checkout -b tempbranch b9dc80c
git rebase -i f49bbbd^
# remove all the commits that you don't want from the editor, and
# replace all the other "pick" commands except the first with "squash"
git log -1 -p

This creates a new branch that initially contains the same sequence of commits as your current branch. Then, on that branch, the rebase will eliminate the commits you don't want, and squash the rest together into one commmit. Then the git log -1 -p step will show you the resulting patch (you could also use git diff HEAD^ HEAD or several other alternatives that give you slightly different output, depending on exactly what you want to use the patch for). Note that depending on the nature of the changes in each commit, you might have to resolve some conflicts during the rebase, but that's not necessarily abnormal...

After you're done with this, you can discard the temporary branch:

git checkout otherbranch
git branch -D tempbranch

Upvotes: 0

Blaise
Blaise

Reputation: 7518

Does printing git show output for all the commit sha-1s you have found would do the trick for you?:

git log --oneline | grep #530 | awk -F" " '{print $1}' | xargs git show --oneline

If you would like to "merge" the output, you would have to extract only unnecessary commit metadata...

or something more "merging friendly": git log --oneline | grep a | awk -F" " '{print $1}' | xargs git show --pretty=format:

Upvotes: 0

Related Questions