2013-04-22 36 views
10

我试图在我的回购中应用一些补丁,并获得消息patch does not apply,除非我指定参数--ignore-space-change --ignore-whitespace。有些补丁即使使用这些键也不能应用,它表示存在需要手动解决的冲突。 (但实际上没有任何冲突,自动合并必须解决这个问题)git format-patch/am问题(补丁不适用)

我已经做了一个实验:从我的回购中提交创建了一个补丁,将主设备重置为以前的提交,尝试从文件应用补丁。相同的错误消息。

任何想法,为什么会发生这种情况?

UPD的命令很简单:

git format-patch -o ../_patches 0f3bf7874c32b22256ae2d9dc00b1afd6464e43c 
git reset --hard 0f3bf7874c32b22256ae2d9dc00b1afd6464e43c 
git am ../_patches/0001-test2.patch 

(此ID是指前最后一次提交)

+0

你能告诉我们更多关于你运行的命令吗?你在运行什么操作系统? .gitattributes的内容是什么? – jszakmeister 2013-04-22 09:10:47

回答

2

啊哈!看起来我找到了原因。存储库使用CRLF行结束符,但format-patch使用LF创建修补程序文件。当我用autocrlf = false从头创建一个repo并进行相同的实验时,我遇到同样的问题。 (看起来像Git中的bug)
任何建议如何解决这个问题?

UPD我的解决方案是创建一个autocrlf = true的全新存储库,并将这两个存储库中的所有更改重新导入到其中。

9

您需要将--keep-cr标志传递给git am。这很不幸,但由于竞争标准(电子邮件工作流程与本地),实际上没有太多选择。

您可能还想尝试设置.gitattributes文件。试图重新创建你的问题,当我将文件指定为需要CRLF时,我能够使事情发挥作用。请注意,没有首先对文件进行标准化,它确实将整个文件显示为已修改。我通常使用.gitattributes本:

.gitattributes export-ignore 
.gitignore  export-ignore 

*.txt   text 
*.C    text trailing-space space-before-tab -indent-with-non-tab 
*.rst   text trailing-space space-before-tab -indent-with-non-tab 
*.clj   text trailing-space space-before-tab -indent-with-non-tab 

*.c    text diff=cpp trailing-space space-before-tab -indent-with-non-tab 
*.cpp   text diff=cpp trailing-space space-before-tab -indent-with-non-tab 
*.h    text diff=cpp trailing-space space-before-tab -indent-with-non-tab 
*.hpp   text diff=cpp trailing-space space-before-tab -indent-with-non-tab 
*.py   text diff=python trailing-space space-before-tab -indent-with-non-tab 
*.tex   text diff=tex 
*.java   text diff=java trailing-space space-before-tab -indent-with-non-tab 
*.pl   text diff=perl trailing-space space-before-tab -indent-with-non-tab 
*.php   text diff=php 
*.rb   text diff=ruby trailing-space space-before-tab -indent-with-non-tab 

*.vcproj  eol=crlf 
*.dsp   eol=crlf 
*.dsw   eol=crlf 

*.sh   eol=lf 

*.jpg   binary 
*.png   binary 
*.gif   binary 
*.tiff   binary 

您将要结束根据gitattributes man page正常化您的线路。另一个SO用户最终关闭了core.autocrlf as well以获得干净的提交和补丁。

试图重现你的错误

$ git init repo 
Initialized empty Git repository in c:/tmp/git-eol/repo/.git/ 
$ cd repo 
$ git config --local core.autocrlf false 
$ vim foo.txt 
$ git add foo.txt 
$ git commit -m "Add foo." 
[master (root-commit) 3903abd] Add foo. 
1 file changed, 3 insertions(+) 
create mode 100644 foo.txt 
$ vim foo.txt 
$ git st 
## master 
M foo.txt 
$ git commit -m "Add more foo." -a 
[master 03e991a] Add more foo. 
1 file changed, 2 insertions(+) 
$ git format-patch HEAD~1 
0001-Add-more-foo.patch 
$ vim 0001-Add-more-foo.patch 

望着那被制作补丁文件,我看到:

正如你所看到的,回车(^M s)被保存在补丁中。这是与core.autocrlf=false。继续,我看到:

$ git reset --hard HEAD~1 
HEAD is now at 3903abd Add foo. 
$ git am 0001-Add-more-foo.patch 
Applying: Add more foo. 
error: patch failed: foo.txt:1 
error: foo.txt: patch does not apply 
Patch failed at 0001 Add more foo. 
The copy of the patch that failed is found in: 
    c:/tmp/git-eol/repo/.git/rebase-apply/patch 
When you have resolved this problem, run "git am --resolved". 
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 --abort 

因此,该补丁不适用于开箱即用。使用--keep-cr虽然如预期:

$ git am --keep-cr 0001-Add-more-foo.patch 
Applying: Add more foo. 
$ 

好吧。因此,让我们试试这个与core.autocrlf=true(不同的版本库):

# Removed the initial commands... 
$ git format-patch HEAD~1 
0001-Add-more-foo.patch 
$ git reset --hard HEAD~1 
HEAD is now at 525b5aa Initial commit. 
$ git am 0001-Add-more-foo.patch 
Applying: Add more foo. 
$ git config --get core.autocrlf 
true 

在这种情况下,补丁随处有LF结局。

+0

这似乎不能解决不适用的修补程序问题。 – fithu 2013-04-23 05:28:32

+0

你试过了吗?我不仅遇到过这个问题,而且还在这里复制了它。你在下面评论关于用LF生成补丁,我认为这是不正确的。标题有LF,但diff的实际行可能具有CRLF结尾。 'git am'剥离CR,这是问题出现的地方。也许你实际上有*混合*行结束? – jszakmeister 2013-04-23 08:26:35

+0

你想告诉我,我错了只有_assumptions和beliefs_?没有混合线结束。生成的补丁文件中的所有行尾都是纯LF,尽管repo仅使用CRLF。 – fithu 2013-04-23 09:03:49