如何使用Git和命令行在合并时保留本地文件或远程文件?

255

我知道如何使用vimdiff合并修改,但是如果我只想保留整个文件或者丢弃整个文件,该怎么做呢?

我不想为每一个文件都打开vimdiff, 我需要一个命令来表示“保留本地”或“保留远程”。

例如,我合并了一个标记为已更改的文件,因为有人在windows下打开它,并改变了EOL,然后提交。当合并时,我只想保留我的版本并丢弃他的版本。

我还对相反情况感兴趣:我搞砸了,想接受远程文件,放弃我的更改。

5个回答

383

你也可以这样做:

git checkout --theirs /path/to/file

保留远程文件,并且:

git checkout --ours /path/to/file

保留本地文件。

然后执行git add,一切就完成了。

附注: 请记住,这适用于合并(merge)场景。在变基(rebase)期间,--theirs 是指你一直在工作的分支。


5
我执行了这个操作,但是没有反应。我该如何知道它是否使用了正确的文件?如果有影响,我正在使用git版本1.8.4 - Rosdi Kasim
3
为什么要使用相反的词语?我假设“theirs”是远程文件,“ours”是我的文件。 - phuclv
8
不,它们的含义是相反的。https://dev59.com/pHA85IYBdhLWcg3wD_O8 https://dev59.com/J4nca4cB1Zd3GeqP7S6T 他们的文件应该是我的文件,我们的文件是远程分支中的文件。 - phuclv
7
“简单”是的。直观易懂?不是。 - Wilbur Whateley
1
我已经每天使用Git将近3年了,每周都会学到新的东西。 - Shadoninja
显示剩余10条评论

146

这种方法似乎更直接,避免了需要逐个选择每个文件的麻烦:

# keep remote files
git merge --strategy-option theirs
# keep local files
git merge --strategy-option ours
或者
# keep remote files
git pull -Xtheirs
# keep local files
git pull -Xours

直接复制自: 如何在Git pull过程中选择对方的更改并解决合并冲突


7
喜欢这个。特别是如果有多个文件的话。 - Tek
这个问题涉及到两个不同的命令,但是没有说明这两个命令具体是做什么的。每一行代码都是干什么用的? - Alex
在找到这个答案之前,我至少查看了五个stackoverflow的回答。非常感谢。 - Bolton Bailey
嗨@keflavich,如果我正在从一个分支进行rebase到另一个分支,并且我想使用这个git merge --strategy-option theirs策略,那么我应该在什么时候输入这个命令?这是暂时的吗?我希望它只在这个rebase中生效,而不是未来的rebase。 - soMuchToLearnAndShare
1
找到了答案,很抱歉没有意识到这个线程只是合并,我以为它是合并冲突。https://dev59.com/L3A85IYBdhLWcg3wF_gO#4273436 - soMuchToLearnAndShare
错误:无法合并,因为您有未合并的文件... 8) - metamonkey

24

git checkout {branch-name} -- {file-name}

这将使用所选分支中的文件。
我喜欢这个命令,因为posh-git自动完成非常出色。它还消除了哪个分支是远程的、哪个是本地的任何歧义。 而且--theirs对我也没有用。


2
这应该是被接受的答案:没有歧义,适用于 {我} 和 {他们},支持添加整个目录。 - dotancohen

11

关于行尾标记,可以参考man git-merge

--ignore-space-change 
--ignore-all-space 
--ignore-space-at-eol

请确保将 autocrlf = false 和/或 safecrlf = false 添加到 Windows 克隆 (.git/config) 中。

使用 git mergetool

如果你像这样配置了一个合并工具:

git config mergetool.cp.cmd '/bin/cp -v "$REMOTE" "$MERGED"'
git config mergetool.cp.trustExitCode true
然后一个简单的
git mergetool --tool=cp
git mergetool --tool=cp -- paths/to/files.txt
git mergetool --tool=cp -y -- paths/to/files.txt # without prompting

能完成任务

使用简单的git命令

在其他情况下,我认为

git checkout HEAD -- path/to/myfile.txt

这应该能解决问题。

编辑可用于执行反向操作(因为您出错了):

git checkout remote/branch_to_merge -- path/to/myfile.txt

感谢您的建议,但是我不接受它,因为这不是我要求的。我需要适用于所有情况的解决方案,而不仅仅是示例情况。此外,“git checkout remote/branch_to_merge -- path/to/myfile.txt”如果您已经开始合并,则无法使用:它会提示您正在进行合并,并阻止您这样做。 - Bite code
1
@e-satis:这很令人惊讶。我认为这是一个错误,因为带路径的检出不是常规检出(并且它不影响HEAD)。我现在要尝试一下,因为我无法相信这个。 - sehe
1
@e-satis:所以...我是对的;git checkout remote/branch_to_merge -- path/to/myfile.txt在解决合并冲突时非常好用。(git 1.7.1) - sehe
1
现在添加了一个基于git mergetool的解决方案。 - sehe

-1

我一天前问了一个问题,与此问题非常相似,但我的问题略有不同,因为它涉及到数据库sqlite3。

但是站点上的管理员要求我删除该问题,所以我删除了它,但他最终封锁了我。

无论如何,对于我的问题,答案是"git checkout --their db.sqlite3"。

与数据库相关的事情,然后只需简单地输入"git checkout --their db.sqlite3",不需要放置路径。

我把这个答案留给那些和我有同样问题的人。


1
这与被接受的答案有何不同?考虑改进以使其更适合广泛的受众或将其删除。 - André Werlang
这个答案与被接受的答案没有什么不同,但是充满了错误,正如提问者所说,与他的问题有关的是“与数据库有关的事情”。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接