Hi squirrel, On Sat, 20 Aug 2022, squirrel wrote: > When someone makes a PR, they may be asked to rebase their feature branch onto > main to resolve conflicts. It may be useful to quickly see what changed during > the rebase, that is how the new version of PR is different to the old one. > > If the PR branch has not been reparented, you may get away with `git diff`. > But if it has, `git diff` may contain a lot of changes from upstream. Instead, > `git range-diff` can be used. > > The problem with this is that in this case `git range-diff` can show chunks > with changes that have nothing to do with changes in the PR. Consider this > repository (commands are runnable): > > git init > git branch -m main > echo -e "a\nb\nc\nd\ne\n1\n2\n3\nf" > file > git add file > git commit -am "a b c d e f" > > git checkout -b foo > echo -e "a\nb\nc\nd\ne\n1\n2\n3\nfoo" > file > git commit -am "f -> foo" > > git checkout main > git checkout -b cat > echo -e "a\nb\ncat\nd\ne\n1\n2\n3\nf" > file > git commit -am "c -> cat" > > We got a few letters of alphabet on separate lines on main, and in branch > foo `f` is changed to `foo`, and in branch cat `c` is changed to `cat`. > > $ git log --all --graph --pretty=oneline > * 90e873e3 (HEAD -> cat) c -> cat > | * 3d8c1baf (foo) f -> foo > |/ > * 4d2337dd (main) a b c d e f > > Now, still on cat, let's combine the two changes. > > $ git rebase foo > Successfully rebased and updated refs/heads/cat > > $ git log --all --graph --pretty=oneline > * 98e554a0 (HEAD -> cat) c -> cat > * 3d8c1baf (foo) f -> foo > * 4d2337dd (main) a b c d e f > > Now, `git rebase foo` worked automatically, so *the change* of the last commit > on `cat` is the same as it was without rebase, which is changing `c` to `cat`. > But if we run `git range-diff`, we will see this: > > $ git range-diff 90e873e3...cat > -: ------- > 1: 3d8c1ba f -> foo > 1: 90e873e ! 2: 98e554a c -> cat > @@ file > +cat > d > e > - f > + foo > > It seems that this chunk is included for the sole reason that the change from > `foo` is sort of close. If we try the same code, but put the lines `c` and `f` > further apart, for example by replacing `e\n` with `e\n1\n2\n3\n` in the > commands above, the output would be, as expected, > > $ git range-diff f1e0a6cc3...cat > -: ------- > 1: 4db06be f -> foo > 1: f1e0a6c = 2: cc56db7 c -> cat > > I suggest not showing uninteresting chunks like that, or perhaps having a > command line option that controls how close together the changes must be in > order to be included in the output. In a generic tool like `range-diff`, it is virtually guaranteed that the default operation does not satisfy all use cases. This example demonstrates that ;-) In general, the `A...B` form does what users want, namely show you pairs between the "left" and the "right" commits in that symmetric range. However, you _can_ use `range-diff` in a way that it produces what you want. In the example you provided above, `git range-diff foo cat@{1} cat` should do it. That would be the `<upstream> <before> <after>` form. In general, you might need to play with `git merge-base --fork-point` (see *1* for more information). I could imagine that the following command might give you what you want in even more cases: git range-diff \ $(git merge-base --fork-point @{u} @{1})..@{1} \ $(git merge-base --fork-point @{u} HEAD)..HEAD Ciao, Johannes Footnote *1*: https://git-scm.com/docs/git-merge-base#_discussion_on_fork_point_mode