为什么`git stash -p`有时会失败?

我♥ git stash -p 。 但是有时候,在一个令人满意的yns会议之后,我得到了这个:

 Saved working directory and index state WIP on foo: 9794c1a lorum ipsum error: patch failed: spec/models/thing_spec.rb:65 error: spec/models/thing_spec.rb: patch does not apply Cannot remove worktree changes 

为什么?

任何时候,我都会尝试将一个大块分成一个小块(它们之间的距离小于3行)。 简单的解释是修补程序中的上下文行与您的本地更改冲突。 下面更全面的解释。


假设我有一个这些未提交的更改的git回购:

 --- a/pangram +++ b/pangram @@ -1,8 +1,8 @@ The -quick +relatively quick brown fox -jumps +walks over the lazy 

如果我藏起第一个变化,我会得到:

 --- a/pangram +++ b/pangram @@ -1,5 +1,5 @@ The -quick +relatively quick brown fox jumps 

git stash命令实际上可以成功地保存这个补丁(检查git stash list ),但是git使用这个补丁来从我的工作目录中删除存储的修改。 大块之后的上下文有“跳跃”,这与我工作目录中的“走路”不匹配。 所以git跟着退出

错误:补丁失败:pangram:1
错误:pangram:补丁不适用
无法删除工作树的更改

并留下了我的工作目录中的所有变化,并且隐藏变得非常不值钱。


我会把这叫做git的分裂支持中的一个bug。 如果它知道它将这些变化分离得太近,它可能会从修补程序中删除几行上下文,或者将修补程序删除以修改上下文行而不是原始行。 另外,如果这个closures分裂的方式在官方上是不受支持的,那么它实际上应该拒绝分割那个closures的方块。

在以同样的方式使用git stash -p失败之后,我对这个解决方法很有好感(git 2.0.2):

  • git add -p ,拆分完全相同的hunk,但用相反的答案(“y” add “保持”更改,“n”保留更改)。
  • git stash -k保留索引并隐藏其他所有内容
  • git reset以继续处理我的文件

我不知道为什么git add -p没有像git stash -p那样失败。 我猜是因为用索引添加作品而不是创build补丁文件?

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