git stash 错误:git stash pop 并以合并冲突告终
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2840816/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
git stash blunder: git stash pop and ended up with merge conflicts
提问by Chirag Patel
I did a git stash pop
and ended up with merge conflicts. I removed the files from the file system and did a git checkout
as shown below, but it thinks the files are still unmerged. I then tried replacing the files and doing a git checkout
again and same result. I event tried forcing it with -f
flag. Any help would be appreciated!
我做了一个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
回答by tanascius
See man git merge(HOW TO RESOLVE CONFLICTS):
请参阅man git merge(如何解决冲突):
After seeing a conflict, you can do two things:
Decide not to merge. The only clean-ups you need are to reset the index file to the HEAD commit to reverse 2. and to clean up working tree changes made by 2. and 3.; git-reset --hard can be used for this.
Resolve the conflicts. Git will mark the conflicts in the working tree. Edit the files into shape and git add them to the index. Use git commit to seal the deal.
看到冲突后,你可以做两件事:
决定不合并。您需要做的唯一清理工作是将索引文件重置为 HEAD 提交以反转 2. 并清理由 2. 和 3. 所做的工作树更改;git-reset --hard 可以用于此。
解决冲突。Git 会在工作树中标记冲突。将文件编辑成形状并将它们添加到索引中。使用 git commit 来达成交易。
And under TRUE MERGE(to see what 2. and 3. refers to):
在TRUE MERGE 下(查看 2. 和 3. 指的是什么):
When it is not obvious how to reconcile the changes, the following happens:
The HEAD pointer stays the same.
The MERGE_HEAD ref is set to point to the other branch head.
Paths that merged cleanly are updated both in the index file and in your working tree.
...
当不清楚如何协调更改时,会发生以下情况:
HEAD 指针保持不变。
MERGE_HEAD ref 设置为指向另一个分支头。
干净合并的路径在索引文件和工作树中都会更新。
...
So: use git reset --hard
if you want to remove the stash changes from your working tree, or git reset
if you want to just clean up the index and leave the conflicts in your working tree to merge by hand.
所以:git reset --hard
如果您想从工作树中删除存储更改,或者git reset
您只想清理索引并将工作树中的冲突手动合并,请使用。
Under man git stash(OPTIONS, pop) you can read in addition:
在man git stash( OPTIONS, pop) 下,您还可以阅读:
Applying the state can fail with conflicts; in this case, it is not removed from the stash list. You need to resolve the conflicts by hand and call git stash drop manually afterwards.
应用状态可能会因冲突而失败;在这种情况下,它不会从存储列表中删除。您需要手动解决冲突,然后手动调用 git stash drop。
回答by Aaron
I had a similar thing happen to me. I didn't want to stage the files just yet so I added them with git add
and then just did git reset
. This basically just added and then unstaged my changes but cleared the unmerged paths.
我也遇到过类似的事情。我还不想暂存文件,所以我添加了它们,git add
然后就做了git reset
. 这基本上只是添加然后取消了我的更改,但清除了未合并的路径。
回答by Pedro Gimeno
If, like me, what you usually want is to overwrite the contents of the working directory with that of the stashed files, and you still get a conflict, then what you want is to resolve the conflict using git checkout --theirs -- .
from the root.
如果像我一样,您通常想要用隐藏文件的内容覆盖工作目录的内容,但仍然遇到冲突,那么您想要的是git checkout --theirs -- .
从根目录使用来解决冲突。
After that, you can git reset
to bring all the changes from the index to the working directory, since apparently in case of conflict the changes to non-conflicted files stay in the index.
之后,您可以git reset
将所有更改从索引带到工作目录,因为显然在发生冲突时,对非冲突文件的更改仍保留在索引中。
You may also want to run git stash drop [<stash name>]
afterwards, to get rid of the stash, because git stash pop
doesn't delete it in case of conflicts.
您可能还想在git stash drop [<stash name>]
之后运行,以摆脱存储,因为git stash pop
在发生冲突时不会删除它。
回答by VonC
Note that Git 2.5 (Q2 2015)a future Git might try to make that scenario impossible.
注意 Git 2.5(2015 年第二季度)未来的 Git 可能会试图让这种情况变得不可能。
See commit ed178efby Jeff King(peff
), 22 Apr 2015.
(Merged by Junio C Hamano-- gitster
-- in commit 05c3967, 19 May 2015)
请参阅Jeff King( ) 的commit ed178ef,2015 年 4 月 22 日。(由Junio C Hamano合并-- -- 在commit 05c3967 中,2015 年 5 月 19 日)peff
gitster
Note: This has been reverted. See below.
注意:这已被恢复。见下文。
stash
: require a clean index to apply/pop
stash
: 需要一个干净的索引来应用/弹出
Problem
问题
If you have staged contents in your index and run "
stash apply/pop
", we may hit a conflict and put new entries into the index.
Recovering to your original state is difficult at that point, because tools like "git reset --keep" will blow away anything staged.
如果您在索引中暂存了内容并运行“
stash apply/pop
”,我们可能会遇到冲突并将新条目放入索引中。
那时恢复到原始状态是很困难的,因为像“git reset --keep”这样的工具会吹走任何 staged。
In other words:
换句话说:
"
git stash pop/apply
" forgot to make sure that not just the working tree is clean but also the index is clean.
The latter is important as a stash application can conflict and the index will be used for conflict resolution.
"
git stash pop/apply
" 忘记确保不仅工作树是干净的,而且索引也是干净的。
后者很重要,因为 stash 应用程序可能会发生冲突,并且索引将用于解决冲突。
Solution
解决方案
We can make this safer by refusing to apply when there are staged changes.
That means if there were merges before because of applying a stash on modified files (added but not committed), now they would not be any merges because the stash apply/pop would stop immediately with:
我们可以通过在分阶段更改时拒绝申请来使这更安全。
这意味着如果之前由于在修改后的文件(添加但未提交)上应用存储而进行了合并,现在它们不会是任何合并,因为存储应用/弹出将立即停止:
Cannot apply stash: Your index contains uncommitted changes.
Forcing you to commit the changes means that, in case of merges, you can easily restore the initial state( before
git stash apply/pop
) with agit reset --hard
.
强制您提交更改意味着,在合并的情况下,您可以
git stash apply/pop
使用git reset --hard
.
See commit 1937610(15 Jun 2015), and commit ed178ef(22 Apr 2015) by Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
--in commit bfb539b, 24 Jun 2015)
见犯1937610(2015年6月15日),并提交ed178ef(2015年4月22日),由杰夫·王(peff
)。
(由Junio C gitster
Hamano合并-- --在提交 bfb539b 中,2015 年 6 月 24 日)
That commit was an attempt to improve the safety of applying a stash, because the application process may create conflicted index entries, after which it is hard to restore the original index state.
Unfortunately, this hurts some common workflows around "
git stash -k
", like:
该提交是为了提高应用 stash 的安全性,因为应用进程可能会创建冲突的索引条目,之后很难恢复原始索引状态。
不幸的是,这会损害一些围绕“
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
If you "git commit" between steps (3) and (4), then this just works. However, if these steps are part of a pre-commit hook, you don't have that opportunity (you have to restore the original state regardless of whether the tests passed or failed).
如果您在步骤 (3) 和 (4) 之间“git commit”,那么这只是有效。但是,如果这些步骤是预提交挂钩的一部分,则您没有这个机会(无论测试通过还是失败,您都必须恢复原始状态)。