Git:无法撤销本地更改(错误:路径...未合并)

459
我有以下工作树状态。
$ git status foo/bar.txt
# On branch master
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add/rm <file>..." as appropriate to mark resolution)
#
#       deleted by us:      foo/bar.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

文件foo/bar.txt已经存在,我想将其恢复到“未更改状态”(类似于'svn revert'):

$ git checkout HEAD foo/bar.txt
error: path 'foo/bar.txt' is unmerged
$ git reset HEAD foo/bar.txt
Unstaged changes after reset:
M       foo/bar.txt

现在情况变得令人困惑:

$ git status foo/bar.txt
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   foo/bar.txt
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   foo/bar.txt
#

同一个文件在两个部分中,一个是新文件,另一个是修改后的文件?我该怎么办?


10
我希望有人能够解释我们是如何陷入这种局面的,为什么会发生这种情况,以及为什么解决方案有效。 - Marcos Dione
5
在rebase之后我执行了stash pop,结果遇到了合并冲突(stash pop会进行一次合并)导致陷入了这种困境...为了解决冲突,我执行了"checkout --theirs"命令...但是很明显我的更改还在那里...为了删除这些更改,我再次对文件执行了checkout,但就在这时我看到了上面的错误提示。 - Arindam Roychowdhury
在切换到主分支、进行 git pull 和执行 git stash pop 后,我陷入了这种情况。 - Zhou Haibo
8个回答

743

你的操作顺序不正确。你应该先重置以取消暂存文件,然后再检出以还原本地更改。

尝试这样做:

$ git reset foo/bar.txt
$ git checkout foo/bar.txt

1
谢谢,运行得非常好!我必须提交(_不是_使用-a参数,相关更改已经暂存),然后我就能像平常一样推送/拉取了。 - Patrick
21
对我来说,需要执行以下操作:<br/> $ git reset -- foo/bar.txt <br/> $ git checkout -- foo/bar.txt <br/> (注意两者之间有额外的"--") - Jan
4
好的语法是“git reset HEAD 文件1 文件2 ...”,然后是“git checkout -- 文件1 文件2...”。 - Thomas Decaux
3
当最高得票的答案基本上只是说“你做错了”的时候,总是很有趣 :) - nathanchere
7
解释(关于事物的作用)将是很好的...... - Kissaki
显示剩余2条评论

82

我对此完全满意:

$ git reset -- foo/bar.txt
$ git checkout foo/bar.txt

17
git checkout origin/[branch] .
git status

// 请注意句末的点号(.),这样就没问题了。


8
如果上述答案不起作用,请尝试:
git reset --merge

7
在最近的git版本中,git restore 被认为是比过载的 checkout 更好的恢复本地错误更改的方式。这听起来很合理 - 一个简单而又专用的工具来处理常见操作。
但是,下面是我新“喜欢”的 git bug。是的,我知道有些 Git-head 会说:“这不是bug,这是设计如此”。但是有了这种用户界面,我仍然坚持使用“bug”这个名词:
% git restore LEGAL
error: path 'LEGAL' is unmerged
# okay, fine...
% git restore --ignore-unmerged LEGAL
warning: path 'LEGAL' is unmerged
# Arg, what?!

(由git 2.25.1提供)
首先是一个小问题:当一个工具因为特定条件而拒绝执行某些操作时,它不仅仅是一个警告。至少应该表明操作未执行。现在我必须去调查操作是否实际上被执行了(提示:没有)。
第二个问题,当然很明显。现在,让我们查看man页条目,看看为什么这个奇妙的工具不会执行我告诉它要做的事情:
   --ignore-unmerged
       When restoring files on the working tree from the index, do not
       abort the operation if there are unmerged entries and neither
       --ours, --theirs, --merge or --conflict is specified. Unmerged
       paths on the working tree are left alone.

哇塞!我猜这里关于用户界面问题的Git风格修复将是将选项从--ignore-unmerged重命名为--ignore-unmerged-except-in-cases-where-we-do-not-want-to-allow-that--consult-documentation-then-source-code-then-team-of-gurus-when-you-cannot-figure-it-out---and-wait-while-half-of-them-argue-about-why-it-is-right-as-is-while-the-other-half-advocate-adding-four-more-options-as-the-fix

然后去社区找寻解决方案。挑战你的勇气吧。

很明显,我的引用状态不允许树形blob通过工作文件到暂存区...咳咳索引?


这是使用 git restore 修复它的方法(尽管我同意你的观点,它并不直观):https://dev59.com/I3A75IYBdhLWcg3w899J#73707347 - wisbucky
@wisbucky... 谢谢。如果我再次遇到这个问题,我会尝试这个方法。我的解决办法是将存储库转换为mercurial并使用它。摩擦力小得多。 - Juan
1
我在一个 cherry-pick 操作中遇到了这个问题,@wisbucky 的解决方案不能解决我的问题。使用 --ours 可以实现我想要的效果,即丢弃传入的 cherry pick 文件。@Juan 你说的那些警告信息需要表明它们没有做什么,而不仅仅是为什么没有做。另外,更多地解释需要通过使用 --ours 等方法来解决冲突产生的歧义,将会对这个错误信息非常有帮助。 - Ryan Hiebert

1

修复未合并路径错误的“现代”方法,可能会在弹出存储库时发生,使用restore命令(自Git v2.23,2019年8月):

# unstage the file
git restore --staged myfile

# restore the file (lose your working dir changes)
git restore myfile

-3
git checkout foo/bar.txt

你试过那个吗?(不带 HEAD 关键字)

我通常会用这种方式撤销我的更改。


1
在合并过程中尝试checkout时的典型错误: $ git co path/to/file =结果=> error: path 'path/to/file' is unmerged => 因此,首先运行:$ git reset path/to/file,然后git checkout path/to/file应该可以正常工作。 - michael
2
不指定HEAD会使git checkout从索引中检出,这是一种较弱的操作(内容源是索引而不是HEAD)。此外,在这种情况下,我认为这没有任何区别-与问题所陈述的具体问题无关。你试过吗? - Kissaki

-4

我发现git stash非常有用,可以暂时处理所有“脏”状态。


4
如果您觉得这很有用,请解释一下它将如何帮助解决这个具体的案例。在这里,您会如何使用它? - Kissaki

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