git 相对于共同祖先的 diff 分支变化

diff branch changes in git relative to common ancestor

我发现自己经常遇到这样一种情况,我想查看所有更改的差异,即分支自分支以来引入的分支。天真

$ git diff ..branch

效果不佳,因为还考虑了 master 中的更改。我正在寻找的基本上是 运行

的更好方法
$ git diff $(git merge-base master branch)..branch

或用图形表示:

---A---B---C---D---E  <== master
        \
         F---G---H    <== branch

如何优雅地找到 BH 之间的差异?

编辑: 如我在下面的回答中所述,master...branch 是解决我的问题的方法。但是,鉴于引用的手册页片段,我仍然不知道为什么会这样。

为什么 diff master...branch 只显示与合并基础的差异,而 man rev-parse 说,它也应该包括 master 的提交?

为什么 diff master..branch 显示 masterbranch 的当前状态之间的差异,而 man rev-parse 说,它应该忽略 master-只提交?

我知道这不是您要在这里寻找的答案,但它可能会对其他人有所帮助。使用像 gitk 这样的图形化工具,你可以:

  • 打开gitk
  • 点击H,右击select "Mark this commit"
  • 点击B,右击select "Diff this -> marked commit"

现在您会在右侧看到所有更新的文件,在左侧看到所有修改的行(每个文件)。

What I'm looking for is basically a nicer way to run

$ git diff $(git merge-base master branch)..branch

创建别名如何?

git config alias.diffbr '!f() { git diff $(git merge-base master )..; }; f'

然后你可以简单地做git diffbr branch

如果您希望别名可用于您计算机上的所有存储库,请添加 --global argument to git config.

在广泛查看 git help rev-parse 并进行试验后,我发现了这条信息:

   <rev1>..<rev2>
       Include commits that are reachable from <rev2> but exclude those
       that are reachable from <rev1>. When either <rev1> or <rev2> is
       omitted, it defaults to HEAD.

   <rev1>...<rev2>
       Include commits that are reachable from either <rev1> or <rev2>
       but exclude those that are reachable from both. When either <rev1>
       or <rev2> is omitted, it defaults to HEAD.

不知何故,我总是觉得 master..branch 是我需要的,而忘记了 master...branch(三个点)。

但试验表明,三点表示法正是我要找的:

$ git diff master...branch

仅显示 branch 相对于 master.

的差异

如果您要根据分支的位置检查当前分支,只需添加 ...。所以命令看起来像

git diff master...

git diff master...HEAD相同。我是 运行 git 版本 2.17.1。这在旧版本中可能会有所不同。