我♥git stash -p
。但有时候,在满意的y
,n
和s
会话之后,我会明白这一点:
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
为什么?
答案 0 :(得分:27)
任何时候我试图将一个大块分成太近的小伙伴(变化之间少于3行)。简短的解释是补丁中包含与您的本地更改冲突的上下文行。下面有更完整的解释。
假设我有一个带有这些未提交更改的git repo:
--- 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拯救了
error: patch failed: pangram:1 error: pangram: patch does not apply Cannot remove worktree changes
并留下我工作目录中的所有变化,并且藏匿变得毫无价值。
我认为这是git的大块分裂支持中的一个错误。如果它知道它将这些变化分得太近,它可以从补丁中删除几行上下文,或者使补丁变得简单,以获得修改后的上下文行而不是原始行。或者,如果将这种情况分开,这种关闭是正式不受支持的,它实际上应该拒绝分离那些关闭的人。
答案 1 :(得分:6)
在以同样的方式发生git stash -p
失败之后,我对此解决方法很有好处(git 2.0.2):
git add -p
,将完全相同的帅哥分开,但使用反向答案(“y”到add
“保持”变化,“n”到stash
保持变化。)git stash -k
保留索引并隐藏其他所有内容git reset
继续处理我的文件我不确定为什么git add -p
没有像git stash -p
那样失败。我想因为添加索引而不是创建补丁文件?
答案 2 :(得分:6)
git stash -p
应该会失败
在此之前,“git add -p
”(与git stash
共享逻辑)在将结果传递给基础“git apply
”之前,在合并拆分补丁方面一直很懒惰,导致了角落案例错误;在收紧大块选择之后准备要应用的补丁的逻辑。
请参阅commit 3a8522f,commit b3e0fcf,commit 2b8ea7f(2018年3月5日),commit fecc6f3,commit 23fea4c,commit 902f414(2018年3月1日),和commit 11489a6,commit e4d671c,commit 492e60c(2018年2月19日)Phillip Wood (phillipwood
)。
(由Junio C Hamano -- gitster
--合并于commit 436d18f,2018年3月14日)
add -p
:在跳过一个时调整后续帅哥的偏移量
(添加,但同样可以应用于藏匿)
自commit 8cbd431(“
git-add--interactive
:”替换hunk 使用apply --recount“,2008-7-2,Git v1.6.0-rc0进行重新计数)如果跳过一个大块,那么我们依靠上下文线来应用右边的后续 地点。虽然大多数时候这种情况有效,但是帅哥可能会这样做 最终被应用在错误的地方。
要解决此问题,请调整偏移量 随后的帅哥纠正任何数量的变化 由于跳过的大块而导致的插入或删除。偏移量的变化 由于编辑的帅哥有插入或删除的数量 这里忽略了更改,它将在下次提交时修复。
您可以看到some tests here。
Git 2.19改进了git add -p
:当用户在“git add -p
”中编辑补丁并且用户的编辑器被设置为不加区别地删除尾随空格时,补丁中未更改的空行将变为完全为空(而不是带有唯一SP的线)
在Git 2.17时间框架中引入的代码无法解析这样的补丁,但现在它学会了注意这种情况并应对它。
commit f4d35a6见Phillip Wood (phillipwood
)(2018年6月11日)
(由Junio C Hamano -- gitster
--合并于commit 5eb8da8,2018年6月28日)
commit 2b8ea7f中引入了
add -p
:修复已编辑补丁中的空上下文行计数
recount_edited_hunk()
(“add -p: 计算修补补丁的偏移增量“,2018-03-05,Git v2.17.0”要求所有上下文行以空格开头,不计算空行。
这是为了避免任何重新计数问题,如果用户在编辑补丁时在末尾引入了空行。然而,这引入了对“
git add -p
”的回归,因为编辑器在编辑补丁时从空上下文行中剥离尾随空格似乎很常见,从而引入应该是空行的空行 计数。
'git apply'知道如何处理这些空行,POSIX声明空上下文行是否有空格是实现定义的(参见diff command)。通过计算仅包含换行符的行来修复回归 以及以空格开头的行作为上下文行并添加测试 以防止未来的回归。
答案 3 :(得分:4)
即使在Git 2.17中,目前接受的答案仍然可能失败。
如果像我一样,你花费了很多精力来构建完美的藏匿点并且不想抛弃那些努力,那么仍然可以大部分得到你想要的东西:
git stash show -p | patch -p1 -R
这会因拒绝而失败,但赔率很高,大多数帅哥都会正确应用,至少可以节省你再次审阅所有文件的时间。
答案 4 :(得分:-2)
应用状态可能会因冲突而失败;在这种情况下,它不会从隐藏列表中删除。您需要手动解决冲突并随后手动调用git stash drop