我做了一个 git stash pop
并以合并冲突告终。我从文件系统中删除了文件并执行了 git checkout
,如下所示,但它认为文件仍未合并。然后我尝试替换文件并再次执行 git checkout
并得到相同的结果。我尝试使用 -f
标志强制它。任何帮助,将不胜感激!
chirag-patels-macbook-pro:haloror patelc75$ git status
app/views/layouts/_choose_patient.html.erb: needs merge
app/views/layouts/_links.html.erb: needs merge
# On branch prod-temp
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: db/schema.rb
#
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# unmerged: app/views/layouts/_choose_patient.html.erb
# unmerged: app/views/layouts/_links.html.erb
chirag-patels-macbook-pro:haloror patelc75$ git checkout app/views/layouts/_choose_patient.html.erb
error: path 'app/views/layouts/_choose_patient.html.erb' is unmerged
chirag-patels-macbook-pro:haloror patelc75$ git checkout -f app/views/layouts/_choose_patient.html.erb
warning: path 'app/views/layouts/_choose_patient.html.erb' is unmerged
git stash apply/pop
的状态应该更容易,因为工作树现在需要清理:请参阅 my answer below
请参阅 man git merge(如何解决冲突):
看到冲突后,您可以做两件事: 决定不合并。您需要的唯一清理是将索引文件重置为 HEAD 提交以反转 2. 并清理 2. 和 3. 所做的工作树更改; git-reset --hard 可用于此。解决冲突。 Git 将标记工作树中的冲突。将文件编辑成形状并将它们添加到索引中。使用 git commit 来达成交易。
在 TRUE MERGE 下(查看 2. 和 3. 指的是什么):
当如何协调更改不明显时,会发生以下情况: HEAD 指针保持不变。 MERGE_HEAD ref 设置为指向另一个分支头。干净合并的路径在索引文件和工作树中都会更新。 ...
所以:如果您想从工作树中删除存储更改,请使用 git reset --hard
,或者如果您只想清理索引并将工作树中的冲突留给手动合并,请使用 git reset
。
在 man git stash(OPTIONS,pop)下,您还可以阅读:
应用状态可能会因冲突而失败;在这种情况下,它不会从存储列表中删除。您需要手动解决冲突,然后手动调用 git stash drop。
我也有类似的事情发生在我身上。我还不想暂存这些文件,所以我用 git add
添加了它们,然后只做了 git reset
。这基本上只是添加然后取消了我的更改,但清除了未合并的路径。
reset --hard
更好,因为它不会覆盖您的文件(有合并问题的文件除外)。谢谢!
add
不是将工作树中的内容暂存到索引吗?我想我不明白为什么您的答案从描述中起作用。
git add
确实将它们暂存,但 git reset
(我之后立即执行)将它们取消暂存。本质上,它清除了未合并的路径,并通过伪装 git 将我返回到我的正常工作树。
git reset
,则不需要 git add
。 git reset
有效地“撤消”了 git add
。 git reset
(--mixed
<- 默认值)实际上不会触及工作目录,因此您的工作目录中的内容、合并冲突和所有内容都不会受到影响。索引(以及技术上的分支头)虽然被重置(没有 ref,它们被重置回 HEAD
,这可能意味着分支头没有更改,并且有效地撤消对索引所做的任何 git add
,以及清除未合并的路径状态)。
git reset
和 git stash drop
运行良好。它做了 git stash pop
在没有冲突的情况下会做的事情。似乎不需要 git add
;尽管它可能有用,但您有许多有冲突的文件。由于每个都已解决,因此可以添加它们并且 git status
会跟踪它们。
如果像我一样,您通常想要用隐藏文件的内容覆盖工作目录的内容,但您仍然会遇到冲突,那么您想要的是使用根目录中的 git checkout --theirs -- .
解决冲突。
之后,您可以 git reset
将索引中的所有更改带到工作目录,因为显然在发生冲突的情况下,对非冲突文件的更改会保留在索引中。
您可能还想在之后运行 git stash drop [<stash name>]
以摆脱存储,因为 git stash pop
不会在发生冲突时将其删除。
请注意,未来的 Git 2.5(2015 年第二季度)可能会尝试使这种情况变得不可能。
请参阅 Jeff King (peff
) 的 commit ed178ef,2015 年 4 月 22 日。
(由 Junio C Hamano -- gitster
-- 在 commit 05c3967 中合并,2015 年 5 月 19 日)
注意:这已被还原。见下文。
stash:需要一个干净的索引来应用/弹出
问题
如果您在索引中暂存内容并运行“stash apply/pop”,我们可能会遇到冲突并将新条目放入索引中。那时很难恢复到原始状态,因为像“git reset --keep”这样的工具会吹走任何上演的东西。
换句话说:
“git stash pop/apply”忘记确保不仅工作树是干净的,而且索引也是干净的。后者很重要,因为存储应用程序可能会发生冲突,并且索引将用于解决冲突。
解决方案
我们可以通过在有阶段性更改时拒绝应用来使这更安全。这意味着如果之前因为对修改的文件(添加但未提交)应用存储而进行了合并,现在它们将不会是任何合并,因为存储应用/弹出将立即停止:
Cannot apply stash: Your index contains uncommitted changes.
强制您提交更改意味着,在合并的情况下,您可以使用 git reset --hard 轻松恢复初始状态(在 git stash apply/pop 之前)。
请参阅 Jeff King (peff
) 的 commit 1937610(2015 年 6 月 15 日)和 commit ed178ef(2015 年 4 月 22 日)。
(由 Junio C Hamano -- gitster
-- 在 commit bfb539b 中合并,2015 年 6 月 24 日)
该提交是为了提高应用存储的安全性,因为应用程序进程可能会创建冲突的索引条目,之后很难恢复原始索引状态。不幸的是,这损害了围绕“git stash -k”的一些常见工作流程,例如:
git add -p ;# (1) stage set of proposed changes
git stash -k ;# (2) get rid of everything else
make test ;# (3) make sure proposal is reasonable
git stash apply ;# (4) restore original working tree
如果您在步骤 (3) 和 (4) 之间“git commit”,那么这很有效。但是,如果这些步骤是预提交挂钩的一部分,那么您就没有这个机会(无论测试通过还是失败,您都必须恢复原始状态)。
git restore --staged name-of-file-that-has--merge-conflict