5

When I run a test on my code, I always take a snapshot of the code in git (using stash create) and attach the commit ID to the test (making sure to put it on a reflog to prevent it from being garbage collected). This way I can later easily check exactly what code lead to that test output.

But often, I want to compare that old code to my current version of the code. The problem is that my current version of the code has been rebased on the master branch, so a git diff will show the combined difference of hundreds of commits. What I currently do instead is two git shows followed by a normal (non-git) diff, but this has the huge disadvantage that for every line that has a different line number, this line number is considered a difference.

So is there an easy way to do a diff between two commits when the second commit has been rebased? So basically, I'm looking for something similar to rebasing the first commit internally, showing the diff, then getting rid of the internal rebased version of that commit. Of course, if the rebase fails, so be it, but in most cases rebases simply work for me, so this would still be useful in most cases.

I think I could write this myself, but it seems like it would be a common problem, so I'm wondering if something like this already exists?

FrederikVds
  • 551
  • 4
  • 11
  • Does `git diff old...current` not show what you want (notice the 3 dots there, not 2) – janos Aug 09 '16 at 08:18
  • No, that shows all changes to current's branch since old's parent commit (in my case, where old's parent is an ancestor of current). So it also shows hundreds of other commits. It's indeed different from two dots, but in my situation it's equivalent to `git diff old^..current` which is also not what I want. – FrederikVds Aug 09 '16 at 08:36
  • 1
    https://stackoverflow.com/a/28114114/2303202 – max630 Aug 11 '16 at 09:13
  • @max630 Yes, that's what I describe in my second paragraph. It doesn't work too well. Meanwhile I found the interdiff tool though. That gives a better result than normal diff. I'm thinking about making it an answer but first I'm going to compare it to the method via cherry-picking `old` onto `new`'s parent commit. Interdiff sometimes fails to notice parts of the two diffs that are equal so I'm thinking maybe `git cherry-pick` would be better at that. – FrederikVds Aug 11 '16 at 11:12
  • Yes, the response from @max630 is the best I've found. Basically you diff the diffs. I realized that the (Gnu?) diff option --ignore-matching-lines is a big help in cleaning up the inevitable garbage that diffing diffs produces. I had good luck with this variant: % diff -U3 --ignore-matching-lines="^@@ " <(git show b7f9f919) <(git show 8ce6b2af) – Ted Apr 23 '18 at 13:26

1 Answers1

0

I do not know of a way to do this in git directly.

But doing as you suggested, by writing a little script that does a "behind-the-scenes" rebase, should work just fine.

By the way, I would just place a tag instead of working with the stash, here.

Lastly, you may want to update the title of this question to mention rebase.

AnoE
  • 8,048
  • 1
  • 21
  • 36
  • I'm not using _the_ stash, I'm using `git stash create`, which creates a snapshot of both your index and your workspace in the form of two commits. It's like manually creating those commits and then doing a reset, but git has this built-in already. Tagging is unrelated to this: it's a way to "remember" a certain commit, but my problem was creating the commit, not remembering it, as I already remember it by saving its commit ID externally. It does prevent garbage collection, but that's what I use reflogs for, which works just as well and allows things like `test@{one week ago}`. – FrederikVds Aug 10 '16 at 12:53