1

我们经常遇到用户“错误地”修复 git 合并冲突和破坏事物的问题。

我是否缺少任何git log可用于查找最近发生冲突的合并以及哪个 git 用户解决了所述冲突的参数。

在某些情况下,这是当有人将 master 合并到“test”分支中时,它可能包含许多人的工作。

工作流程:-

  • 在基于 master 的特性分支中做一些工作。
  • 将功能分支合并到“测试”分支中进行测试。
  • Master 偶尔会被合并到测试分支中以保持最新状态。

git 工作流程需要改进很多并变得更严格,但是我能在短期内做些什么来发现用户错误地修复了合并冲突吗?

4

1 回答 1

2

一方面,它真的很微不足道。另一方面,这非常困难。

这是微不足道的:

  • 有一个合并。合并要么是正确的,要么是错误的。查看合并,看看它是对还是错。如果错了,作者和提交者会告诉你是谁做的(在你信任作者和提交者1的范围内)。

这是非常困难的:

  • 有一个合并。这样对吗?

没有自动方法可以找到该问题的答案。

如果您有良好的自动化测试,您可以任意接近自动回答问题。好的自动化测试并不容易,如果你试图让它们变得非常好,就会变得非常困难。

如果您没有自动化测试,但确实有一些擅长正确合并的人,您也许可以进行抽查:只需让这些优秀的人自己重复合并,并将他们的结果与之前的结果进行比较。如果相同,则原始合并已正确完成。如果它不同,则不是。

合并冲突的存在与否并不能确定合并是否正确完成。Git 没有秘密知识:它只是根据一组固定的规则组合文本。也就是说,如果您希望选择手动测试,特别是那些确实看到冲突的合并,您可以自动化这部分。只需重复合并(确保git rerere没有打开),看看是否有冲突。

重复合并

上面,短语“repeat the merge”出现了两次。您可能想知道如何重复合并。这大多是微不足道的。2 首先,找到每个合并的提交 ID:

git rev-list --merges <start-point> [additional options if desired]

这会生成一个候选 ID 列表。(您将希望将它们全部保存在某个地方,并注释您检查过的那些,以便您以后不必重新检查它们。在这里使用您喜欢的任何临时解决方案。)

然后,给定一个合并 ID,只需将其第一个父级作为分离的 HEAD 检出,并git merge在其剩余的父级 ID 上运行(此位依赖于 POSIX shell 行为和语法):

id=c79a113...          # or whatever, from your list
set -- $(git rev-parse ${id}^@)
git checkout $1        # check out first parent
shift                  # now that we have $1 out, discard $1
git merge $*           # (attempt to) merge the remaining commits

rev^@符号来自gitrevisions,意思是“给定修订版的所有父母”。如果您的所有合并都是标准的双父合并,则可以使用更清晰的(但不太通用):

git checkout ${id}^1
git merge ${id}^2

gitrevisions语法和外壳setshift技术允许章鱼合并)。

由于此合并是在分离的 HEAD 上进行的,因此生成的合并(如果它自动完成)可以通过检查任何其他提交或分支名称来轻松放弃。如果因冲突而git merge失败,则您有一个冲突的合并,索引中的通常结果;您可以继续完成合并,或使用git merge --abort终止它。(如果合并成功,则退出状态为非零,否则为非零git merge。)0


1请记住,除了通过 push 或 fetch 进行的提交传输之外,每个 Git 操作都是由完全控制他或她自己的存储库的人在本地完成的。用户当然可以撒谎并声称自己是其他人。如果你完全控制了这一点,你可以而且必须在传输边界这样做:当你从其他人那里收到一个提交时——无论是git fetch从你这边还是git push从他们那边——你知道你在和谁说话(通过您实施的任何身份验证:这完全在 Git 之外,并且现在通常来自 ssh 或 https,通常包含在 Gitolite 等第三方扩展中,或者由 GitHub 等作为服务提供)。此时,您有机会在接受提交之前进行任何您喜欢的验证。

或者,您可以使用例如 PGP 签名来检查“事后”。如果有人对某些标签和/或某些提交进行了 PGP 签名,并且您可以验证这些签名,那么您可以选择相信这些标签和/或提交是他们的。然后,您可以将该信任(当然,基于 SHA-1 的安全性以及您对签名者的信任程度)扩展到这些提交和/或标签的祖先,因为构建了一个匹配的对象预定义的 SHA-1 及其文本至少非常难。(这称为第二个原像电阻;例如,请参阅此 crypto.stackexchange.com 问题。)

2我说“几乎是微不足道的”,因为用户提供的选项在git merge此处不可用。您可以要求使用非标准合并选项的用户将它们记录在他们的提交中,或者在提交附加的注释中,但这很难强制执行。另见脚注 1:您只能在转移边界应用强制规则。

于 2016-11-15T16:01:55.880 回答