如何验证功能分支不包含任何合并提交并且是最新的?

How to verify that feature branch doesn't contain any merge commits and is up to date?

我将 GitHub 与 CircleCI 一起使用,并想验证所有到达我的 master 分支的拉取请求都来自一个功能分支,该分支不包含 master 中不存在的合并提交,并且功能分支已重新基于最新的 master。

这意味着我总是希望历史看起来像这样:

*   1924562 Merge pull request #2 from feature-2
|\
| * 02ebbde Commit 6
| * 514752d Commit 5
| * 204d48f Commit 4
| * a1d16da Commit 3
|/
*   d03cd1e Merge pull request #1 from feature-1
|\
| * d6fe4ad Commit 2
| * 7aa415c Commit 1
|/
*   6ac1979 Initial commit

而不是例如这个:

*   1924562 Merge pull request #2 from feature-2
|\
| *   1abfe7f Merge branch 'extra-branch-1' into feature-2
| |\
| * | 02ebbde Commit 6
| * | 514752d Commit 5
| | * 204d48f Commit 4
| |/
| * a1d16da Commit 3
|/
*   d03cd1e Merge pull request #1 from feature-1
|\
| * d6fe4ad Commit 2
| * 7aa415c Commit 1
|/
*   6ac1979 Initial commit

而不是这样:

*   1924562 Merge pull request #2 from feature-2
|\
| * 02ebbde Commit 6
| * 514752d Commit 5
| * 204d48f Commit 4
| * a1d16da Commit 3
* | d03cd1e Merge pull request #1 from feature-1
|\|
| * d6fe4ad Commit 2
| * 7aa415c Commit 1
|/
*   6ac1979 Initial commit

我想我可以通过 运行 一个 shell 脚本作为我的 CircleCI 管道的一部分来实现这一点,它会断言来自功能分支的每个提交都是正确的。

问题是我不确定我将如何实现这样的脚本。我想一个起点是检查仅存在于功能分支中的每个提交并验证它们是否只有 1 个父提交:

[ $(git show --no-patch --format="%P" | wc -w) -eq 1 ] || exit 1

但我不确定如何捕获显示的第二个错误情况,其中功能分支不是从 master 的最新 marge 提交开始的。 (我在想 git merge-base 可能用于那部分。)但也感觉这是必须已经解决的问题所以我不知道是否从头开始重新发明轮子很有道理。

你可以:

  1. 检查 masterbranch 的祖先:
if ! git merge-base --is-ancestor master $branch; then
   echo "please rebase $branch on top of master"
   exit 1
fi
  1. 使用 git rev-list --mergesgit log --merges 检查 branch 上是否没有合并:
cnt=$(git rev-list --count --merges master..$branch)

if [ "$cnt" -ne 0 ]; then
    echo "there are merge commits on $branch"
    exit 2
fi

1. 将确保最新的 master 是目标分支历史的一部分,2. 将确保此历史仅由 [= 之上的直线提交组成12=].