Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare changesets in Git?

Git makes it very easy to compare differences between commits, using for instance the git commands diff and difftool. Also in TortoiseGit you just select two commits to compare them.

But is there a way to compare changesets? In other words: to see the differences between the diffs of one set of commits and the diffs of another set of commits.

This would be very handy to compare (sets of) commits which are cherry-picked or have been rebased.

like image 653
Paul Pladijs Avatar asked Feb 17 '11 22:02

Paul Pladijs


2 Answers

Perhaps diff <(git show rev1) <(git show rev2) will do what you want?

like image 183
Jeff Bradberry Avatar answered Oct 12 '22 18:10

Jeff Bradberry


I think that in general to get what you want, you'll have to do some sort of merge/rebase operation in order to create something to compare with.

When you really think about it, the idea of a diff between changesets is fuzzy. I'm assuming here that you're in a situation like this:

[other history]   [ "changeset 1" ]
o - o - o - o - o ( - o - o - o - o)
 \
  (o - o - o - o - o)
  [ "changeset 2" ]

So what does it mean to compare those two? Maybe in your case, the diffs in the other history are completely disjoint from those of the two changesets, but in general, the contents of changeset 1 may depend on that other history! This means that there's no good general way for git to perform an operation like this; to do it properly, it'd have to essentially say "what would the difference between the two end commits be if I rebased?" In other words, I believe that the only reasonable definition of the diff between the changesets is the diff between the resulting end commits if they're rebased to have a common ancestor. And of course, if that's what you want, then you'll have to perform an operation in the work tree - there's no other way to muck around with diffs like this. The obvious thing to do would be to rebase, and compare the new endpoints (branches):

[other history]   [ "changeset 1" ]
o - o - o - o - o ( - o - o - o - o)
                 \
                  (o - o - o - o - o)
                  [ "changeset 2'" ]

Rebases aren't always the most fun, though, and I can think of one little way to work around this. The resulting work tree of the rebase, assuming you resolve conflicts appropriately, ought to be the same as the result of a merge:

[other history]   [ "changeset 1" ]
o - o - o - o - o ( - o - o - o - o)
 \               \
  \               ------
   \                    \
   (o - o - o - o - o) - X
    [ "changeset 2" ]

So you could perform that temporary merge, and compare the resulting commit to the end commit of the other changeset. That'll be a lot faster than doing the rebase. (Either way, you'll of course use a throwaway branch, not the real one for changeset 2.)

like image 20
Cascabel Avatar answered Oct 12 '22 19:10

Cascabel