如何允许 git 合并提交到 master 但阻止非合并提交?

How can I allow git merge commits to master but prevent non-merge commits?

我有一个 Git 预提交挂钩,它阻止我提交到 master 除非被覆盖,以鼓励在分支上开发。

但是我想自动允许合并提交到 master。有没有办法从我的预提交挂钩脚本中识别合并提交?脚本如下所示:

#!/bin/bash

BRANCH=`git branch --color=never| grep '^*'|cut -c3-`

if [ "${BRANCH}D" == "masterD" -a "${GIT_COMMIT_TO_MASTER}D" != "trueD" ]
then
  echo "Commit directly to master is discouraged."
  echo "If you want to do this, please set GIT_COMMIT_TO_MASTER=true and then commit."
  exit 1
fi

已解决:对于任何正在寻找剪切和粘贴的人来说,这个钩子脚本的工作版本是:

#!/bin/bash

BRANCH=$(git rev-parse --abbrev-ref HEAD)

if [ "${BRANCH}" == "master" -a "${GIT_COMMIT_TO_MASTER}" != "true" ]
then
  if [ -e "${GIT_DIR}/MERGE_MODE" ]
  then
    echo "Merge to master is allowed."
    exit 0
  else
    echo "Commit directly to master is discouraged."
    echo "If you want to do this, please set GIT_COMMIT_TO_MASTER=true and then commit."
    exit 1
  fi
fi

我在其中添加了一些评论,但这里重要的是,在 pre-commit 挂钩中,您要测试的提交尚不存在,因此你数不过来 parents.

这是你得到的:

  • 如果您使用 git commit --amend 修改 合并提交,pre-commit 挂钩是 运行 作为通常,但它无法真正检测到这种情况正在发生。新的提交将是一个合并,但你不知道。

  • 如果您使用常规的旧 git commit 创建 non-merge 提交,文件 MERGE_HEAD 将不存在于 git 目录中,您可以看出这不会创建合并提交。

  • 如果您使用 git commit 完成冲突合并,文件 MERGE_HEAD 存在,您可以告诉这将创建一个合并提交。

  • 如果你 运行ning git merge 并且它自己成功了,它会在不使用 pre-commit 钩子的情况下进行新的提交,所以你不需要甚至在这里被调用。

因此,如果您愿意允许 git commit --amend 合并失败,您可以接近您想要的结果:只需测试 $GIT_DIR/MERGE_HEAD 是否存在,看看这是否是一个git commit 正在完成冲突合并。 (即使命令 运行 在 git 树之外,使用 $GIT_DIR 也是使这项工作起作用的技巧。Git 设置 $GIT_DIR 以便 in-hook git 命令将正常工作。)