How difftool can show branch changes but avoiding merges?

88 Views Asked by At

How to use Difftool to show all changes between two revisions avoiding changes made in merges?

I can use git log to show that changes with this command:

 git log --no-merges -p firstrevinbranch..lastrevinbranch

But git log only shows changesets, not the file, so I can read the context properly.

Is there any way to use difftool to do this and show changes between revisions buy avoiding merges? I mean, in a scneario like that:

  A---B---C---D topic
 /       /      \
E---F---G---H---I master

I want to show with kdiff only changes made in commits A,B and D, avoiding C so it's a merge commit.

Thank you very much.

1

There are 1 best solutions below

1
On

The short answer is "you can't".

The long answer is that you can, but only by first creating new commits that have different changes in them. In other words, rather than looking at what you do have now, you can make something else, and then look at that. The amount of value you get by doing this will depend in part on how well you do when you make the something-else.

Here are the facts. (Whether these are happy facts or sad facts depends on your point of view.) A commit, in Git, stores a snapshot. It does not store changes. The snapshot itself is literally an archive. No existing snapshot can ever be changed, so it's a read-only archive.

When you use git difftool with kdiff3, you:

  • have Git extract one or more commits, so that the archived files are accessible as files instead of being packed up into a Git-only format; then
  • run kdiff3 on these files, perhaps having it compare them to your current working tree (one option) or to another extracted archive (the other option).

So, given your example:

  A---B---C---D topic
 /       /     \
E---F---G---H---I master

you can get git difftool to extract the snapshot from commit A, or from commit B, or C or D or ... up through I. You can have it extract any other commit as well, and then run kdiff3 on the two extractions, or you can use the first extraction to run kdiff3 on that and whatever is currently in your working tree.

To see what might be in a hypothetical snapshot formed by taking the snapshot in B, then making the changes to that snapshot achieved by:

  1. finding the changes from C to D; then
  2. adding those changes to the snapshot in B

you will literally have to execute steps 1 and 2 first. The result can be stored anywhere you like: a temporary directory, a whole new repository, or a commit (temporary or permanent) that you make in this repository. Git can assist you with the making a new commit. The value you get from actually making such a commit is, well, up to you, but the easy way to do that is:

  • check out commit B, creating a new branch (as temporary or permanent as you like):

    git checkout -b temp-branch <hash-of-B>
    
  • cherry-pick commit D:

    git cherry-pick <hash-of-D>
    

The result of all this is a new commit J:

        J   <-- temp-branch
       /
  A---B---C---D   <-- topic
 /       /     \
E---F---G---H---I   <-- master

The difference between the snapshot in J and that in B is the same as, or similar to, the difference between the snapshot in D and that in C. For this reason you might want to call commit J by some other name, such as D', but it doesn't really matter what you call it; it's a new commit, containing an archive of the result of the cherry-pick.