为特定文件选择 Git 合并策略(“我们的”、“我的”、“他们的”)

问题描述 投票:0回答:5

git pull --rebase
之后我正处于变基过程中。 我有一些存在合并冲突的文件。 我如何接受“他们的”更改或“我的”对特定文件的更改?

$ git status
# Not currently on any branch.
# You are currently rebasing.
#   (fix conflicts and then run "git rebase --continue")
#   (use "git rebase --skip" to skip this patch)
#   (use "git rebase --abort" to check out the original branch)
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:  CorrectlyMergedFile
#
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add <file>..." to mark resolution)
#
#       both modified: FileWhereIWantToAcceptTheirChanges
#       both modified: FileWhereIWantToAcceptMyChanges

通常我只是打开文件或合并工具并手动接受所有“他们的”或“我的”更改。 但是,我怀疑我缺少一个方便的 git 命令。

另请注意,当我看到哪些文件发生冲突以及可能存在哪些冲突时,我只能为每个文件选择合并策略。

git git-rebase git-merge-conflict
5个回答
433
投票

对于您获得的每个冲突文件,您可以指定

git checkout --ours -- <paths>
# or
git checkout --theirs -- <paths>

来自

git checkout
文档

git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...

--ours

--theirs

从索引中检查路径时,请检查阶段 #2 (
ours
) 或 #3 (
theirs
) 是否有未合并的路径。

由于之前合并失败,索引可能包含未合并的条目。默认情况下,如果您尝试从索引中检出此类条目,则检出操作将失败并且不会检出任何内容。使用

-f
将忽略这些未合并的条目。可以使用
--ours
--theirs
从索引中检出合并特定侧的内容。使用
-m
,可以放弃对工作树文件所做的更改,以重新创建原始的冲突合并结果。


247
投票

尽管这个问题已经得到解答,但还是提供一个例子来说明 git rebase 与 merge 中“他们的”和“我们的”的含义。请参阅此链接

Git 变基

rebase
的情况下,theirs 实际上是当前分支。因此,下面的命令集实际上是通过远程分支接受您当前的分支更改。

# see current branch
$ git branch
... 
* branch-a
# rebase preferring current branch changes during conflicts
$ git rebase -X theirs branch-b

Git 合并
对于 merge

theirs
ours
的含义相反。因此,为了在 merge 期间获得相同的效果,即,将当前分支更改 (
ours
) 保留在正在合并的远程分支 (
theirs
) 上。

# assuming branch-a is our current version
$ git merge -X ours branch-b  # <- ours: branch-a, theirs: branch-b

47
投票

请注意,

git checkout --ours|--theirs
完全覆盖文件,通过选择
theirs
ours
版本,这可能是也可能不是您想要做的(如果您有任何来自另一边,他们会迷路)。

如果您想对文件执行三向合并,并且仅使用 --ours|--theirs 解决

冲突的帅哥
,同时保持双方不冲突的帅哥,您可能需要诉诸 git merge-file
;请参阅
此答案中的详细信息。


20
投票
从上面的评论中引用@user456814:

git rebase -s recursive -X <ours/theirs>



git merge -s recursive -X <ours/theirs>

请记住,对于变基,“我们的”和“他们的”是相反的 合并期间它们是什么

@user456814 在 2014 年对已接受答案的评论中给出了这个有用的答案。我将其作为社区 wiki 在这里呈现,以便更容易查找、评估、更新等,因为评论在这方面是有限的。


0
投票
我正在 GitHub Actions 存储库中工作,该存储库

需要.js

 文件保存在其中,而不是在其他地方发布。所以我们必须定期管理 
.js
 合并。

我已经构建了一个

autobuild

 操作,因此每次推送时,它都会重建 
.js
 文件;这消除了我们开发人员这样做的需要。

但是,当 PR 或合并分支时,如果我们更改了

.ts

 代码中的任何内容,总是会与 js 文件发生冲突。如果我们只是在合并冲突的情况下提交它们,自动构建将会失败。所以我们必须解决它们,即使代码不准确,推送时它只会被自动构建器覆盖,但它仍然需要
编译

基于之前的优秀答案,我使用了之前答案中所示的

git checkout --theirs -- **/.js

方法,但它仍然显示了 VSCode 源代码控制窗格中的所有冲突。

所以我运行

git add **/*.js

,它会暂存所有这些更改。这比逐个浏览 UI 窗格要容易得多。

© www.soinside.com 2019 - 2024. All rights reserved.