git是错误的:“补丁不适用”

我试图从一个项目提交到第二个类似的使用git的提交。

所以我创build了一个包含5个提交的补丁:

git format-patch 4af51 --stdout > changes.patch 

然后将补丁移动到第二个项目的文件夹,并想要应用该补丁:

 git am changes.patch 

…但它给了我错误:

 Applying: Fixed products ordering in order summary. error: patch failed: index.php:17 error: index.php: patch does not apply Patch failed at 0001 Fixed products ordering in order summary. The copy of the patch that failed is found in: c:/.../project2/.git/rebase-apply/patch When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". 

所以我打开了index.php,但没有改变。 我假设有一些>>>>>>>标记等,就像解决合并冲突一样,但文件中没有标记冲突。 git status也给了我更改的文件的空列表(只有changes.patch在那里)。 所以我运行git am --continue ,但是又出现了一个错误:

 Applying: Fixed products ordering in order summary. No changes - did you forget to use 'git add'? If there is nothing left to stage, chances are that something else already introduced the same changes; you might want to skip this patch. When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". 

我使用Windows 7和最新的git版本“1.9.4.msysgit.1”

PS经过几个小时的谷歌search,我find了一些解决scheme,但没有为我工作:


 git am -3 changes.patch 

给出奇怪的“sha1信息”错误:

 Applying: Fixed products ordering in order summary. fatal: sha1 information is lacking or useless (index.php). Repository lacks necessary blobs to fall back on 3-way merge. Cannot fall back to three-way merge. Patch failed at 0001 Fixed products ordering in order summary. The copy of the patch that failed is found in: c:/.../project2/.git/rebase-apply/patch When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". 

 git am changes.patch --ignore-whitespace --no-scissors --ignore-space-change 

给出第一个错误,如上所示:“错误:补丁失败:index.php:17”,但在index.php没有冲突标记添加。

什么是补丁?

一个补丁比一系列的指令稍微多一些(见下文):“在这里添加”,“删除那里”,“把这第三件事改成第四件”。 这就是为什么 git告诉你:

 The copy of the patch that failed is found in: c:/.../project2/.git/rebase-apply/patch 

你可以在你最喜欢的浏览器或者编辑器中打开这个补丁,在你最喜欢的编辑器中打开要修改的文件,然后用你知道的 (而不是git)修改补丁,找出“add这里“是要做的,当要改变的文件看起来很less或没有什么,他们做什么时,他们做了更早的变化,作为一个补丁提供给你的变化。

再来一点

一个三方合并引入了比简单的“一系列指令”更“多一点”的信息:它告诉你什么是原始版本的文件。 如果您的存储库具有原始版本,则您的git可以将对文件所做的操作与修补程序对该文件所做的操作进行比较。

正如你上面看到的,如果你要求三路合并,git在其他库中找不到“原始版本”,所以甚至不能尝试三路合并。 因此,您不会得到冲突标记,您必须手动执行补丁程序。

使用--reject

当你必须手动应用补丁时,git仍然可以自动应用大部分的补丁,并且只留下几块给实体,并且能够推理代码(或者不pipe它是需要补丁的) 。 添加--reject告诉git这样做,并将修补程序的“不适用”部分保留在拒绝文件中。 如果使用此选项,则必须手动应用每个失败补丁 ,并找出如何处理被拒绝的部分。

一旦你做了必要的更改,你可以git add修改后的文件,并使用git am --continue告诉git提交更改并转到下一个补丁。

如果没有什么可做的呢?

由于我们没有你的代码,我不能确定是否是这种情况,但是有时候,你会发现一个补丁说一些相当重要的东西,例如,“修复第42行的一个单词的拼写”那里的拼写已经固定了。

在这个特例中,你看了补丁和当前的代码,应该对自己说:“啊哈, 这个补丁应该完全被跳过!” 这是当你使用其他的build议git已经打印:

 If you prefer to skip this patch, run "git am --skip" instead. 

如果你运行git am --skip ,git会跳过这个补丁,所以如果邮箱里有五个补丁,那最后只会增加四个提交,而不是五个(如果你跳过两次,等等)。

git format-patch也有-B标志。

手册页中的描述有很多不足之处,但是在简单的语言中,它是阈值格式 – 在对文件进行全部重写之前,修补程序将遵循(通过删除旧的一切,然后单次插入一切都是新的)。

这对手工编辑过于繁琐,对我来说非常有用,而且信息来源比我的目的地更具权威性。

一个例子:

 git format-patch -B10% --stdout my_tag_name > big_patch.patch git am -3 -i < big_patch.patch