Search code examples
gitdiffrebase

How can I git diff branches after rebasing on top of master


Say I have a repo as:

A - B - C <- master
  \ D - E <- dev

Then, I create a new branch feature from dev and I rebase it on top of master

A - B - C <- master
 \        \ F - G <- feature 
  \ D - E <- dev

While doing the rebase, I need to merge manually a few files to get F and G.

Given this situation, when I finish the rebase, how can I see a diff of these changes I've made during the rebase?

More formally, I would like to get the diff between F and the resulting commit first after rebasing dev on top of master with -Xtheirs. Same for G (with perhaps a slightly different command) and the second commit from this potential rebase.

Is there any way of doing this in a concise way without needing to actually rebase dev on top of master?


Solution

  • TL;DR

    The simplest way to show the information you want is to diff the diffs.

    The story

    I tend to compare the contents of the commit themselves in situations like yours.

    On the Bash prompt, the command

    diff <(git show D) <(git show F)
    

    will diff the diffs for you.

    You'll get some spurious diffs: the sha1's of the commit and the files, the line numbers if those changed, and the context lines if those changed

    So you need to look for lines that start with < +, < -, > + and > - to see the real differences between the change set in D and the change set in F.

    Any changes you made manually for whatever reason, whether it's fixing a conflict or making further changes, will be shown in this diff.

    Cleaner output

    This variant of the diff command, proposed by OP @Lezkus in the comments, removes a lot of the noise in the diff output:

    diff -I '@@[^@]*@@' -I '^index.*' -I 'commit.*' <(git show D) <(git show F)
    

    The caveat

    This is not exactly what you asked -- a script that cherry picks D onto C, diffs the results, and reverts it all would yield more precisely what you asked for -- but I think it's a decent compromise and it's super quick to run, requiring no setup or reverting of temporary operations.