git stash blunder:git stash pop并最终出现合并冲突

时间:2010-05-15 16:18:54

标签: git git-stash git-checkout

我做了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

4 个答案:

答案 0 :(得分:218)

请参阅man git merge如何解决冲突):

  

看到冲突后,你可以做两件事:

     
      
  • 决定不合并。您需要的唯一清理是将索引文件重置为HEAD提交以反转2.并清除由2.和3进行的工作树更改。 git-reset --hard可用于此目的。

  •   
  • 解决冲突。 Git将标记工作树中的冲突。将文件编辑为形状,然后将它们添加到索引中。使用git commit来达成协议。

  •   

TRUE MERGE 下(看看2.和3.指的是什么):

  

如果不明白如何协调更改,则会发生以下情况:

     
      
  1. HEAD指针保持不变。

  2.   
  3. MERGE_HEAD ref设置为指向另一个分支头。

  4.   
  5. 干净地合并的路径在索引文件和工作树中都会更新。

  6.   
  7. ...

  8.   

因此:如果要从工作树中删除存储更改,请使用git reset --hard;如果您只想清理索引并将工作树中的冲突留给合并,请使用git reset手。

man git stash OPTIONS,pop )下,您可以阅读:

  

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

答案 1 :(得分:41)

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

答案 2 :(得分:12)

如果像我一样,你通常想要的是用stashed文件的内容覆盖工作目录的内容,但仍然会发生冲突,那么你想要的是使用git checkout --theirs -- .来解决冲突从根。

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

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

答案 3 :(得分:2)

请注意, Git 2.5(2015年第2季度)未来的Git可能会尝试使该场景无法实现。

2015年4月22日commit ed178efpeff)见Jeff King (由Junio C Hamano合并 - gitster - 在commit 05c3967,2015年5月19日)

注意:已经恢复了。见下文

  

stash:需要一个干净的索引来应用/ pop

问题

  

如果您在索引中已暂存内容并运行“stash apply/pop”,我们可能会遇到冲突并在索引中添加新条目。
  此时恢复到原始状态很困难,因为像“git reset --keep”这样的工具会吹掉任何上演的

换句话说:

  

git stash pop/apply”忘记确保工作树不仅清洁,而且索引也很干净。
  后者很重要,因为存储应用程序可能会发生冲突,索引将用于解决冲突。

解决方案

  

我们可以通过在有阶段性更改时拒绝申请来使这更安全。

     

这意味着如果之前有合并因为在已修改的文件上存储(已添加但未提交),则现在它们不会是任何合并,因为存储应用/弹出将立即停止:

Cannot apply stash: Your index contains uncommitted changes.
  

强制您提交更改意味着,在合并的情况下,您可以使用git stash apply/pop轻松恢复初始状态(git reset --hard之前)。

commit 1937610(2015年6月15日)和commit ed178ef(2015年4月22日)Jeff King (peff)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”,那么这个   只是工作。但是,如果这些步骤是预先提交的一部分   钩,你没有那个机会(你必须恢复   原始状态,无论测试是否通过或   失败)。

相关问题