unhammer
unhammer

Reputation: 4700

`git diff --no-merges work ^master ^notinmaster` still shows changes from notinmaster

I sometimes have a work branch that's a merge of master and one or more feature branches that haven't yet been merged to master. I can get a log of changes that are only in my work branch and not in master nor the "notinmaster" feature branch, e.g.

        -B--               <-- notinmaster
       /    \
      /   w--*--d          <-- work
     /   /  /    ·
...-*---*--C------D-...    <-- master

by doing git log --no-merges work ^master ^notinmaster, which here would show commits w and d.

However, D is actually git cherry-pick d. If I hadn't merged notinmaster into work, I would be able to see with git diff master that only the minor changes from w where real changes. However, since notinmaster is merged into work, git diff master is too messy to be useful. And it doesn't seem that I can use the --not/^ syntax to exclude notinmaster (e.g. git diff --stat --no-merges work ^master ^notinmaster gives the same output as git diff --stat --no-merges work ^master, at least on git 2.11.0).

Is there a simple way to get this kind of diff, without first reverting all the notinmaster commits?

Upvotes: 0

Views: 54

Answers (1)

Mark Adelsberger
Mark Adelsberger

Reputation: 45649

The negative commit syntax doesn't work that way with diff.

With log you're making rules for how much of the commit graph to traverse, so it's perfectly sensible to say "nothing reachable from this point in the graph"; but with diff you're just identifying two TREEs (often by identifying two commits) and comparing them. There is no graph traversal to be limited, no way to say "I want changes if they were introduced by this path only". A path in the TREEs is the same, or it's not the same, and that's all diff sees.

So the question is what assumptions you're willing to make. In this example, git show W should give the patch you want. If W might really be n commits, but you know there's nothing intervening, then you could do git diff W1^ Wn. You could do an interactive rebase, picking just the w commits to a new ref, and generate a patch from that. (You have shown already that you can use log - or rev-list if you need a lower-level command for scripting, to find the w commit(s).

Of course all of that assumes that d^ in your diagram is a pure merge, and that there's nowhere else for meaningful changes to hide. If it were me, I'd want to consider ways to simplify my workflow instead of having to reason that much about how changes might or might not be flowing.

Upvotes: 1

Related Questions