我有一些本地文件,我从远程分支提取,有冲突。我知道我希望保留本地更改,而忽略导致冲突的远程更改。是否有一个命令我可以用来有效地说“标记所有冲突已解决,使用本地”?


当前回答

确定冲突的来源:如果是git合并的结果,请参阅Brian Campbell的回答。

但如果是git重基的结果,为了放弃远程(他们的)更改并使用本地更改,你必须执行以下操作:

git checkout --theirs -- .

参见“为什么“我们的”和“他们的”的含义颠倒了”,以了解在重基过程中我们的和他们的是如何交换的(因为上游分支被签出)。

其他回答

确定冲突的来源:如果是git合并的结果,请参阅Brian Campbell的回答。

但如果是git重基的结果,为了放弃远程(他们的)更改并使用本地更改,你必须执行以下操作:

git checkout --theirs -- .

参见“为什么“我们的”和“他们的”的含义颠倒了”,以了解在重基过程中我们的和他们的是如何交换的(因为上游分支被签出)。

Git签出有—ours选项来签出您在本地拥有的文件版本(而不是—their,这是您拉入的版本)。你可以通过。让它签出树中的所有东西。然后你需要将冲突标记为已解决,这可以用git add完成,并在完成后提交你的工作:

git checkout --ours .  # checkout our local version of all files
git add -u             # mark all conflicted files as merged
git commit             # commit the merge

Note the . in the git checkout command. That's very important, and easy to miss. git checkout has two modes; one in which it switches branches, and one in which it checks files out of the index into the working copy (sometimes pulling them into the index from another revision first). The way it distinguishes is by whether you've passed a filename in; if you haven't passed in a filename, it tries switching branches (though if you don't pass in a branch either, it will just try checking out the current branch again), but it refuses to do so if there are modified files that that would effect. So, if you want a behavior that will overwrite existing files, you need to pass in . or a filename in order to get the second behavior from git checkout.

这也是一个好习惯,当传递文件名时,用——来抵消它,比如git checkout——ours——<filename>。如果您不这样做,而文件名恰好与分支或标记的名称匹配,Git将认为您想要签出该修订,而不是签出该文件名,因此使用checkout命令的第一种形式。

我将详述一下Git中冲突和合并的工作原理。当你合并别人的代码时(这也发生在拉取过程中;pull本质上是一个fetch,然后是merge),有几种可能的情况。

最简单的就是你在复习。在这种情况下,你“已经是最新的”,什么也没有发生。

另一种可能是,他们的修订只是你的后代,在这种情况下,你将默认有一个“快进合并”,在这种情况下,你的HEAD只是更新到他们的提交,没有合并发生(如果你真的想记录一个合并,可以禁用——no-ff)。

Then you get into the situations in which you actually need to merge two revisions. In this case, there are two possible outcomes. One is that the merge happens cleanly; all of the changes are in different files, or are in the same files but far enough apart that both sets of changes can be applied without problems. By default, when a clean merge happens, it is automatically committed, though you can disable this with --no-commit if you need to edit it beforehand (for instance, if you rename function foo to bar, and someone else adds new code that calls foo, it will merge cleanly, but produce a broken tree, so you may want to clean that up as part of the merge commit in order to avoid having any broken commits).

The final possibility is that there's a real merge, and there are conflicts. In this case, Git will do as much of the merge as it can, and produce files with conflict markers (<<<<<<<, =======, and >>>>>>>) in your working copy. In the index (also known as the "staging area"; the place where files are stored by git add before committing them), you will have 3 versions of each file with conflicts; there is the original version of the file from the ancestor of the two branches you are merging, the version from HEAD (your side of the merge), and the version from the remote branch.

为了解决冲突,您可以编辑工作副本中的文件,删除冲突标记并修复代码以使其正常工作。或者,您可以从合并的一方或另一方签出版本,使用git签出-我们的或git签出-他们的。一旦你把文件放到你想要的状态,你就表明你已经完成了文件的合并,可以使用git add提交了,然后你就可以使用git commit提交合并了。