我使用
从三次提交中创建了一个补丁git format-patch <revision_three_commits_ago>
这会创建三个我从笔记本邮寄的补丁文件,并在我的桌面计算机上读取邮件(两个都是Windows框)。
我现在这样做
git am --3way --ignore-space-change *.patch
补丁适用,但我没有为提交获得相同的SHA1 ID。在修补文件中搜索了一下,我发现桌面计算机上的修改后的行以LF
结尾,而笔记本上的修改后的行(我创建补丁的行)以CR LF
结束。
所以,我的第一个想法就是在没有--ignore-space-change
的情况下拨打git am
,但这会给我一个错误(补丁不适用)。
我怎么能告诉git format-patch
或git am
如何处理行结尾(msysgit 1.7.4)?
在应用修补程序之前,我是否真的需要使用VIM并将文件格式从UNIX
更改为DOS
?
编辑:甚至不用VIM修改补丁文件有帮助:我认为,set ff=dos
和:%s/^M//g
会有所帮助,但事实并非如此!
在我看来,应用补丁应该会导致完全相同的内容,以及我从其他创建补丁的repo中提取的相同提交哈希。我错了吗?
答案 0 :(得分:19)
在使用各种选项(core.autocrlf
,core.eol
)后,我发现使用
git am --keep-cr
可以解决问题(但会引发有关尾随空格的警告)。
不需要手动编辑补丁文件或其他污垢。
但是,(当然)散列是不同的,如nikai的答案所述......感谢nikai指出我的哈希值。
在我的笔记本 - 桌面方案中,我想将一些更改从笔记本电脑离线转移到桌面计算机,但是当我在桌面上应用补丁然后执行操作时,回购不应该分歧也不应该发生相同的提交两次来自笔记本的git pull desktop
。
为实现这一目标,我做了以下工作:
git am --keep-cr ...
git pull desktop
,这导致补丁引入的每个提交发生两次(一次用于原始笔记本提交,一次用于修补和拉入桌面提交)master
分支上),发出git rebase desktop/master
会发出No changes -- Patch already applied
消息,并将原始笔记本提交替换为桌面提交答案 1 :(得分:5)
Git 2。3。0(2015年2月)将提出另一个新选项: --transfer-encoding
,以指定要使用的传输编码(quoted-printable,8bit,base64),而不是仅依靠--keep-cr
。
git send-email
man page。
git am
man page
commit 8d81408见Paolo Bonzini (bonzini
):
git-send-email
:添加--transfer-encoding
选项mailing-list thread详细说明在使用CRLF行结尾的存储库中应用带有“
git am
”的修补程序时的问题。
在线程的示例中,存储库源自“git-svn
”,因此无法在其上使用core.eol
和朋友。目前,最好的选择是使用“
git am --keep-cr
” 但是,当修补程序创建新文件时,修补程序应用程序进程将拒绝新文件,因为它找到“/dev/null\r
”字符串而不是“/dev/null
”。问题是 SMTP transport是CRLF不安全的 通过电子邮件发送补丁与通过“
dos2unix | unix2dos
”传递补丁相同 新引入的CRLF通常是透明的,因为git-am
剥离它们。keepcr=true
设置保留了它们,但它主要是偶然的,在具有混合LF和CRLF行结尾的存储库中有一个“git am
”工作流是非常有问题的。MIME solution to this is the quoted-printable transfer enconding 这不是我们想要默认启用的内容,因为它会使收到的电子邮件看起来很糟糕。
但是,它非常适合将CRLF行结尾存储在存储库中的项目。quoted-printable的唯一缺点是引用可打印 如果维护者使用“
git am --keep-cr
”,则补丁无法应用 这是因为解码后的补丁最后会有两个回车符 这条线 因此,添加对base64 transfer encoding的支持,这使收到的电子邮件无法在MUA (Mail User Agent)之外查看,但实际上只是有效。该补丁涵盖所有基础,包括仍然生活在80年代后期的用户,同时提供7位内容传输编码,拒绝发送带有非ASCII字符的电子邮件。
最后,“8bit”将添加Content-Transfer-Encoding标头,但不执行任何操作。
git send-email的文档现在包括:
--transfer-encoding=(7bit|8bit|quoted-printable|base64)
指定用于通过SMTP发送邮件的传输编码 遇到非ASCII消息时,7位将失败。
当存储库包含包含回车符的文件时,Quoted-printable会很有用,但会使原始修补程序电子邮件文件(从MUA保存)更难以手动检查。
base64更加傻瓜式,但也更加不透明。默认值是“
sendemail.transferEncoding
”配置值的值;如果未指定,git
将使用8位而不添加Content-Transfer-Encoding标头。
答案 2 :(得分:3)
这里有一个类似的问题:apparently same commits give different sha1, why?
作为一个简短的回顾,git cat-file commit <sha>
应该能够缩小树,父母,电子邮件,日期,作者或提交者的名称是否不同,或者是否在提交消息中引入了额外的'\ n'。
答案 3 :(得分:2)
简短回答:git am --committer-date-is-author-date
长篇故事:我刚刚发现我在同一条船上尝试在两个存储库之间进行sneakernet提交。在尝试使用git am
选项后,我注意到文件ID始终匹配,但git am
的连续运行为相同的选项生成不同的提交ID。事实证明,有两个时间戳 - 您通常看到的“作者”时间戳,以及创建提交时的“提交者”时间戳。默认情况下,后者在git am
中设置为当前时间。您需要使用--committer-date-is-author-date
选项来保持日期同步,这反过来会使您的提交ID同步。
因此,如果您的环境中有选项,我会说git bundle
更可靠。