获取传递给 git 合并的分支名称

Get name of branch passed to git merge

我正在编写一个 prepare-commit-msg(作为预合并)挂钩,需要获取合并的源分支名称以传递给 REST API。换句话说,我需要从 git merge <branchname>.

中获取 branchname 的值

到目前为止,我已经尝试过 rev-parse MERGE_HEAD,但是当钩子触发时它似乎还没有设置。目前,我只是使用 git revparse --abbrev-ref @{-1} 来获取我所在的最后一个分支,但这不一定总是我想要合并的分支。

我要强制执行的规则是,除非满足某些条件,否则用户不应该能够将他们的功能分支与 master 合并。如果有更好的钩子可以做到这一点,那也会有所帮助。 Prepare-commit-msg 似乎是唯一一个将提交类型作为参数的。

So far, I've tried to rev-parse MERGE_HEAD, but it appears it has not been set yet when the hook triggers.

没错;但问题远不止于此。 (And/or 更小,也许!:-) )(我也会在这里注意到 :不合并的 git merge,即快进的跳过 一切.)

首先,考虑如果用户 运行s:

会发生什么
git merge a97131c

这个合并是什么分支?好吧,让我们画一点图:

...--*--o--o--@   <-- blarg (HEAD), xtest
      \
       o--A--B   <-- br1
           \
            C   <-- br2, br3

HEAD 告诉我们当前分支的名称是 blarg,因此尽管当前提交是提交 @(例如,其哈希可能是 9fd178a) ,一旦实际进行了合并提交,名称 blarg 将指向新的合并提交。

接下来,哪个提交是a97131c?它可能是 ABC 中的任何一个。如果它是提交 A,这本身不是任何分支提示,因此 没有 适合要合并的分支的名称。我们只是合并提交 A 所以结果将是:

...--*--o--o--o   <-- xtest
      \        \
       o-----A--@   <-- blarg (HEAD)
             |\
             | B  <-- br1
              \
               C   <-- br2, br3

如果 a97131c 是提交的 ID B,我们可能正在做 git merge br1,所以结果将是:

...--*--o--o--o   <-- xtest
      \        \
       o        @  <-- blarg (HEAD)
        \      /
         A----B   <-- br1
          \
           C   <-- br2, br3

如果 a97131c 是提交 C 的 ID,我们可能正在做 git merge br2git merge br3。 (我将绘制结果图作为练习,但请注意,和以前一样,唯一移动的 nameblarg。)

无论如何,这是一种冗长的说法,即使您可以获得某人发布的分支的 名称 作为论据——通常,您可以:它是隐藏在 .git/MERGE_MSG 中——实际上并不重要。 在 Git 中,分支名称几乎无关紧要。重要的是提交。

那么可以做什么?

The rule I'm trying to enforce is that users should not be able to merge their feature branch with master unless certain conditions have been met. If there's a better hook to do this with then that would help too. Prepare-commit-msg is the only one that seems to have the commit type as an argument.

听起来好像真正的目标是禁止导致 任何 新提交或出现在 master 上的提交,除非这些新提交满足某些约束).当然,我不知道你的限制是什么,我只能补充几点:

  • git merge 跳过常规 pre-commitcommit-msg 完全挂钩,只要合并自动顺利进行。所以你必须使用 prepare-commit-msg 钩子来尽早捕获它。

  • 但是,如果 prepare-commit-msg 挂钩在 git merge 期间退出非零,合并仍在进行中。随后的 git commit 将提交合并。此操作 执行 运行 pre-commitcommit-msg 挂钩(与成功的自动合并不同)。然而,同样,虽然退出非零会阻止提交,但合并仍在进行中,准备提交。

  • 用户总是可以跳过这些挂钩(或者不设置它们)。要真正执行某些操作,您需要在提交进入某个存储库 you 控制时执行此操作。在许多典型的设置中,这意味着在一个集中的存储库中,各个开发人员 git push 他们的工作。您可以在 pre-receiveupdate 挂钩中执行此操作(and/or 通过 Gitolite 及其更高级的系统)。

综上所述,在个人开发人员端强制执行一些规则可能仍然很好,这样他们就不会做很多工作并认为一切都很好,然后去推送并让推送失败.处理 this 的最简单方法是编写一个包装器供某人使用:而不是直接 运行ning git checkout master; git merge featureX,他们 运行 你的包装器,它会进行预检查,然后甚至会打扰 调用 git merge 如果一切正常。

您仍然可以在中心化服务器上​​严格执行,以确保开发者没有绕过规则。但是你给他们一个工具来帮助他们,然后说:"If you want to avoid stumbling over the rules very late, use this tool."