【问题标题】:Have git raise a merge conflict for differences between branches让 git 针对分支之间的差异引发合并冲突
【发布时间】:2019-09-07 00:51:42
【问题描述】:

我有一个 github 分支,其中有大量不在主分支上的更改。当我尝试将更改分支合并到主分支时,git 会自动合并大量内容,并在添加内容直接集成到现有 html 或 javascript 的情况下引发冲突。

我希望 git 为两个分支之间存在差异的所有实例引发合并冲突,这样我就可以通过并批准每一个添加。

我已经尝试了“我们的”策略,但这只是进行了强制合并,使所有传入的更改都无法识别。

有没有办法在合并两个分支时触发两个分支之间所有差异的合并冲突?或者类似的功能可以促进这些分支的谨慎组合?我知道使用 git diff,但我希望存在的东西更像是解决合并冲突时发生的事情。

【问题讨论】:

  • 您可以执行git checkout mainbranch && git reset new-branch 之类的操作,然后查看它所做的所有更改

标签: git github merge


【解决方案1】:

我想要 [...to] 审核并批准每一项添加。

Git 的 automerge 旨在让您省去这些,但如果您不想要它,您可以将其关闭并通过其他方法应用个体差异,

git merge --no-commit -s ours thatbranch
git checkout -p thatbranch -- .

这将提示您当前分支与 thatbranch 上的内容之间的所有差异,获得您所追求的“批准每个添加”。 git commit 当你得到你想要的合并结果时。

【讨论】:

  • 谢谢。我试过了,它会提示终端中的所有更改。你知道是否有办法在 vs 代码或文本编辑器中提示更改?
  • 您可以尝试运行git diff thatbranch >diffsgit diff ...thatbranch >diffs,编辑该文件以删除您不喜欢的任何内容,然后git apply -3 <diffs,Git 有很多用于消除差异的机器,如此之多以至于一旦你偏离了人迹罕至的道路,为了避免不知所措,你真的必须在尝试弄清楚如何之前知道你在追求什么。
  • 这与 merge 不一样(尽管也许 OP 并不是真的在寻找合并)。
【解决方案2】:

有没有一种方法可以在合并两个分支时触发两个分支之间所有差异的合并冲突?

没有。问题实际上在于git read-tree(以及git merge 使用的实现它的C 代码)。阅读树只是说:

  • 索引槽 1(合并基)中的提交具有哈希 Hbase
  • 索引槽 2 (--ours) 中的提交具有哈希 Hours
  • 索引槽 3 (--theirs) 中的提交具有哈希 H他们的

    • 如果所有三个哈希都匹配,请使用任何副本,我们就完成了。
    • 如果 Hbase = Htheirs,使用我们的副本 Hours,我们就完成了。
    • 如果 Hbase = Hours,使用他们的副本 Htheirs,我们就完成了。
    • 这三个都不同:进行低级合并。
  • “完成”表示:丢弃暂存槽 1-3;将选择的哈希 ID 写入 slot 0。

合并冲突低级合并声明时发生。您可以控制调用哪个程序(如果有)来执行低级合并,但您无法控制前三个“if”测试。

或者类似的功能可以促进这些分支的仔细组合?

最接近的方法是运行git merge --no-commit,然后,对于每个索引条目(使用git ls-files --stage 获取所有索引条目),将暂存槽零中的哈希ID 与合并库中树中的哈希ID 进行比较。那就是:

  1. 使用git merge-base --all 查找合并基本提交哈希ID。如果有两个或更多,停下来寻求帮助,因为现在问题很棘手。否则,将此哈希 ID 保存为合并基本哈希 ID。无论如何,您现在也可以获取其他两个哈希 ID(git rev-parse HEAD 获取我们的,git rev-parse <em>merge-argument</em> 获取他们的)。

  2. 创建一个临时索引并使用git read-tree 用合并库中的文件填充它。 (如果它使编码器更简单,您可以推迟此步骤,它可能会这样做。)

  3. 照常使用(不带临时索引)git merge,但添加--no-commit。考虑检查退出状态,因为 0 表示“Git 认为一切顺利”,非零表示“出现问题”——包括合并冲突——但即使 Git 认为出现问题,您也可能希望继续。

  4. 读取结果索引(使用git ls-files --stage)。 git merge 认为已成功合并的每个文件都位于暂存槽零中。 git merge 认为未能成功合并的每个文件在插槽 1、2 和/或 3 中都有一个或多个条目。

  5. 读取临时索引(使用git ls-files --stage 和适当设置的GIT_INDEX_FILE 环境变量)。对于此索引中的所有文件,如果更新后的主索引中的相应文件位于插槽 0 但具有 不同 哈希 ID,则意味着 Git 从 --ours 或 @ 获取该文件987654339@ 提交。

  6. 对于 Git 认为已成功合并但与合并基础匹配的文件,使用git update-index --index-info 将合并基础、我们的和他们的文件放入槽中1、2 和 3,只留下 Git-thinks-the-merge-failed 文件(或更新它们,但更新将是无操作的)。注意仅存在于部分而非全部 3 个提交中的文件:它们的暂存槽应为零,以指示该文件在该版本中不存在。

这里的重命名文件也存在一些问题。如果 Git 认为它已成功合并,则文件将在新名称下的零槽中。合并基础名称将消失,并且这个新名称不会出现在合并基础提交中。您可以记下这一点,但请注意,如果在 --ours--theirs 中添加了一个新文件,而不是在另一个提交中,则该文件将在插槽 0 中,而不是在出现基地。

不过,大多数情况下,上述六个步骤应该会产生您想要的结果:成功合并的文件将被视为“冲突”,合并工具将看到所有三个输入。您不会在文件的 work-tree 副本中看到任何冲突 markers,但您会知道哪些文件是哪些文件,因为 git status 会调用它们 未合并

【讨论】:

    猜你喜欢
    • 2020-04-18
    • 2022-11-03
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 2013-11-02
    • 2012-10-06
    • 2013-05-10
    相关资源
    最近更新 更多