【问题标题】:git: checkout vs merge vs ?? for resolving conflicts in favor of ours selectivelygit:结帐 vs 合并 vs ??有选择地解决有利于我们的冲突
【发布时间】:2017-04-21 22:25:16
【问题描述】:

这个主题似乎有上千种变化,很多人被问过,但我似乎找不到适合我的解决方案。

我有两条开发线,一条是我(我们的)完成的“master”,一条是分支“their_new_stuff”。两者都更改了大量文件,在同一个地方接触了许多文件并产生了冲突。

现在我需要将他们的工作合并到我们的工作中,并通过以下方式处理冲突:对于 99% 的冲突,我可以简单地接受“我们的”。但是,我还需要他们所做的所有不冲突的更改,并且在一些关键冲突中,我需要接受他们的更改或手动合并。了解哪些文件需要手动合并或合并中的“他们的”需要手动检查。

我尝试了以下方法:

尝试1:

git merge their_new_stuff
# for each file with conflicts:
    # if requires manual merge:
        # do manual merge
    # else:
        git checkout --ours all/files/not/merged/by/hand.cc

起初我以为这是我想要的,但这不起作用,因为使用“我们的”结帐是完整的文件结帐,并且不仅结帐/解决冲突的部分。所以我失去了我想要的他们的非冲突更改。

尝试2:

git merge -s recursive -Xours their_new_stuff

这不起作用,因为它不允许单个文件合并。我需要知道哪里有冲突,并且希望看到带有冲突标记的文件版本来帮助我进行手动合并,所以理想情况下我会在合并失败后做一些事情。

尝试 3:然后我想我可以做类似的事情:

git merge their_new_stuff
# for each file with conflict:
    # if file needs manual merge:
        cp file file2
git merge --abort
git merge -s recursive -Xours their_new_stuff
# for each file with manual merge:
    cp file2 file
    # merge by hand

我认为这应该可行,但感觉非常笨拙。有没有“正确”的方法来做到这一点?理想情况下,我想做这样的事情:

git merge their_new_stuff
# for each file with conflict
    # if needs manual merge
        # do manual merge
    # else
        # is there any command that does something like?:
        git remerge -s recursive -Xours file

实际上我想进行合并,获取冲突标记。检查手动合并,如果不需要手动合并,请使用“-Xours”仅在该文件上重做合并。这可能吗?

【问题讨论】:

  • Git 确实有 git-merge-file,您可以在每个文件的基础上使用它。请注意,为了 to 使用它,您必须提取(通常从索引中的三个阶段)基本(阶段 1)、本地 (--ours) 和其他 (--theirs) 文件转换成普通的文件系统文件。请注意,merge-file 确实采用 --ours 和 --theirs,它们具有 -X 样式含义。
  • @torek 谢谢,不知道。这很有趣——我想我可以做一个merge 来查看冲突,然后中止,然后在“保留我们的”文件中使用merge-file --ours 并在没有--ours 的情况下使用merge-file 来获取“手册”上的冲突标记合并”文件。如果没有更好的东西很快出现,请随时将此作为答案,我会接受。
  • 您甚至不需要(也可能不希望)中止合并:您希望将文件的三个索引版本提取到临时文件中,而那些保留在 in仅在文件仍未解析时索引。 (另见:git ls-files --stage、git ls-files --unmerged。)

标签: git merge


【解决方案1】:

Git 是一个基于 repository 的版本控制系统,这意味着 Git 分支中的状态更改通常适用于该分支中的所有文件。这在概念上与其他 VCS 工具(例如 SVN)不同,后者可以操作和提交单个文件。 Git 中没有单一文件合并的概念。如果合并两个分支,则所有文件需要在合并期间进行协调。

两者都更改了大量文件,在同一个地方接触了许多文件并产生了冲突。

我相信这是您的问题的根本原因。理想情况下,您和您的合作伙伴应该在代码库的不同区域上工作,这样当您合并时,冲突就会最小化。在我看来,大量的合并冲突意味着糟糕的分支设计和策略。两个软件人在同一个 Java 类中工作可能会导致合并冲突,两个人在同一个方法中工作更糟。试着看看你是否可以用这样的方式分离你的关注点,以便以后尽量减少冲突。

话虽如此,关于您当前的问题,我只是建议您手动合并。如果您确定要使用任一父版本的文件,请使用以下方法之一:

git checkout --theirs <path/to/file.ext>
git checkout --ours <path/to/file.ext>

【讨论】:

  • 感谢您的回答。是的,我知道合并是一个回购范围的概念,但我的印象(我是一个长期的反复无常的用户,但对 git 来说是新手)是 git 对大块级合并有很多支持。我想这就是我需要学习的吗?虽然您的理想情况会很​​好,但在这个拥有 10 名开发人员的项目中,情况并非如此。 99% 的冲突实际上是更改了构造函数接口,实际上两个人以几乎相同的方式更改了它。
  • @EthanCoon 根据我的经验,如果你不够聪明,无法解决丑陋的合并冲突,那么 Git 通常也不是。是的,您可以尝试创建脚本来自动执行此操作,但我在解决合并冲突时非常偏执,并且总是手动完成。也许其他人会给你不同的答案。
  • 我足够聪明,我只是懒惰!一目了然,我可以看到我想要“我们的”,但仅用于界面更改。由于结帐是文件方面的,而不是大块方面的,那是行不通的。如果文件只有接口更改冲突,那么解决所有有利于我们的冲突就可以了,但我似乎不够聪明,无法告诉 git 这样做。
猜你喜欢
  • 1970-01-01
  • 2018-03-11
  • 2015-10-15
  • 2012-03-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多