4

So here's the situation:

There's a big task with over 30 commits that I'm reviewing. Already went through one cycle of review and fixes and now I'd like to review the fixes only. The Problems is, meanwhile around 200-something commits were merged from master to the feature branch:

         code review
              ↓
    B---D---F---H---J---L---M---N---O feature
   ↗                   ↗
--A---C---E---G---I---K master

How do I go about diffing the changes of the H to O range to F, while ignoring what came in from the merge?

Rebasing is troublesome due to many conflicts.

pilau
  • 6,635
  • 4
  • 56
  • 69
  • You can create a temporary branch on `O`, check it out then run `git rebase --onto J L`. This way the new branch skips the `L` commit and `git diff F` includes only the changes introduced by commits `H, J, M, N, O` (I assume here that `L` is the merge commit). – axiac Mar 28 '18 at 10:27
  • - Chcekout on F, create new branch there, cherry pick changes H,J, L(unleess it's a merge?), M,N,O. Git diff F on that new branch – running.t Mar 28 '18 at 10:29
  • I updated the answer: rebasing causes many conflicts, so I'd rather try other options without having to rebase – pilau Mar 28 '18 at 10:37
  • If there were many conflicts in L, there could be no good answer. Review separately F->J, the conflict resolution in L, L->O and overall change as K->O – max630 Mar 28 '18 at 11:22
  • @max630 is there any special way to review the conflict resolution? – pilau Mar 28 '18 at 11:44
  • except `git show`, you could try something from https://stackoverflow.com/q/5072693/2303202 – max630 Mar 28 '18 at 12:15
  • Thank you very much Max! – pilau Mar 28 '18 at 13:37

2 Answers2

2

Assuming that L is the merge commit, you can create a temporary branch on O, check it out then run git rebase --onto J L. This way the new branch skips the L commit and git diff F includes only the changes introduced by commits H, J, M, N, O. Make sure you don't have uncommitted changes before starting. The existing branches are not affected.

The commands are:

git checkout -b temp O
git rebase --onto J L
git diff F

When you end the review you can run:

git checkout feature
git branch -D temp

to checkout feature again and remove the temporary branch.

axiac
  • 68,258
  • 9
  • 99
  • 134
  • Thank you for the quick answer! I forgot to mention, I did already try rebasing but there are so many conflicts, I'd rather try other options without having to rebase – pilau Mar 28 '18 at 10:36
  • You get conflicts on rebasing because the changes in the commits after the merge (`M`, `N`, `O`) operate on lines changed by the merge. You cannot skip the merge commit in this situation. – axiac Mar 28 '18 at 10:38
  • I think the best way in this case is to review the changes introduced by commits `H` and `J` (`git diff F J`) then review the changes introduced by the commits `M`, `N` and `O` (`git diff L O`). – axiac Mar 28 '18 at 10:39
  • Thanks axiac. I think I'm going to go with [running.t's solution](https://stackoverflow.com/questions/49530781/git-diff-a-range-but-ignore-merges/49532170?noredirect=1#comment86070269_49530781) of checking out a branch from `F`, and then cherry-picking all the rest bar the merge commit – pilau Mar 28 '18 at 10:45
  • Cherry-picking doesn't change anything. If skipping `L` produces conflicts, you'll get them no matter how you attempt to apply `M`, `N` and `O`. The work Git does to perform `git cherry-pick` and `git rebase` is the same. – axiac Mar 28 '18 at 10:47
  • 1
    Unfortunately you are right! I guess reviewing commit-by-commit is the only way to go in this particular case. I just scheduled a dev meeting to discuss rebasing instead of merges, and other workflow matters. Thanks! – pilau Mar 28 '18 at 11:00
0

You mention that rebasing generates a lot of conflicts. That says to me that the code in M through O is likely dependent on the merge, and reviewing it without the merge may be a fruitless endeavor. That said, there are some things you could try:

One option is to check out feature, create a temporary branch, and on the temporary branch revert L. This would create a new commit ~L which you could compare to F. If the rebase attempt generates conflicts, this may also generate conflicts; but at least you'd only have a single resolution step.

Another option is to review in two steps. First compare F to J, then compare L to O. It means looking at two patches, but if that's two modest-sized patches instead of one gigantic one consisting mostly of "noise", it could still be a win.

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52