ChatGPT解决这个技术问题 Extra ChatGPT

git stash 错误:git stash pop 并以合并冲突告终

我做了一个 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 2.5(2015 年第二季度)恢复 之前 git stash apply/pop 的状态应该更容易,因为工作树现在需要清理:请参阅 my answer below

C
Community

请参阅 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 stashOPTIONS,pop)下,您还可以阅读:

应用状态可能会因冲突而失败;在这种情况下,它不会从存储列表中删除。您需要手动解决冲突,然后手动调用 git stash drop。


事实上,即使你删除了一个存储,仍然有可能(尽管更困难)再次检索它,因为变更集仍然存在于存储库中。 stackoverflow.com/search?q=git+recover+dropped+stash
@nalply:那是好是坏?欢迎您改进我的答案,您首先不理解它......
我认为源代码修订是一个复杂的问题域。很容易混淆。我仍然认为您的回答很好,因为它再次证实了我的方法。
意识到存储并没有像我想象的那样被删除,这不仅对我有很大帮助,而且这也解释了为什么即使我确定我没有忘记从中取回东西,我的存储仍然不断增长。
“应用状态可能会因冲突而失败;在这种情况下,它不会从存储列表中删除。”在我看来,这是帖子中最重要的部分。考虑编辑您的答案,将其与“不要恐慌”(DON'T PANIC)用大而友好的字母放在前面。 (虽然已经+1了。)谢谢。
A
Aaron

我也有类似的事情发生在我身上。我还不想暂存这些文件,所以我用 git add 添加了它们,然后只做了 git reset。这基本上只是添加然后取消了我的更改,但清除了未合并的路径。


这似乎比使用 reset --hard 更好,因为它不会覆盖您的文件(有合并问题的文件除外)。谢谢!
我还不想暂存文件,所以我添加了它们 -- add 不是将工作树中的内容暂存到索引吗?我想我不明白为什么您的答案从描述中起作用。
git add 确实将它们暂存,但 git reset(我之后立即执行)将它们取消暂存。本质上,它清除了未合并的路径,并通过伪装 git 将我返回到我的正常工作树。
如果您要去 git reset,则不需要 git addgit reset 有效地“撤消”了 git addgit reset--mixed <- 默认值)实际上不会触及工作目录,因此您的工作目录中的内容、合并冲突和所有内容都不会受到影响。索引(以及技术上的分支头)虽然被重置(没有 ref,它们被重置回 HEAD,这可能意味着分支头没有更改,并且有效地撤消对索引所做的任何 git add,以及清除未合并的路径状态)。
sequenceedit/resolvegit resetgit stash drop 运行良好。它做了 git stash pop 在没有冲突的情况下会做的事情。似乎不需要 git add;尽管它可能有用,但您有许多有冲突的文件。由于每个都已解决,因此可以添加它们并且 git status 会跟踪它们。
P
Pedro Gimeno

如果像我一样,您通常想要用隐藏文件的内容覆盖工作目录的内容,但您仍然会遇到冲突,那么您想要的是使用根目录中的 git checkout --theirs -- . 解决冲突。

之后,您可以 git reset 将索引中的所有更改带到工作目录,因为显然在发生冲突的情况下,对非冲突文件的更改会保留在索引中。

您可能还想在之后运行 git stash drop [<stash name>] 以摆脱存储,因为 git stash pop 不会在发生冲突时将其删除。


V
VonC

请注意,未来的 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”,那么这很有效。但是,如果这些步骤是预提交挂钩的一部分,那么您就没有这个机会(无论测试通过还是失败,您都必须恢复原始状态)。


z
z atef
git restore --staged  name-of-file-that-has--merge-conflict

这似乎是一个有用的替代解决方案,但可以添加一个介绍来解释这究竟有什么影响?人们可能需要多种选择,但这种选择并不总是正确的。