Git合并后在我的文件中留下了HEAD标记

129

我尝试使用Git在命令行中合并文件,但是出现了一个错误提示,告诉我合并被中止了。

我以为这就结束了,但后来我意识到我的文件中有git标记,像这样:

start =
    expression

validchar = 
    [0-9a-zA-Z_?!+\-=@#$%^&*/.]

integer = 
<<<<<<< HEAD
    digits:[0-9]+
        { return digits.join(""); }
=======
    sign:"-"* digits:[0-9]+
        { return sign + digits.join(""); }
>>>>>>> gh-pages

这些文件不是我编辑的,它们显示出以下内容:

  • 小于号后面的 HEAD 标记 (<<<<<<< HEAD)
  • 更改代码的行
  • 一串等号 (=======)
  • 新版本的代码
  • 以大于号开始的另一行,并带有分支名称 (>>>>>>> gh-pages)

更糟糕的是,文件内容不再按顺序排列。 有人知道如何将这些文件恢复正常,并将我对 gh-branch 所做的更改合并到 master 分支吗?


1
如果您并不真正想合并任何内容(或认为这是不必要的),但现在已经到了这里,并且对“手动编辑这些部分”在数十个文件中的建议感到非常困惑,那么 git merge --abort 命令可以将本地文件夹恢复到其先前的状态。git status 命令会向您提供相关提示。如果您确实想编辑它们,那么下面的答案中提到的 git mergetool 命令可能已经足够好用了。 - Fons MA
6个回答

121

这些是冲突标记。你仍在合并过程中,但有一些部分Git无法自动合并。你需要手动编辑这些部分,使它们变成你想要的样子,然后提交结果。


例如,在您的特定情况下,您可能希望像这样解决它(注意-右侧箭头/文本只是我的注释,不是您要输入文件中的内容):

integer = 
<<<<<<< HEAD                                  <-+ remove the bits here
    digits:[0-9]+                               |
        { return digits.join(""); }             |
=======                                       <-+
    sign:"-"* digits:[0-9]+
        { return sign + digits.join(""); }
>>>>>>> gh-pages                              <-- and this

因此,您需要将文件保存为...
integer = 
    sign:"-"* digits:[0-9]+
        { return sign + digits.join(""); }

6
你希望最终合并结果看起来是怎样的?我猜你只想要gh-pages版本中的一部分,所以你只需要删除<<<<<<======之间的内容,并删除单独的>>>>>>行,留下=======>>>>>>之间的两行实际代码。 - Amber
1
没错,这是正确的。(没有真正的“其余部分”需要处理 - 您只需提交合并的结果,如果没有冲突,Git通常会自动执行此操作。) - Amber
2
@lowerkey,请考虑阅读有关此主题的书籍。我建议您完整地阅读该书,因为您似乎缺乏有关版本控制系统如何工作的某些基本知识,并且最好为将来可能出现的问题做好准备。 - kostix
http://matthew-brett.github.io/pydagogue/foundation.html 是一个不错的起点,比一本书更加轻量化。 - niefpaarschoenen
1
这太有趣了。你指出一个问题的答案被标记为重复,尽管这个问题的答案可以在其他问题中找到。 - t3chb0t
显示剩余6条评论

27

首先使用 'git status' 命令查看当前状态,看看有哪些文件被修改了。如果你中止了一个合并操作(或者合并操作被中止了),并且在工作目录中有冲突的文件,那么说明出了问题。Git 状态会告诉你现在所处的位置。之后,你有几个选项。你可以手动解决合并提交,这可能会很具有挑战性,或者使用工具:

git mergetool

如果您的文件被列为需要合并,则合并工具将起作用。

您还可以执行以下操作之一:

git checkout --ours -- /path/to/conflicted-file       # this is probably the one you want
git checkout --theirs -- /path/to/conflicted-file

您可以使用:1:文件名语法查看不同的版本。有关说明,请参见此处。但是,上述所有内容都假定'git status'显示需要合并的文件。

最后,您始终可以选择:

git reset --hard   # sounds like --hard is what you need but check other options

9
我完全赞同 "从git status开始查看你所拥有的" 的建议:在某些圈子里,将Git归咎于其想象中的复杂性已经成为一种时尚,但是实际上仔细阅读git status的输出就足以理解在大多数常见情况下下一步该做什么。因此,确实:如果有什么问题,请停下来,阅读git status,思考。 - kostix

6
所有的答案都是正确的,但如果你想自动删除所有的冲突标记,并希望自动更改文件以保留HEAD,则可以创建自己的bash脚本,例如:

示例脚本:

# vim /usr/sbin/solve.git

(追加以下内容)

#!/bin/bash
for f in $(grep -Rl '^>>>>>>> ' --include="*.php" --include="*.css" --include="*.js" --include="*.html" --include="*.svg" --include="*.txt" .)
do
sed -i -e '/^=======/,/^>>>>>>> /d' -e '/^<<<<<<< /d' $f
sed -i -e '/^>>>>>>> /d' $f
echo "$f Fixed"
done
git add . ; git commit -am "[+] Resolved on `date` from `hostname` by `whoami`" --no-verify

# chmod 755 /usr/sbin/solve.git

只需在您的GIT存储库/路径中运行该命令来解决问题:

$ cd <path_to_repo>
$ solve.git

注意:上述文件扩展名为php、css、js、html、svg和txt。


呃,不要再用那种差劲的工具了。花点钱买一个能够智能处理合并冲突的正规 diff 工具吧。 - C.J.

0

我来自这个问题。我想要一些自动化的方法来合并半合并的文件,而不是手动编辑文件(如其他答案所建议的,但我并不真正舒服)。所以这就是我最终通过netbeans完成的,但也可以通过命令行完成。

现在,请记住,只有在merge->add->commit之后立即意识到你搞砸了,并且想重新进行该过程时,此方法才有效。

步骤1:重置到先前的提交。

git reset --hard a992a93f9312c6fa07c3a1b471c85e9fbf767d0e

步骤2:重新尝试合并分支

git merge --ff origin/feature/YOUR-Branch_here

如果您正在使用GUI,则此时将提示您进行合并窗口,然后您可以像平常一样继续操作。


0

如果您想考虑新的更改(来自要合并的分支),则删除所有属于HEAD的代码。如果您想保留自己的代码而不是新分支的代码,则删除其他代码并保留HEAD的代码。


0
在Atom中,我遇到了一些文件无法将已解决的合并冲突保存到驱动器的问题,所以我不得不手动点击“保存”按钮。这花费了我相当长的时间才找出原因。

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