我试图使用git将几个提交从一个项目移动到第二个类似的提交.
所以我创建了一个包含5个提交的补丁:
git format-patch 4af51 --stdout > changes.patch
Run Code Online (Sandbox Code Playgroud)
然后将补丁移动到第二个项目的文件夹并想要应用补丁:
git am changes.patch
Run Code Online (Sandbox Code Playgroud)
...但它给了我错误:
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".
Run Code Online (Sandbox Code Playgroud)
所以我打开了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".
Run Code Online (Sandbox Code Playgroud)
我使用的是Windows 7和最新的git版本"1.9.4.msysgit.1"
PS经过几个小时的谷歌搜索,我找到了一些解决方案,但没有什么对我有用:
git am -3 changes.patch
Run Code Online (Sandbox Code Playgroud)
给出了奇怪的"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".
Run Code Online (Sandbox Code Playgroud)
git am changes.patch --ignore-whitespace --no-scissors --ignore-space-change
Run Code Online (Sandbox Code Playgroud)
如上所述给出第一个错误:"错误:补丁失败:index.php:17",但没有index.php
添加冲突标记.
tor*_*rek 95
补丁比一系列指令更多(见下文):"在这里添加","删除那里","将第三件事改为第四件".这就是 git告诉你的原因:
Run Code Online (Sandbox Code Playgroud)The copy of the patch that failed is found in: c:/.../project2/.git/rebase-apply/patch
您可以在您喜欢的查看器或编辑器中打开该补丁,在您喜欢的编辑器中打开要更改的文件,并使用您所知道的(并且git没有)"手动应用"补丁来弄清楚如何 "添加"这里要做的是"当要更改的文件现在看起来很少或什么都不像他们之前更改时所做的那样,将这些更改作为补丁传递给您.
三向合并引入了比简单的"一系列指令"更多的"信息":它告诉你文件的原始版本是什么.如果您的存储库具有原始版本,那么您的git可以将您对文件所做的操作与修补程序对文件所做的操作进行比较.
如上所述,如果您请求三向合并,git无法在其他存储库中找到"原始版本",因此它甚至无法尝试三向合并.因此,您没有获得冲突标记,您必须手动执行补丁程序.
--reject
当您必须手动应用补丁时,git仍然可以自动应用大部分补丁,只留下几个部分,能够推断代码(或者需要修补的任何东西) .添加--reject
tell git来做到这一点,并将补丁的"不适用"部分留在拒绝文件中. 如果使用此选项,则仍必须手动应用每个失败的补丁,并弄清楚如何处理被拒绝的部分.
完成所需的更改后,您可以git add
修改文件并使用它git am --continue
来告诉git提交更改并转到下一个修补程序.
由于我们没有你的代码,我无法判断是否是这种情况,但有时候,你最终会找到一些补丁来说明相当于的事情,例如"修复第42行的单词拼写"当那里的拼写已经修好了.
在这种特殊情况下,你看过补丁和当前的代码,应该对自己说:"啊哈,这个补丁应该完全被跳过!" 那是当你使用已打印的其他建议git时:
Run Code Online (Sandbox Code Playgroud)If you prefer to skip this patch, run "git am --skip" instead.
如果你运行git am --skip
,git将跳过该补丁,这样如果邮箱中有五个补丁,它最终只会添加四个提交,而不是五个(如果你跳过两次,则为三个而不是五个,依此类推).
这种错误可能是由 LF 与 CRLF 行结尾不匹配引起的,例如,当您查看补丁文件时,您绝对确定它应该能够应用,但事实并非如此。
为了测试这一点,如果您有一个仅适用于一个文件的补丁,您可以尝试仅在该文件上运行“unix2dos”或“dos2unix”(两者都尝试,以查看哪一个导致文件更改;您可以获取这些适用于 Windows 和 Unix 的实用程序),然后将该更改作为测试提交提交,然后再次尝试应用补丁。如果这有效,那就是问题所在。
NBgit am
默认情况下将补丁应用为 LF(即使补丁文件包含 CRLF),因此如果要将 CRLF 补丁应用于 CRLF 文件,则必须使用git am --keep-cr
,按照此答案。
git format-patch
也有-B
国旗。
手册页中的描述还有很多不足之处,但用简单的语言来说,这是格式补丁在完全重写文件之前将遵守的阈值(通过一次删除所有旧内容,然后插入一次一切都是新的)。
当手动编辑太麻烦并且来源比我的目的地更权威时,这对我来说非常有用。
一个例子:
git format-patch -B10% --stdout my_tag_name > big_patch.patch
git am -3 -i < big_patch.patch
Run Code Online (Sandbox Code Playgroud)
我有同样的问题。我用过
git format-patch <commit_hash>
Run Code Online (Sandbox Code Playgroud)
创建补丁。我的主要问题是补丁由于某些冲突而失败,但我在文件内容中看不到任何合并冲突。我曾经git am --3way <patch_file_path>
应用过补丁。
应用补丁的正确命令应该是:
git am --3way --ignore-space-change <patch_file_path>
Run Code Online (Sandbox Code Playgroud)
如果执行上述命令进行补丁,如果补丁应用失败会产生合并冲突。然后您可以修复文件中的冲突,就像解决git merge 的合并冲突一样