从存储冲突后强制签出文件

Force checkout of the file after conflict from stash

我做了 git stash save 然后 git pull git stash pop 现在我有冲突,我想重置一个文件与从 pull 中删除相同的文件以从存储中删除更改(我有我想保留的其他文件中的其他更改)。

我试过:

git checkout -f inst/app/server.R

但收到警告:

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

而且文件没变,我里面还是有冲突标记。我如何从上次提交中检出该文件?

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

您正处于冲突合并中,因此有 两个 "last commit"。一个是您的 HEAD(当前)提交。请注意,您当前的提交是您在 运行 您的命令时所在的提交,除非您的命令是 git rebase,在这种情况下,事情会交换:请参阅名称 [=] 下的 What is the precise meaning of "ours" and "theirs" in git? Since you say the last command, the one that failed with a merge conflict, was git stash apply,1 your current commit is the one you made after your git pull ran a successful git merge for you,2 and the other commit is one of the several commits in your current git stash stash-bag 16=](也就是 stash)。

(任何有冲突的合并都涉及第三次提交,即 合并基础。它可能与存储不太相关,这有点奇怪,但值得提到。请注意,如果您在 Git 配置中将 merge.conflictStyle 设置为 diff3,您将获得带有一组额外冲突标记的合并基础版本,|||||||,介于<<<<<<<>>>>>>> 部分向您展示了 "ours" 和 "theirs" 版本。我喜欢保持 diff3 设置,因为它向我展示了在我-并且-他们都以相互冲突的方式更改了文件。)

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

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

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

按照您的方式解决所有问题后,使用 git commit 完成合并。


1你说的是git stash pop,但是git stash pop只是一个快捷方式,意思是"Run git stash apply and then, if and only if that succeeds, run git stash drop."由于应用步骤失败,你将不得不运行 git stash drop 手动,一旦您对存储已干净地应用并已提交感到满意。

2我建议避免 git pull。它所做的只是 运行 为您提供另外两个 Git 命令:git fetch,然后是 git mergegit rebase,具体取决于您告诉 Git进步。两个命令最好分开运行,这样:

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

使用git pull从根本上没有错,只是记住它真的是git fetch && git something,你必须提前决定"something"部分。如果您不选择一个,Git 将选择 git merge,这可能是错误的默认设置,但这是 Git 最早在 2005 年所做的设置,因此无法更改。 :-)

3没有--base选项,但是可以使用gitrevisions syntax从索引中访问:git结帐--:1:<em>路径</em>。您可以使用相同的语法来获取 --ours 版本(索引条目 #2)和 --theirs 版本(索引条目 #3),但更容易记住 --ours--theirs 无论如何。

"ours"版本有时称为本地版本,"theirs"版本有时称为远程[=108] =] 版本,但我讨厌这些名字。 "Remote" 尤其容易与 origin 等遥控器和 origin/master.

等远程跟踪 b运行ch 名称混淆