为什么git会提示“无法拉取,因为存在未合并的文件”?

316

当我尝试在终端中拉取我的项目目录时,我看到以下错误:

harsukh@harsukh-desktop:~/Sites/branch1$ git pull origin master
U app/config/app.php
U app/config/database.php
U app/routes.php
Pull is not possible because you have unmerged files.
Please, fix them up in the work tree, and then use 'git add/rm <file>'
as appropriate to mark resolution, or use 'git commit -a'.

为什么git会显示"Pull is not possible because you have unmerged files",我该如何解决?


3
在我的情况下,我只是使用了这些命令:"git add .",然后是"git commit -m "Test",最后是"git push"。错误已被删除。 - Akhzar Nazir
1
你只需要添加 "$ git add <file>" ... 来更新将要提交的内容或还原(丢弃工作目录中的更改),然后提交 "$ git commit",最后使用 "$ git push" 完成合并。 - find_x
如果有帮助的话:我注意到仅使用“git add .”再提交不起作用。我必须通过名称添加单个文件,然后提交和拉取/推送。 - ouonomos
12个回答

299

目前发生的情况是,您有一组文件,您曾尝试合并它们,但它们产生了合并冲突。

理想情况下,如果出现合并冲突,应该手动解决它们,并使用 git add file.name && git commit -m "removed merge conflicts" 提交更改。

现在,另一个用户已经更新了相关的文件,并将其更改推送到共同的上游仓库。

很遗憾,您的合并冲突(可能是最后一次提交)未被解决,因此您的文件没有正确合并,并且对应的标记为 Uunmerged)。

因此,当您执行 git pull 时,Git 会抛出错误,因为您有某个版本的文件未正确解决。

要解决此问题,您需要解决相关的合并冲突,并添加和提交更改,然后才能执行 git pull

问题的示例复制和解决:

# Note: commands below in format `CUURENT_WORKING_DIRECTORY $ command params`
Desktop $ cd test

首先,让我们创建仓库结构。

test $ mkdir repo && cd repo && git init && touch file && git add file && git commit -m "msg"
repo $ cd .. && git clone repo repo_clone && cd repo_clone
repo_clone $ echo "text2" >> file && git add file && git commit -m "msg" && cd ../repo
repo $ echo "text1" >> file && git add file && git commit -m "msg" && cd ../repo_clone

现在我们在repo_clone目录中,如果你执行git pull命令,它会引发冲突。

repo_clone $ git pull origin master
remote: Counting objects: 5, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/anshulgoyal/Desktop/test/test/repo
 * branch            master     -> FETCH_HEAD
   24d5b2e..1a1aa70  master     -> origin/master
Auto-merging file
CONFLICT (content): Merge conflict in file
Automatic merge failed; fix conflicts and then commit the result.
如果我们忽略克隆中的冲突,并在原始存储库中进行更多的提交现在,
repo_clone $ cd ../repo
repo $ echo "text1" >> file && git add file && git commit -m "msg" && cd ../repo_clone

然后我们执行 git pull 命令,就能获取到

repo_clone $ git pull
U   file
Pull is not possible because you have unmerged files.
Please, fix them up in the work tree, and then use 'git add/rm <file>'
as appropriate to mark resolution, or use 'git commit -a'.

请注意,file现在处于未合并状态,如果我们运行 git status 命令,我们可以清楚地看到同样的结果:

repo_clone $ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 1 different commit each, respectively.
  (use "git pull" to merge the remote branch into yours)

You have unmerged paths.
  (fix conflicts and run "git commit")

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both modified:      file

因此,要解决这个问题,我们首先需要解决之前忽略的合并冲突。

repo_clone $ vi file

并将其内容设置为

text2
text1
text1

然后将其添加并提交更改。

repo_clone $ git add file && git commit -m "resolved merge conflicts"
[master 39c3ba1] resolved merge conflicts

2
为了完整起见,我建议添加 @Pawan 的回答,使用 'git mergetool' 解决冲突。倒数第二步可能不太实用(“通过将其内容设置为:[某些文本]”来解决合并问题)。 - undeniablyrob
或者,你可以采用@user261的建议进行合并。无论哪种方式,我认为在实际操作中添加一个关于如何合并的步骤会使这个答案更完整。 - undeniablyrob
4
当你需要修复单个文件中简单冲突(例如,一两行不同的代码)时,这个答案非常有效。如果有多个文件被大量修改,则这可能是一个困难的修复过程。但它强调了使用Git时应该经常提交以避免困难冲突的想法。 - Vaughn D. Taylor
如果我想回到冲突之前的仓库阶段怎么办? - sandeepnegi

107

如果您不想合并更改,仍然希望更新本地,请运行:

git reset --hard HEAD  

这将使用git reset命令将本地代码重置到HEAD状态,并使用git pull命令拉取远程代码。

如果您已经在本地提交了合并(但尚未推送到远程),并且想要撤销该提交:

git reset --hard HEAD~1 

68
您正在尝试在本地分支中添加新提交,而您的工作目录不干净。因此,Git拒绝进行拉取操作。请参考以下图表以更好地可视化该场景:
远程:A<-B<-C<-D 本地:A<-B* (*表示您已修改但未提交的多个文件)
处理此情况有两种选择。您可以舍弃文件中的更改,也可以保留它们。
选项一:丢弃更改 您可以使用“git checkout”命令对每个未合并的文件进行操作,或者使用“git reset --hard HEAD”命令将分支中的所有文件重置为HEAD状态。此时,本地分支中的HEAD为B,没有星号。如果选择此选项,则图表变为:
远程:A<-B<-C<-D 本地:A<-B
现在,当您执行拉取操作时,可以使用从主干获取的更改快进您的分支。拉取后,您的分支将看起来与主干相同:
本地:A<-B<-C<-D
选项二:保留更改 如果要保留更改,请首先解决每个文件中的任何合并冲突。您可以在IDE中打开每个文件,查找以下符号: <<<<<<< HEAD //您代码的版本 ======= //远程代码的版本 >>>>>>>>
然后进行相应的修改。

Git向您展示了两个代码版本。在HEAD标记中包含的代码是来自当前本地分支的版本。另一个版本是来自远程的版本。选择代码版本(并将另一个代码与标记一起删除)后,您可以通过键入git add 将每个文件添加到暂存区。最后一步是使用适当的消息键入git commit -m提交结果。此时,我们的图表如下所示:

远程: A <- B <- C <- D
本地: A <- B <- C'

这里我将刚刚提交的修改标记为C'因为它不同于远程的提交C。现在,如果您尝试进行pull拉取,则会收到非快速转发错误提示。Git无法在您的分支上播放远程的更改,因为您的分支和远程都已经从共同的祖先提交B分叉开。此时,如果您想要拉取,则可以执行另外一个git merge,或者git rebase您的分支。

精通Git需要能够理解和操作单向链表。我希望这个解释能让您正确地思考使用Git。


40

有一个简单的解决方案。但是为了达到这个目的,您首先需要学习以下内容

vimdiff

为了消除冲突,您可以使用

git mergetool

上述命令基本上会打开本地文件、混合文件和远程文件(共三个文件),对于每个冲突的文件。本地文件和远程文件仅供参考,您可以使用它们选择在混合文件中包含或排除什么。 然后保存并退出文件即可。


3
我会说vimdiff 不是必需的(你可以使用任何你选择的合并/比较工具,如WinMerge或OSX内置的FileMerge等)。话虽如此,这是对@mu回答的很好补充。 - undeniablyrob

8

如果您想将远程分支拉到本地运行(例如进行审查或测试),并且当您执行$ git pull命令时出现本地合并冲突:

$ git checkout REMOTE-BRANCH
$ git pull  (you get local merge conflicts)
$ git reset --hard HEAD (discards local conflicts, and resets to remote branch HEAD)
$ git pull (now get remote branch updates without local conflicts)

6
如果你不想保留本地分支的任何更改,我认为这是最佳方法。
git clean -df
git reset --hard
git checkout REMOTE_BRANCH_NAME
git pull origin REMOTE_BRANCH_NAME

这个命令的意思是:(开发|REBASE 1/1) - Shashank Bodkhe

5

在进行拉取操作之前,您需要合并本地的一些文件。您可以将这些文件检出,然后执行拉取操作覆盖本地的文件。

git checkout app/config/app.php app/config/database.php app/routes.php
git pull origin master

合并将两个文件的内容合并在一起。目前,您本地的文件与远程服务器上的文件不同。必须在远程服务器上进行合并。因此,如果您暂存了编辑过的文件并将它们推送,您的更改将被添加到存储库中的文件中。然后,您的文件将同步,并且您可以拉取其他更改的整个项目。当我开始使用git时,我发现git帮助书非常有用。您可以在此处找到它:http://git-scm.com/book/en/Getting-Started - Nick
请注意,我不是原帖作者。"合并文件"是不正确的术语。严格来说,您合并提交,而不是文件。 - jub0bs
啊,是的,那是真的。抱歉,我尝试给出一个简单的答案。 - Nick
如果在合并提交时出现冲突,那么是的,您将会有冲突和未合并的文件,需要进行合并。 - Edward Thomson

5

遵循的步骤:

step-1 : git reset --hard HEAD  (if you want to reset it to head)
step-2 : git checkout Master 
step-3 : git branch -D <branch Name>
(Remote Branch name where you want to get pull) 
step-4 : git checkout <branch name>
step-5 : git pull. (now you will not get any
error)

谢谢,Sarbasish


5

我也遇到了同样的问题。
在我的情况下,解决步骤如下-

  1. 删除所有以U(未合并)符号开头的文件,例如-

U   project/app/pages/file1/file.ts
U   project/www/assets/file1/file-name.html

从主分支上拉取代码。
$ git pull origin master
  1. 检查状态

 $ git status

以下是出现的消息:
分别有两个和一个不同的提交。
(使用"git pull"命令将远程分支合并到自己的分支中)
您有未合并的路径。
(解决冲突并运行"git commit")

未合并的路径:
(使用"git add ..."标记解决方案)

both modified:   project/app/pages/file1/file.ts
both modified:   project/www/assets/file1/file-name.html
  1. 添加了所有新的更改 -

    $ git add project/app/pages/file1/file.ts
project/www/assets/file1/file-name.html
  1. 提交对头的更改-

$ git commit -am "resolved conflict of the app."
  1. 代码上传 -

$ git push origin master

这张图片可以解决哪个转折点的问题 - 在这里输入图片描述


4
当合并冲突发生时,您可以打开单个文件。您将获得"<<<<<<< or >>>>>>>"符号。这些符号表示您的更改和远程存在的更改。您可以手动编辑所需的部分。然后保存文件,再运行以下命令:git add。合并冲突将被解决。

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