【问题标题】:Git - check if some files were manually unstaged in git mergeGit - 检查是否在 git merge 中手动取消了某些文件
【发布时间】:2021-03-31 00:47:33
【问题描述】:

场景:

在针对developmentfeature 分支合并请求中,我们可以看到feature 分支从development 还原了一些更改,尽管没有显式还原或手动更改。这使我们相信feature 分支中的某处可能存在不正确的合并。

我们怀疑在早些时候将development 分支合并到feature 分支时,其中一位开发人员意外取消了一些合并更改。

有没有简单的方法来验证是否是这种情况?

检查合并提交的详细信息时,它只显示添加到提交中的文件,但显然不显示开发人员手动取消暂存的文件。

【问题讨论】:

  • 在提交之前进行暂存。提交只记录暂存的内容,因此您可以假设,如果文件不存在,则说明它没有暂存。我担心,这就是你能走多远。
  • 我认为您需要分析功能和开发分支的日志才能发现问题。
  • 听起来您的历史远非线性的,因此发现错误提交可能并不那么容易。你检查了git show MERGE_COMMITgit diff MERGE_COMMIT^1..MERGE_COMMIT^2 的输出吗?

标签: git gitlab git-merge


【解决方案1】:

您正在尝试检查提交内容与理论合并内容。您可以做的是空运行合并以检测冲突。

https://stackoverflow.com/a/63777004/5237940 提供了执行此操作的第一个提示。 您可以对其进行调整以获取在合并期间将执行的更改的完整列表:

git merge-tree <base> <commit or branch 1> <commit or branch 2> |grep -E -- ' their | our |changed |merged|added|removed'

这将为您提供如下输出:

removed in local
  their  100644 5b194c882f6f8f0d0453b5df5a798d3164e432ed README.txt
changed in both
  our    100644 4825357e4088a083f0fee644c51c32a13d6a3df3 bar
  their  100644 0984a2a7a75695e942f0d16a89dd68a988c35c3a bar
changed in both
  our    100644 be89542ce50400c455c8715f0a2d3b12ee8d9a58 foo
  their  100644 ff14dbf9569ae99b880339588b3bcbf84687f5e6 foo

简单的获取文件列表:

 git merge-tree <base> <commit or branch 1> <commit or branch 2> |grep -E -- ' their | our ' | awk '{print $NF}' |sort -u

你得到:

bar
foo
README.txt

然后就可以使用了

git diff --name-only

获取由您的实际提交修改的文件

【讨论】:

    【解决方案2】:

    您实际上是在寻找某个合并是否是evil merge

    目前,确定是否有人在 Git 中进行了恶意合并的唯一方法是重新执行合并。你自己做同样的合并,你知道你是否做了一个邪恶的合并。然后,您可以将您的合并结果与他们的进行比较。如果您进行了非邪恶合并(“良好合并”?“天使合并”?)并且您的结果与他们的不同,那么他们一定进行了邪恶合并。

    这种方法需要大量的人工干预,因此并不适合广泛使用。作为Sousou noted / linked-to,您可以使用git merge-tree 来确定原始合并是否存在必须解决的合并冲突。如果没有,Git 本身可以在某处自动进行合并并将其与提交的合并进行比较。这可以自动化。

    正如上面的词可以所暗示的,Git 现在实际上并没有这样做。有一个新的合并策略正在开发中(参见this answerWhen would you use the different git merge strategies?),这将作为一个很好的支持技术,一旦它到位,就会有一些模糊但合理直截了当的计划来提供这个作为一种选择(我认为它会有点计算密集型,但真的很方便)。

    即使上述所有内容都已落地,仍然有一个绊脚石。在实践中会有多大,我不知道。如果以及当您手动使用“重新执行合并”方法时,您会看到它。特别是当有人运行git merge时,他们可以提供选项,例如-s ours-X ours-X find-renames=75这些选项不会记录在任何地方。 当您(或 Git)去重新执行合并时,您应该提供哪些选项?幸运的是,如果您手动重做合并,您(大概)知道应该提供哪些选项(如果有的话)。

    因此,如果您想测试恶意合并,只需将两个提示提交的第一个父提交检查为 分离的 HEAD 并运行 git merge <em>options hash</em>,提供所需的选项和第二个提示提交的哈希 ID。解决任何冲突(当然是正确的);如果你愿意,提交结果;然后将此结果与现有的合并提交进行比较。

    请注意,git log 已经显示了两个父节点的(缩写)哈希值,但如果您愿意,可以运行 git rev-parse <em>hash</em>^@。 hat-at (^@) 后缀表示给定提交的所有父级。它们按顺序出现,因此列出的第一个哈希 ID 是合并的第一个父级,列出的第二个哈希 ID 是合并的另一个父级。 (对于章鱼合并,git rev-parse 将列出两个以上的父级,但这不会是章鱼合并。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-26
      • 1970-01-01
      • 2019-02-11
      • 2012-09-27
      • 2011-03-16
      • 2013-04-02
      • 2014-05-28
      • 2010-10-30
      相关资源
      最近更新 更多