What is the difference between `git diff topic1 topic2 ^master` and `git diff topic1..topic2 ^master`?

前端 未结 1 1797
清歌不尽
清歌不尽 2020-12-07 04:07

I am trying to compare changes that were made on two different branches that forked from master at two different commits. So, I do not want to see the changes that were made

相关标签:
1条回答
  • 2020-12-07 05:00

    The revision parsing code for git diff is overly permissive, and then winds up doing the wrong thing with multiple arguments. In some cases it mis-interprets its arguments if you give it more than two commit IDs and at least one of them is negated (as you are doing). In particular, it winds up treating the (positive-ref, positive-ref, negative-ref) triple as if it were the three-dot syntax.

    Several weeks ago, I submitted a Git fix specifically for this, which (as usual) has been ignored (sigh). Even with this fix, though, you can't get what you want. Except for the even-more-special case of combined diffs—which still are not what you want—you can only have Git compare at most two existing trees already stored in the repository:

    I am trying to compare changes that were made on two different branches that forked from master at two different commits. So, I do not want to see the changes that were made on master in-between the two branches.

    In other words, you have a commit graph that goes something like this:

              a--a--A      <-- feature-A
             /
    ...--o--*--o--o-...    <-- master
                   \
                    b--B   <-- feature-B
    

    and you want to compare the tip-most commit of feature-A—i.e., commit A—to what you would get if you took the two commits that are exclusively on feature-B (commits b and B) and applied them to the commit I marked with a *, i.e., the point where feature-A branched off from master.

    You can quite easily have Git compare the tree for commit A vs the tree for commit B. This is what git diff feature-A feature-B and git diff feature-A..feature-B do. But this is not what you want.

    To get a diff between the tree for commit A and a (currently hypothetical) tree B' you must create a temporary branch,1 and then cherry-pick the two feature-B-only commits onto *:

              a--a--A      <-- feature-A
             /
    ...--o--*--o--o-...    <-- master
             \     \
              \     b--B   <-- feature-B
               \
                b'-B'      <-- temporary branch
    

    Now you really do have a commit B' with the tree that you get if you "take away" the two intermediate master commits, and now you can compare the tree for A against this new commit's tree.


    1It is technically possible to do all this without a temporary branch, by constructing the hypothetical tree B' in the work-tree, without committing, using git cherry-pick -n, rather than as a series of commits on a temporary branch using git cherry-pick. But commits in Git, including temporary ones on a temporary branch, are fast enough and cheap enough that this does not buy you much—and if some of the cherry-pick steps require resolving merge conflicts, it just makes everything that much more difficult.

    0 讨论(0)
提交回复
热议问题