0

我当时做过git stash savegit pull git stash pop现在我有冲突,我想将一个文件重置为与从拉取相同的文件以从存储中删除更改(我在其他文件中有其他更改,我想保留)。

我试过了:

git checkout -f inst/app/server.R

但收到警告:

warning: path 'inst/app/server.R' is unmerged

并且文件没有改变,我里面仍然有冲突标记。如何从上次提交中签出该文件?

4

1 回答 1

2

TL;DR:听起来你想要git checkout --ours inst/app/server.R

您正处于冲突合并的中间,因此有两个“最后一次提交”。一个是您的 HEAD(当前)提交。请注意,您当前的提交是您在运行命令时所做的提交,除非您的命令是git rebase,在这种情况下,事情会被交换:请参阅git 中“我们的”和“他们的”的确切含义是什么? 既然您说最后一个命令(因合并冲突而失败的命令)是git stash apply1您当前的提交是您在为您git pull运行成功后所做的那个git merge2另一个提交是您当前git stash 存储中的几个提交之一-bag的名称stash@{0}(又名 just stash)。

(在任何冲突的合并中都涉及第三次提交,即合并基础。它可能与 stash 不太相关,这有点奇怪,但值得一提。请注意,如果您在 Git 配置中设置merge.conflictStylediff3获得带有额外冲突标记集的合并基础版本|||||||,在<<<<<<<>>>>>>>部分之间显示“我们的”和“他们的”版本。我喜欢保持diff3设置,因为它向我展示了我和他们之前的内容两者都以相互冲突的方式更改了文件。)

当您在git checkout没有命名特定提交或使用--oursor--theirs选项的情况下运行时,Git 会尝试从索引中获取版本。(请记住,索引(也称为暂存区,有时也称为缓存)是您构建下一次提交的地方。)但是冲突合并会在索引中留下每个冲突文件的三个版本。Git 不知道要获取哪一个,因此它因该错误而失败。使用--ourstellgit checkout将文件的“我们的”(即 HEAD)版本从索引复制到工作树;使用--theirs告诉git checkout复制文件的“其他”(即,MERGE_HEAD)版本。3

当您从索引中提取其中一个版本时,会将其他两个版本留在索引中,即,使文件处于未解析合并状态。 仔细检查内容以确保您拥有正确的版本,然后git add是解决冲突的文件。这将清除三个单独的索引版本,将工作树版本放入“已解析”索引槽(槽零)。

如果您需要重新创建合并冲突,您可以使用(只有在类似于选项时才需要,但这是一个好习惯)。这一直有效,直到您运行以完成失败的合并。git checkout -m -- path--pathgit commit

一旦一切都按照您想要的方式解决,请使用git commit完成合并。


1你说git stash pop, 但git stash pop只是一个快捷方式,意思是“运行git stash apply,然后,当且仅当成功时,运行git stash drop。” git stash drop由于应用步骤失败,一旦您对存储已干净应用并已提交感到满意,您将不得不手动运行。

2我建议避免git pull。它所做的只是为您运行另外两个 Git 命令:,git fetch然后根据您事先告诉 Git 的内容来执行。最好分别运行这两个命令,这样:git mergegit rebase

  • 当一个人失败时,你知道什么是失败的;和
  • 检查获取的内容后,您可以选择合并或变基git fetch

使用 根本没有错git pull,只要记住它真的是git fetch && git something,你必须提前决定“某事”部分。如果您不选择,Git 会选择git merge,这可能是错误的默认设置,但这是 Git 第一次做的事情,早在 2005 年,因此无法更改。:-)

3没有--base选项,但您可以使用gitrevisions语法从索引中访问它:. 您可以使用相同的语法来获取版本,即索引条目#2,以及版本,即#3,但无论如何它更容易记住。git checkout -- :1:path--ours--theirs--ours--theirs

“我们的”版本有时被称为本地版本,“他们的”版本有时被称为远程版本,但我讨厌这些名字。特别是“远程”太容易与远程origin和远程跟踪分支名称(如origin/master.

于 2017-03-08T11:53:21.017 回答