检查Y..X
中的所有提交是否都是Y
的后代的一种方法是使用git log --boundary Y..X
或git rev-list --boundary Y..X
检查该范围的边界。
从这个历史记录开始:
$ git log --graph --oneline --all
* 036a9f9 (HEAD -> X) create d.txt
* cadd199 create c.txt
| * 0680934 (Z) Merge commit '22a23fe' into Z
|/|
| * 22a23fe create b.txt
* | 8dec744 (Y) create a.txt
|/
* 878ac8b first commit
您将获得:
$ git log
036a9f9 (HEAD -> X) create d.txt
cadd199 create c.txt
- 8dec744 (Y) create a.txt # <- one single boundary commit, pointing at Y
$ git log
0680934 (Z) Merge commit '22a23fe' into Z
22a23fe create b.txt
- 8dec744 (Y) create a.txt # <- two commits on the boundary
- 878ac8b first commit # <-
一个可编写脚本的方式来检查你是否处于这种情况是:
boundary=$(git rev-list --boundary Y..X | grep -e '^-')
want=$(git rev-parse Y)
want="-$want"
if [ "$boundary" = "$want" ]; then
echo "all commits in X are descendants of Y"
fi
上述代码检查了所有提交是否在“Y”之后。你可能还会遇到以下情况:
* 036a9f9 (HEAD -> X) create d.txt
* 0680934 Merge 'origin/X' into X # <- someone created a merge commit in between
|\
| * cadd199 create c.txt
* | 22a23fe create b.txt
|/
* 8dec744 (Y) create a.txt
* 878ac8b first commit
这也会干扰变基工作流程。
如果您还想排除此选项,请使用git log
或git rev-list
的--merges
选项:
merges=$(git rev-list --count --merges Y..X)
if [ "$merges" -eq 0 ]; then
echo "all good, no merges between Y and X"
fi
关于--boundary
的文档并没有很好地解释什么是“边界提交”。
我认为这个Stack Overflow回答有一个不错的定义:
边界提交是限制修订范围但不属于该范围的提交。例如,修订范围HEAD~3..HEAD包含3个提交(HEAD~2、HEAD~1和HEAD),而提交HEAD~3作为其边界提交。
更正式地说,Git通过从指定的提交开始,并通过父链接获取其他提交来处理修订范围。它在不满足选择条件的提交处停止(因此应该被排除)- 这些就是边界提交。
pull.rebase=true
仍会将你的新提交变基到旧的提交上。对于变基工作流程,我的配置偏好是pull.ff=only
,这样如果无法快进合并部分,则拉取失败。(我建议使用此配置,并建议我的团队,在真正需要显式地将变基或合并到上游分支的情况下,可以这样做。) - TTTgit pull
,而是使用git fetch
后跟随我想要的操作。 - LeGEC