我♥ 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
Run Code Online (Sandbox Code Playgroud)
为什么?
Mu *_*ind 27
每当我试图将一个大块分成太近的小伙伴(变化之间少于3行)时,我就会发生这种情况.简短的解释是补丁中包含与您的本地更改冲突的上下文行.下面有更完整的解释.
假设我有一个带有这些未提交更改的git repo:
--- a/pangram
+++ b/pangram
@@ -1,8 +1,8 @@
The
-quick
+relatively quick
brown
fox
-jumps
+walks
over
the
lazy
Run Code Online (Sandbox Code Playgroud)
如果我收藏第一个更改,我得到:
--- a/pangram
+++ b/pangram
@@ -1,5 +1,5 @@
The
-quick
+relatively quick
brown
fox
jumps
Run Code Online (Sandbox Code Playgroud)
该git stash命令实际上确实成功保存了补丁(check git stash list),但是然后git反向使用该补丁来从我的工作目录中删除隐藏的更改.大块头之后的上下文有"跳跃",这与我工作目录中的"行走"不匹配.所以git拯救了
error: patch failed: pangram:1 error: pangram: patch does not apply Cannot remove worktree changes
并留下我工作目录中的所有变化,而藏匿变得毫无价值.
我会把这称为git的大块分裂支持中的一个bug.如果它知道它将这些变化分得太近,它可以从补丁中删除几行上下文,或者使补丁变得简单,以获得修改后的上下文行而不是原始行.或者,如果分裂帅哥这种关闭是正式不受支持的,它实际上应该拒绝分离那些关闭的帅哥.
在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.我想因为添加索引而不是创建补丁文件?
git stash -pGit 2.17(2018年第二季度)应该会失败.
在此之前," git add -p"(与逻辑分享git stash)在将结果传递给底层" git apply" 之前,在合并拆分补丁方面一直很懒惰,导致角落错误; 在收紧大块选择之后准备要应用的补丁的逻辑.
参见提交3a8522f,提交b3e0fcf,提交2b8ea7f(2018年3月5日),提交fecc6f3,提交23fea4c,提交902f414(2018年3月1日),并提交11489a6,提交e4d671c,提交492e60c(2018年2月19日),由Phillip Wood(phillipwood)提交.
(由Junio C gitsterHamano合并- -在提交436d18f,2018年3月14日)
add -p:当跳过一个时,调整后续帅哥的偏移量
(添加,但同样,可以应用于藏匿)
由于提交8cbd431("
git-add--interactive:使用apply --recount替换hunk recounting",2008-7-2,Git v1.6.0-rc0)如果跳过了一个hunk,那么我们依靠上下文行在正确的位置应用后续的haks.虽然这在大多数情况下都有效,但是帅哥最终可能会被应用到错误的地方.
要解决这个问题,请调整后续数据库的偏移量,以纠正由于跳过的数据块导致的插入或删除次数的任何变化.这里忽略了由于已编辑的具有更改插入或删除次数的数据而导致的偏移量变化,它将在下一次提交中得到修复.
Git 2.19改进了git add -p:当用户在" git add -p"中编辑补丁并且用户的编辑器被设置为不加选择地去除尾随空格时,补丁中未更改的空行将变为完全空(而不是在其上具有唯一SP的行).
在Git 2.17时间框架中引入的代码无法解析这样的补丁,但现在它学会了注意这种情况并应对它.
请参阅Phillip Wood()提交f4d35a6(2018年6月11日).(由Junio C Hamano合并- -在提交5eb8da8,2018年6月28日)phillipwood
gitster
add -p:修复计算修补程序中的空上下文行计数
recount_edited_hunk()在提交2b8ea7f("add -p:calculate offset delta for edited patches",2018-03-05,Git v2.17.0)中引入要求所有上下文行以空格开头,不计算空行.
这是为了避免任何重新计数问题,如果用户在编辑补丁时在末尾引入了空行.然而,这引入了回归'
git add -p',因为编辑器在编辑补丁时从空的上下文行中剥离尾部空格似乎很常见,从而引入应该计数的空行.
'git apply'知道如何处理这些空行和POSIX声明是否在空上下文行上有空格是实现定义的(参见diff命令).通过计算仅包含换行符的行以及以空格作为上下文行开头的行来修复回归,并添加测试以防止将来出现回归.
不幸的是,即使在 Git 2.17 中,目前接受的答案仍然可能失败。
如果像我一样,您花了很多精力构建完美的藏匿处并且不想浪费这些努力,那么仍然可以通过以下方式获得您想要的东西:
git stash show -p | patch -p1 -R
这将因拒绝而失败,但很有可能大多数帅哥会正确应用,至少可以节省您再次查看所有文件的时间。