1

I often use git rebase --interactive for cleaning up history. It happens there are mergeconflicts, or even if there are no conflicts, there are still merges. I'm always a bit scared that something has changed even though I only changed the order of the commits, squashed them etc.

I used to keep a backup copy of my working tree to paste over the new one. Then I looked at the commit window in gitg to see if everything was the same. This is a pain though and I stopped making backup copies.

Next I made a backup branch and I found that git diff backup-branch works.

Now I tried with: (because I would like to stop making backup branches as well)

git --diff HEAD ORIG_HEAD

But that shows me changes, and when I look at the file in my working directory it looks like it hasn't changed.

What is the correct command for this scenario?

2 Answers2

2

In this case, the interactive rebase starts out by doing a checkout, and for some reason ORIG_HEAD is set after the checkout. You actually want to diff against the commit that was the HEAD before rebase did that checkout. You can find it in the reflog:

git reflog

Look for the checkout closest to the top and diff against the commit in the next line. If your reflog looks like this:

ec4bd97 HEAD@{0}: rebase -i (finish): returning to refs/heads/big_cat_branch
ec4bd97 HEAD@{1}: rebase -i (fixup): Divide the bug class into modules
5d62142 HEAD@{2}: rebase -i (fixup): updating HEAD
c28c562 HEAD@{3}: checkout: moving from big_cat_branch to c28c562
7f6bc0e HEAD@{4}: commit: Fix bug related to big cats.

then you want to diff like this:

git diff HEAD 7f6bc0e

or

git diff HEAD HEAD@{4}

And you'd expect no output unless the interactive rebase actually changed something in your code.

It'd be nice if you could pluck that entry from the reflog, but I don't know of an easy way aside from getting the commit pointed to by ORIG_HEAD (with git rev-parse ORIG_HEAD), grepping for it in the reflog, and looking at the following line. You could write a script to do it, but it's not hard to find it manually.

(You might think that ORIG_HEAD^ would give you what you want, but that gives you the commit that precedes ORIG_HEAD in the commit history, not in your local reflog. You want the latter.)

Rob Davis
  • 15,597
  • 5
  • 45
  • 49
  • Hi, that makes some sense. What I still don't understand is that `git reset --hard ORIG_HEAD` is used to undo a git rebase. See here for [example](http://stackoverflow.com/a/5375113/1115652) –  May 18 '12 at 22:12
  • 1
    `git reset --hard ORIG_HEAD` only works for non-interactive rebases. If you do `rebase -i`, `ORIG_HEAD` is reset for every commit. To save myself time, I usually tag the tip I'm rebasing, so I can get back to it (or compare it to the final branch state) easily. It's a shortcut for Rob's method above. – ellotheth May 23 '12 at 06:42
0

I personally like git log -p. I shows the diffs of every commit, including merges.

Pedro Nascimento
  • 13,136
  • 4
  • 36
  • 64