【问题标题】:Find out which user is incorrectly resolving merge conflicts?找出哪个用户错误地解决了合并冲突?
【发布时间】:2017-03-29 13:33:30
【问题描述】:

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

我是否遗漏了任何 git log 参数,我可以使用这些参数来查找最近发生冲突的合并,以及哪个 git 用户解决了上述冲突。

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

工作流程:-

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

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

【问题讨论】:

    标签: git version-control merge merge-conflict-resolution git-merge-conflict


    【解决方案1】:

    在某一方面,它真的很微不足道。换句话说,这很难。

    这是微不足道的:

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

    这是非常困难的:

    • 有一个合并。对吗?

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

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

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

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

    重复合并

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

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

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

    然后,给定一个合并 ID,只需将其第一个父级作为分离的 HEAD 检出,然后在其剩余的父级 ID 上运行 git merge(此位依赖于 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
    

    <em>rev</em>^@ 表示法来自gitrevisions,意思是“给定修订版的所有父级”。如果您所有的合并都是标准的双父合并,您可以使用更清晰的(但不太通用):

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

    (gitrevisions 语法和 shell set 和 shift 技术允许章鱼合并)。

    由于此合并是在分离的 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 及其文本至少非常难。 (这称为第二个图像前电阻;参见,例如,this crypto.stackexchange.com question。)

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

    【讨论】:

      猜你喜欢
      • 2012-03-01
      • 2015-10-15
      • 2018-04-19
      • 2019-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多