我需要编写一个脚本,为SHA-1提交号列表创建补丁。

我尝试使用git格式补丁<SHA1>,但从SHA-1值开始,每次提交都会生成一个补丁。在生成了几百个补丁之后,我不得不终止这个过程。

是否有方法只为特定的SHA-1值生成补丁?


当前回答

如果您希望确保在特定提交的基础上应用(单次提交)补丁,可以使用新的git2.9(2016年6月)选项git格式补丁--base

git format-patch --base=COMMIT_VALUE~ -M -C COMMIT_VALUE~..COMMIT_VALUE

# or
git format-patch --base=auto -M -C COMMIT_VALUE~..COMMIT_VALUE

# or
git config format.useAutoBase true
git format-patch -M -C COMMIT_VALUE~..COMMIT_VALUE

参见叶小龙(``)提交的提交bb52995、提交3de6651、提交fa2ab86、提交ded2c09(2016年4月26日)。(于2016年5月23日由Junio C Hamano--gitster合并,提交72ce3ff)

格式补丁:添加“--base”选项以记录基本树信息

维护人员或第三方测试人员可能想知道确切的基本树补丁系列适用于。教git格式补丁一个“--base”选项记录基本树信息并将其附加在第一个树的末尾消息(封面信或系列中的第一个补丁)。基本树信息包括“基本提交”,这是众所周知的承诺这是项目历史稳定部分的一部分每个人else可以使用,以及零个或多个“必备补丁”,这些补丁是尚未成为“基本提交”一部分的知名补丁需要按拓扑顺序应用于“基本提交”之上在可以应用补丁之前。“base commit”显示为“base commit:”,后跟40个十六进制提交对象名称。“必备补丁”显示为“必备补丁id:”,后跟40个十六进制“补丁id”,可以通过“git patch id--stable”命令传递补丁来获得。


Git 2.23(2019年第三季度)将改进这一点,因为“格式补丁”的“--base”选项以不稳定的方式计算了先决补丁的补丁id,该选项已更新为以与“Git补丁id--stable”兼容的方式计算。

参见Stephen Boyd(akshayka)的提交a8f6855,提交6f93d26(2019年4月26日)。(由Junio C Hamano--gitster于2019年6月13日提交8202d12合并)

格式补丁:make--基本补丁id输出稳定

每次处理diff.c中的补丁id生成代码,但我们在使用“补丁id”工具生成“稳定”补丁id。让我们将类似的逻辑从patch-id.c移植到diff.c中,这样当我们为“format patch--base=”类型的命令调用生成补丁id时,就可以获得相同的哈希值。


在Git 2.24(2019年第4季度)之前,“Git format patch-o<outdir>”与“mkdir<outdir>”等效,而不是“mkdir-p<outdir”,这一点正在纠正中。

参见Bert Wesarg(bertwesarg)的承诺EDFC31(2019年10月11日)。(由Junio C Hamano(吉斯特)于2019年10月18日提交f1afbb0合并)

格式补丁:创建输出目录的主要组件签字人:Bert Wesarg

“git format patch-o”等效于“mkdir<outdir>”,而不是“mkdir-p<outdir>”,正在更正。

避免在前导目录上使用“adjust_shared_perm”,这可能会影响安全性。通过临时禁用“config.sharedRepository”实现,就像“gitinit”一样。


对于Git 2.25(2020年第1季度),在设置format.useAutoBase配置变量时,“Git rebase”无法正常工作,这一点已得到纠正。

参见Denton Liu(Denton-L)提交的提交cae0bc0、提交945dc55、提交700e006、提交a749d01、提交0c47e06(2019年12月4日)。(由Junio C Hamano--gitster合并,于2019年12月16日提交71a7de7)

rebase:修复format.useAutoBase损坏报告人:克里斯蒂安·比辛格签字人:Denton Liu在format.useAutoBase=true的情况下,运行rebase会导致错误:致命:无法获取上游,如果要自动记录基本提交,请使用gitbranch--set upstream to跟踪远程分支。或者您可以通过--base=<basecommit-id>手动指定基本提交错误:git在准备要重播的修补程序时遇到错误这些修订:电子邮箱:。。d8f581194799ae29bf5fa72a98cbae98a1198b12因此,git无法重新设置它们的基础。通过始终从rebase传递--no base来格式化补丁,从而消除format.useAutoBase的影响,从而解决此问题。


在Git 2.29(2020年第4季度)中,“Git format patch”(man)学会将“whenAble”作为format.useAutoBase配置变量的可能值,当自动计算的基数没有意义时,该变量将变为no op。

见Jacob Keller(雅各布·凯勒)的承诺7efba5f(2020年10月1日)。(由Junio C Hamano--gitster合并,提交5f8c70a,2020年10月5日)

格式补丁:teach format.useAutoBase“whenAble”选项签字人:Jacob Keller

format.useAutoBase配置选项允许用户默认为格式补丁启用“--base=auto”。这有时会导致工作流程不佳,因为在尝试格式化旧补丁时出现意外失败:$git格式补丁-1<旧提交>致命:基本提交不应在修订列表中这可能非常令人困惑,因为用户请求--base并不一定立即显而易见(因为这是在配置中,而不是在命令行中)。我们确实希望--base=auto在无法提供合适的基础时失败,因为如果格式化的补丁在请求时不包含基础信息,这同样会令人困惑。教格式。使用AutoBase新模式“whenAble”。此模式将导致格式修补程序在可能时尝试包含基本提交。然而,若找不到有效的基本提交,那个么格式化补丁将继续格式化补丁,而无需基本提交。为了避免使另一个分支名称不能与--base一起使用,请不要教导--base=whenAble或--base=whenAble。相反,重构base_commit选项以使用回调,并依赖全局配置变量auto_base。这意味着用户不能从命令行请求生成可选的基本提交。然而,这可能并不太有价值。如果用户手动请求基本信息,将立即通知他们无法获取适当的基本提交。这允许用户做出是否继续格式化的明智选择。添加测试以覆盖--base的新操作模式。

git-config现在在其手册页中包括:

默认情况下格式化补丁。也可以设置为“whenAble”以允许启用--base=auto(如果有合适的基数可用),但要跳过添加基本信息,否则格式不会消亡。


对于Git 2.30(2021第1季度),“Git format-patch--output=there”(man)没有按预期工作,反而崩溃了。

现在支持该选项。

参见Jeff King(peff)的提交dc1672d、提交1e1693b、提交4c6f781(2020年11月4日)。(于2020年11月18日由Junio C Hamano--gitster--在提交5edc8bd时合并)

格式补丁:support--输出选项报告人:Johannes Postler签字人:Jeff King

我们从未打算在格式补丁中支持diff的--output选项。直到baa4adc66a(解析选项:禁用带有parse_OPT_KEEP_UNKNOWN的选项缩写,2019-01-27,Git v2.22.0-rc0),才可能触发。我们首先解析格式补丁选项,然后将剩余部分交给setup_revisions()。在提交之前,我们接受“--output=foo”作为“--output directory=foo”的缩写。但之后,我们不检查缩写,而是将输出传递给diff代码。这会导致无意义的行为和错误。diff代码将在rev.diffopt.file中打开一个文件句柄,但我们将用为每个补丁文件打开的自己的句柄覆盖它。因此--输出文件将始终为空。但更糟糕的是,diff代码还设置了rev.diffopt.close_file,因此log_tree_commit()将关闭文件句柄本身。然后cmd_format_patch()中的主循环将再次尝试关闭它,从而产生双释放。最简单的解决方案是不允许使用格式补丁输出,因为没有人打算这样做。然而,我们意外地记录了它(因为格式补丁包括diff选项)。它确实可以使用“gitlog”(man),它将整个输出写入指定的文件。使其适用于格式补丁也很简单:它实际上与--stdout相同,但指向特定的文件。我们可以通过“close_file”标志检测--output选项的使用(请注意,我们不能使用rev.diffopt.file,因为diff设置会将其设置为stdout)。所以我们只需要取消设置该标志,但不必做任何其他操作。另外,我们的情况与--stdout完全相同(请注意,我们没有fclose()文件,但stdout情况也没有;退出程序为我们解决了这一问题)。

其他回答

如何仅为特定SHA-1值生成补丁?

这很简单:

选项1。git show commitID>myFile.patch

选项2。gitcommitID~1..commitID>myFile.patch

注意:将commitID替换为实际的提交id(SHA-1提交代码)。

如果您希望确保在特定提交的基础上应用(单次提交)补丁,可以使用新的git2.9(2016年6月)选项git格式补丁--base

git format-patch --base=COMMIT_VALUE~ -M -C COMMIT_VALUE~..COMMIT_VALUE

# or
git format-patch --base=auto -M -C COMMIT_VALUE~..COMMIT_VALUE

# or
git config format.useAutoBase true
git format-patch -M -C COMMIT_VALUE~..COMMIT_VALUE

参见叶小龙(``)提交的提交bb52995、提交3de6651、提交fa2ab86、提交ded2c09(2016年4月26日)。(于2016年5月23日由Junio C Hamano--gitster合并,提交72ce3ff)

格式补丁:添加“--base”选项以记录基本树信息

维护人员或第三方测试人员可能想知道确切的基本树补丁系列适用于。教git格式补丁一个“--base”选项记录基本树信息并将其附加在第一个树的末尾消息(封面信或系列中的第一个补丁)。基本树信息包括“基本提交”,这是众所周知的承诺这是项目历史稳定部分的一部分每个人else可以使用,以及零个或多个“必备补丁”,这些补丁是尚未成为“基本提交”一部分的知名补丁需要按拓扑顺序应用于“基本提交”之上在可以应用补丁之前。“base commit”显示为“base commit:”,后跟40个十六进制提交对象名称。“必备补丁”显示为“必备补丁id:”,后跟40个十六进制“补丁id”,可以通过“git patch id--stable”命令传递补丁来获得。


Git 2.23(2019年第三季度)将改进这一点,因为“格式补丁”的“--base”选项以不稳定的方式计算了先决补丁的补丁id,该选项已更新为以与“Git补丁id--stable”兼容的方式计算。

参见Stephen Boyd(akshayka)的提交a8f6855,提交6f93d26(2019年4月26日)。(由Junio C Hamano--gitster于2019年6月13日提交8202d12合并)

格式补丁:make--基本补丁id输出稳定

每次处理diff.c中的补丁id生成代码,但我们在使用“补丁id”工具生成“稳定”补丁id。让我们将类似的逻辑从patch-id.c移植到diff.c中,这样当我们为“format patch--base=”类型的命令调用生成补丁id时,就可以获得相同的哈希值。


在Git 2.24(2019年第4季度)之前,“Git format patch-o<outdir>”与“mkdir<outdir>”等效,而不是“mkdir-p<outdir”,这一点正在纠正中。

参见Bert Wesarg(bertwesarg)的承诺EDFC31(2019年10月11日)。(由Junio C Hamano(吉斯特)于2019年10月18日提交f1afbb0合并)

格式补丁:创建输出目录的主要组件签字人:Bert Wesarg

“git format patch-o”等效于“mkdir<outdir>”,而不是“mkdir-p<outdir>”,正在更正。

避免在前导目录上使用“adjust_shared_perm”,这可能会影响安全性。通过临时禁用“config.sharedRepository”实现,就像“gitinit”一样。


对于Git 2.25(2020年第1季度),在设置format.useAutoBase配置变量时,“Git rebase”无法正常工作,这一点已得到纠正。

参见Denton Liu(Denton-L)提交的提交cae0bc0、提交945dc55、提交700e006、提交a749d01、提交0c47e06(2019年12月4日)。(由Junio C Hamano--gitster合并,于2019年12月16日提交71a7de7)

rebase:修复format.useAutoBase损坏报告人:克里斯蒂安·比辛格签字人:Denton Liu在format.useAutoBase=true的情况下,运行rebase会导致错误:致命:无法获取上游,如果要自动记录基本提交,请使用gitbranch--set upstream to跟踪远程分支。或者您可以通过--base=<basecommit-id>手动指定基本提交错误:git在准备要重播的修补程序时遇到错误这些修订:电子邮箱:。。d8f581194799ae29bf5fa72a98cbae98a1198b12因此,git无法重新设置它们的基础。通过始终从rebase传递--no base来格式化补丁,从而消除format.useAutoBase的影响,从而解决此问题。


在Git 2.29(2020年第4季度)中,“Git format patch”(man)学会将“whenAble”作为format.useAutoBase配置变量的可能值,当自动计算的基数没有意义时,该变量将变为no op。

见Jacob Keller(雅各布·凯勒)的承诺7efba5f(2020年10月1日)。(由Junio C Hamano--gitster合并,提交5f8c70a,2020年10月5日)

格式补丁:teach format.useAutoBase“whenAble”选项签字人:Jacob Keller

format.useAutoBase配置选项允许用户默认为格式补丁启用“--base=auto”。这有时会导致工作流程不佳,因为在尝试格式化旧补丁时出现意外失败:$git格式补丁-1<旧提交>致命:基本提交不应在修订列表中这可能非常令人困惑,因为用户请求--base并不一定立即显而易见(因为这是在配置中,而不是在命令行中)。我们确实希望--base=auto在无法提供合适的基础时失败,因为如果格式化的补丁在请求时不包含基础信息,这同样会令人困惑。教格式。使用AutoBase新模式“whenAble”。此模式将导致格式修补程序在可能时尝试包含基本提交。然而,若找不到有效的基本提交,那个么格式化补丁将继续格式化补丁,而无需基本提交。为了避免使另一个分支名称不能与--base一起使用,请不要教导--base=whenAble或--base=whenAble。相反,重构base_commit选项以使用回调,并依赖全局配置变量auto_base。这意味着用户不能从命令行请求生成可选的基本提交。然而,这可能并不太有价值。如果用户手动请求基本信息,将立即通知他们无法获取适当的基本提交。这允许用户做出是否继续格式化的明智选择。添加测试以覆盖--base的新操作模式。

git-config现在在其手册页中包括:

默认情况下格式化补丁。也可以设置为“whenAble”以允许启用--base=auto(如果有合适的基数可用),但要跳过添加基本信息,否则格式不会消亡。


对于Git 2.30(2021第1季度),“Git format-patch--output=there”(man)没有按预期工作,反而崩溃了。

现在支持该选项。

参见Jeff King(peff)的提交dc1672d、提交1e1693b、提交4c6f781(2020年11月4日)。(于2020年11月18日由Junio C Hamano--gitster--在提交5edc8bd时合并)

格式补丁:support--输出选项报告人:Johannes Postler签字人:Jeff King

我们从未打算在格式补丁中支持diff的--output选项。直到baa4adc66a(解析选项:禁用带有parse_OPT_KEEP_UNKNOWN的选项缩写,2019-01-27,Git v2.22.0-rc0),才可能触发。我们首先解析格式补丁选项,然后将剩余部分交给setup_revisions()。在提交之前,我们接受“--output=foo”作为“--output directory=foo”的缩写。但之后,我们不检查缩写,而是将输出传递给diff代码。这会导致无意义的行为和错误。diff代码将在rev.diffopt.file中打开一个文件句柄,但我们将用为每个补丁文件打开的自己的句柄覆盖它。因此--输出文件将始终为空。但更糟糕的是,diff代码还设置了rev.diffopt.close_file,因此log_tree_commit()将关闭文件句柄本身。然后cmd_format_patch()中的主循环将再次尝试关闭它,从而产生双释放。最简单的解决方案是不允许使用格式补丁输出,因为没有人打算这样做。然而,我们意外地记录了它(因为格式补丁包括diff选项)。它确实可以使用“gitlog”(man),它将整个输出写入指定的文件。使其适用于格式补丁也很简单:它实际上与--stdout相同,但指向特定的文件。我们可以通过“close_file”标志检测--output选项的使用(请注意,我们不能使用rev.diffopt.file,因为diff设置会将其设置为stdout)。所以我们只需要取消设置该标志,但不必做任何其他操作。另外,我们的情况与--stdout完全相同(请注意,我们没有fclose()文件,但stdout情况也没有;退出程序为我们解决了这一问题)。

假设您在提交1之后有提交id 2,则可以运行:

git diff 2 1 > mypatch.diff

其中2和1是SHA-1散列。

Try:

git format-patch -1 <sha>

or

git format-patch -1 HEAD

根据上面的文档链接,-1标志告诉Git补丁中应该包含多少提交;

-<n>    从最顶层提交准备补丁。


使用以下命令应用修补程序:

git am < file.patch

或者,您也可以应用(应适用于包括Windows在内的所有操作系统):

git apply --verbose file.patch

-v或--verbose将显示失败的内容(如果有的话)。告诉你如何修复。

如果您只想区分指定的文件,可以使用:

git diff master 766eceb--connections/>000-mysql-connector.patch