如何为特定提交生成 Git 补丁?

发布于 2024-11-19 19:25:18 字数 173 浏览 1 评论 0原文

我想为特定提交哈希 创建补丁。

我尝试使用 git format-patch,但这会为自 提交以来的每次提交生成补丁。有没有办法只为 生成补丁?

I want to create a patch for a specific commit hash, <rev>.

I tried using git format-patch <rev>, but that generated a patch for each commit since the <rev> commit. Is there a way to generate a patch only for <rev>?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

高跟鞋的旋律 2024-11-26 19:25:19

尝试:

git format-patch -<n> <rev>

例如:

git format-patch -1 HEAD

-1 标志指示补丁中应包含多少次提交:

-

   
从最上面的开始准备补丁提交。


使用以下命令应用补丁:

git am < file.patch

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

git apply --verbose file.patch

-v--verbose 将显示失败的内容,如果任何。为您提供有关如何修复的线索。

Try:

git format-patch -<n> <rev>

For example:

git format-patch -1 HEAD

The -1 flag indicates how many commits should be included in the patch:

-<n>

Prepare patches from the topmost <n> commits.


Apply the patch with the command:

git am < file.patch

Alternatively you can also apply (should work on all OSes including Windows) with:

git apply --verbose file.patch

The -v or --verbose will show what failed, if any. Giving you a clue on how to fix.

亽野灬性zι浪 2024-11-26 19:25:19

用于从最上面的生成补丁。从特定 SHA-1 哈希提交:

git format-patch -<n> <SHA-1> --stdout > <name_of_patch_file>.patch

单个补丁文件中头部的最后 10 个补丁:

git format-patch -10 HEAD --stdout > 0001-last-10-commits.patch

For generating the patches from the topmost <n> commits from a specific SHA-1 hash:

git format-patch -<n> <SHA-1> --stdout > <name_of_patch_file>.patch

The last 10 patches from head in a single patch files:

git format-patch -10 HEAD --stdout > 0001-last-10-commits.patch
抽个烟儿 2024-11-26 19:25:19

假设您在提交 1 之后提交了提交 id 2,您将能够运行:

git diff 2 1 > mypatch.diff

其中 2 和 1 是 SHA-1 哈希值。

Say you have commit id 2 after commit 1 you would be able to run:

git diff 2 1 > mypatch.diff

where 2 and 1 are SHA-1 hashes.

叹梦 2024-11-26 19:25:19

此命令(正如 @Naftuli Tzvi Kay 已经建议的那样),

git format-patch -1 HEAD

HEAD 替换为特定的哈希或范围。

将生成最新提交的补丁文件,格式类似于 Unix 邮箱格式。

- - 从最上面的开始准备补丁提交。

然后,您可以通过以下方式重新应用邮箱格式的补丁文件:

git am -3k 001*.patch

请参阅: man git-format-patch

This command (as suggested already by @Naftuli Tzvi Kay),

git format-patch -1 HEAD

Replace HEAD with a specific hash or range.

will generate the patch file for the latest commit formatted to resemble the Unix mailbox format.

-<n> - Prepare patches from the topmost <n> commits.

Then you can reapply the patch file in a mailbox format by:

git am -3k 001*.patch

See: man git-format-patch.

森林散布 2024-11-26 19:25:19
git format-patch commit_Id~1..commit_Id  
git apply patch-file-name

快速而简单的解决方案。

git format-patch commit_Id~1..commit_Id  
git apply patch-file-name

Fast and simple solution.

谎言 2024-11-26 19:25:19

如果您想确保(单个提交)补丁将应用于特定提交之上,您可以使用新的 git 2.9(2016 年 6 月)选项 git format-patch --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

请参阅 < a href="https://github.com/git/git/commit/bb52995f3ec7fac2b282a91af4230e4f387af234" rel="noreferrer">提交 bb52995,提交 3de6651提交 fa2ab86, 提交 ded2c09(2016 年 4 月 26 日),作者:叶小龙(``)
(由 Junio C Hamano -- gitster -- 合并于 提交72ce3ff,2016 年 5 月 23 日)

format-patch:添加'--base'选项来记录基本树信息

维护人员或第三方测试人员可能想知道确切的基础树
该补丁系列适用于。教 git format-patch 一个 '--base' 选项
记录基本树信息并将其附加在第一个树的末尾
消息(求职信或该系列中的第一个补丁)。

基础树信息由“基础提交”组成,这是众所周知的
提交是项目历史稳定部分的一部分
else 可以工作于零个或多个“先决补丁”,它们是
正在运行的知名补丁尚未成为“基础提交”的一部分
需要按拓扑顺序应用在“基本提交”之上
在应用补丁之前。

“基本提交”显示为“base-commit:”,后跟 40 进制
提交对象名称。
“先决条件补丁”显示为“precession-patch-id:”,后跟 40 十六进制“补丁 ID”,可以通过将补丁传递给“git patch”来获取-id --stable”命令。


Git 2.23(2019 年第 3 季度)将改进这一点,因为“format-patch”的“--base”选项计算了 patch-ids以不稳定的方式获取必备补丁,已更新为以与“git patch-id --stable”兼容的方式进行计算。

请参阅提交a8f6855提交 6f93d26(2019 年 4 月 26 日),作者:斯蒂芬·博伊德(akshayka
(由 Junio C Hamano -- gitster -- 合并于 提交8202d12,2019 年 6 月 13 日)

format-patch:使--base patch-id输出稳定

每次我们处理一个块时,我们并没有刷新上下文
patch-id 生成代码在 diff.c 中,但是当我们这样做时
使用“patch-id”工具生成“稳定”patch-id。

让我们将类似的逻辑从 patch-id.c 移植到 diff.c 中,这样我们在为 ' 生成 patch-ids 时就可以获得相同的哈希值format-patch --base=' 命令调用类型。


在 Git 2.24(2019 年第 4 季度)之前,“git format-patch -o” 相当于“mkdir”,而不是“” mkdir -p”,正在更正。

请参阅 提交 edefc31(2019 年 10 月 11 日),作者:伯特·韦萨尔格(bertwesarg
(由 Junio C Hamano -- gitster -- 合并于 提交f1afbb0,2019 年 10 月 18 日)

format-patch:创建输出的前导组件目录

签署人:Bert Wesarg

'git format-patch -o ' 相当于 'mkdir' 而不是 'mkdir -p',后者正在已更正。

避免在主要目录上使用“adjust_shared_perm”,这可能会产生安全隐患。通过像“git init”一样暂时禁用“config.sharedRepository”来实现。


在 Git 2.25(2020 年第 1 季度)中,设置 format.useAutoBase 配置变量时“git rebase”无法正常工作,该问题已得到纠正。

请参阅提交cae0bc0提交 945dc55, 提交 700e006, 提交 a749d01, 提交 0c47e06(2019 年 12 月 4 日),作者:刘丹顿(Denton-L
(由 Junio C Hamano -- gitster -- 合并于 提交71a7de7,2019 年 12 月 16 日)

rebase:修复format.useAutoBase破损

报告人:Christian Biesinger
签字人:刘丹顿

使用 format.useAutoBase = true,运行 rebase 会导致错误:

fatal: 无法到达上游,如果你想自动记录基本提交,
请使用 gitbranch --set-upstream-to 来跟踪远程分支。
或者您可以通过 --base= 指定基本提交手动
错误:
git 在准备重播补丁时遇到错误
这些修订:

ede2467cdedc63784887b587a61c36b7850ebfac..d8f581194799ae29bf5fa72a98cbae98a1198b12

因此,git 无法对它们进行 rebase。

通过始终从 rebase 传递 --no-base 到 format-patch 来修复此问题,从而消除 format.useAutoBase 的效果。


使用 Git 2.29(2020 年第 4 季度),“git格式补丁(man ) 学习将“whenAble”作为 format.useAutoBase 配置变量的可能值,以便在自动计算的基数没有意义时变为无操作。

请参阅 提交 7efba5f(2020 年 10 月 1 日),作者:雅各布·凯勒(雅各布-凯勒
(由 Junio C Hamano -- gitster -- 合并于 提交5f8c70a,2020 年 10 月 5 日)

format-patch:教授格式.useAutoBasewhenAble”选项

签字人:雅各布·凯勒

format.useAutoBase 配置选项允许用户默认为 format-patch 启用“--base=auto”。

这有时会导致工作流程不佳,因为尝试格式化旧补丁时会出现意外失败:

$ git format-patch -1 <旧提交>;
致命:基本提交不应出现在修订列表中  

这可能非常令人困惑,因为用户请求 --base 不一定立即显而易见(因为这是在配置中,而不是在命令行中)。

我们确实希望 --base=auto 在无法提供合适的基础时失败,因为如果格式化补丁在请求时不包含基础信息,也会同样令人困惑。< /p>

教授format.useAutoBase新模式“whenAble”。

此模式将导致格式补丁尝试在可能的情况下包含基本提交。但是,如果找不到有效的基本提交,则 format-patch 将在没有基本提交的情况下继续格式化补丁。

为了避免使另一个分支名称无法与 --base 一起使用,请勿教导 --base=whenAble--base=whenable< /代码>.

相反,重构 base_commit 选项以使用回调,并依赖全局配置变量 auto_base

这确实意味着用户无法从命令行请求生成此可选的基本提交。然而,这可能不太有价值。如果用户手动请求基本信息,他们将立即被告知无法获取合适的基本提交。这允许用户就是否继续该格式做出明智的选择。

添加测试以涵盖 --base 的新操作模式。

git config 现在包含在其

默认情况下

格式补丁
也可以设置为“whenAble”以允许
如果有合适的基础,则启用 --base=auto,但要跳过
添加基本​​信息,否则格式不会消失。


对于 Git 2.30(2021 年第一季度),“git格式补丁--output=there"(man) 没有按预期工作,而是崩溃了。

现在支持该选项。

请参阅提交dc1672d提交 1e1693b, 提交 4c6f781(2020 年 11 月 4 日),作者:杰夫·金(peff
(由 Junio C Hamano -- gitster -- 合并于 提交5edc8bd,2020 年 11 月 18 日)

format-patch:支持 --output 选项

报告人:Johannes Postler
签字人:杰夫·金

我们从未打算在 format-patch 中支持 diff 的 --output 选项。
直到 baa4adc66a (解析选项:使用 PARSE_OPT_KEEP_UNKNOWN 禁用选项缩写, 2019-01-27,Git v2.22.0-rc0),无法触发。我们首先解析格式补丁选项,然后将剩余部分交给 setup_revisions()
在提交之前,我们接受“--output=foo”作为“--output-directory=foo”的缩写。但之后,我们不检查缩写,并且 --output 被传递到 diff 代码。

这会导致无意义的行为和错误。 diff 代码将在 rev.diffopt.file 打开一个文件句柄,但我们将使用我们为每个单独的补丁文件打开的自己的句柄覆盖它。因此 --output 文件将始终为空。
但更糟糕的是,diff 代码还设置了 rev.diffopt.close_file,因此 log_tree_commit() 将关闭文件句柄本身。然后cmd_format_patch()中的主循环将尝试再次关闭它,导致双重释放。

最简单的解决方案是禁止 --output 与 format-patch 一起使用,因为没有人希望它起作用。然而,我们不小心记录了它(因为格式补丁包含差异选项)。它确实适用于“git log "(man) ,它将整个输出写入指定的文件。使其适用于格式补丁也很容易:它实际上与 --stdout 相同,但指向特定文件。

我们可以通过 "close_file" 标志检测 --output 选项的使用(请注意,我们不能使用 rev.diffopt.file,因为 diff 设置会将其设置为标准输出)。所以我们只需要取消设置该标志,而不必执行任何其他操作。我们的情况在其他方面与 --stdout 完全相同(请注意,我们不会 fclose() 文件,但 stdout 情况也不会;退出程序会为我们解决这个问题)。

If you want to be sure the (single commit) patch will be applied on top of a specific commit, you can use the new git 2.9 (June 2016) option git format-patch --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

See commit bb52995, commit 3de6651, commit fa2ab86, commit ded2c09 (26 Apr 2016) by Xiaolong Ye (``).
(Merged by Junio C Hamano -- gitster -- in commit 72ce3ff, 23 May 2016)

format-patch: add '--base' option to record base tree info

Maintainers or third party testers may want to know the exact base tree
the patch series applies to. Teach git format-patch a '--base' option
to record the base tree info and append it at the end of the first
message (either the cover letter or the first patch in the series).

The base tree info consists of the "base commit", which is a well-known
commit that is part of the stable part of the project history everybody
else works off of, and zero or more "prerequisite patches", which are
well-known patches in flight that is not yet part of the "base commit"
that need to be applied on top of "base commit" in topological order
before the patches can be applied.

The "base commit" is shown as "base-commit: " followed by the 40-hex of
the commit object name.
A "prerequisite patch" is shown as "prerequisite-patch-id: " followed by the 40-hex "patch id", which can be obtained by passing the patch through the "git patch-id --stable" command.


Git 2.23 (Q3 2019) will improve that, because the "--base" option of "format-patch" computed the patch-ids for prerequisite patches in an unstable way, which has been updated to compute in a way that is compatible with "git patch-id --stable".

See commit a8f6855, commit 6f93d26 (26 Apr 2019) by Stephen Boyd (akshayka).
(Merged by Junio C Hamano -- gitster -- in commit 8202d12, 13 Jun 2019)

format-patch: make --base patch-id output stable

We weren't flushing the context each time we processed a hunk in the
patch-id generation code in diff.c, but we were doing that when we
generated "stable" patch-ids with the 'patch-id' tool.

Let's port that similar logic over from patch-id.c into diff.c so we can get the same hash when we're generating patch-ids for 'format-patch --base=' types of command invocations.


Before Git 2.24 (Q4 2019), "git format-patch -o <outdir>" did an equivalent of "mkdir <outdir>" not "mkdir -p <outdir>", which is being corrected.

See commit edefc31 (11 Oct 2019) by Bert Wesarg (bertwesarg).
(Merged by Junio C Hamano -- gitster -- in commit f1afbb0, 18 Oct 2019)

format-patch: create leading components of output directory

Signed-off-by: Bert Wesarg

'git format-patch -o ' did an equivalent of 'mkdir <outdir>' not 'mkdir -p <outdir>', which is being corrected.

Avoid the usage of 'adjust_shared_perm' on the leading directories which may have security implications. Achieved by temporarily disabling of 'config.sharedRepository' like 'git init' does.


With Git 2.25 (Q1 2020), "git rebase" did not work well when format.useAutoBase configuration variable is set, which has been corrected.

See commit cae0bc0, commit 945dc55, commit 700e006, commit a749d01, commit 0c47e06 (04 Dec 2019) by Denton Liu (Denton-L).
(Merged by Junio C Hamano -- gitster -- in commit 71a7de7, 16 Dec 2019)

rebase: fix format.useAutoBase breakage

Reported-by: Christian Biesinger
Signed-off-by: Denton Liu

With format.useAutoBase = true, running rebase resulted in an error:

fatal: failed to get upstream, if you want to record base commit automatically,
please use git branch --set-upstream-to to track a remote branch.
Or you could specify base commit by --base=<base-commit-id> manually
error:
git encountered an error while preparing the patches to replay
these revisions:

ede2467cdedc63784887b587a61c36b7850ebfac..d8f581194799ae29bf5fa72a98cbae98a1198b12

As a result, git cannot rebase them.

Fix this by always passing --no-base to format-patch from rebase so that the effect of format.useAutoBase is negated.


With Git 2.29 (Q4 2020), "git format-patch"(man) learns to take "whenAble" as a possible value for the format.useAutoBase configuration variable to become no-op when the automatically computed base does not make sense.

See commit 7efba5f (01 Oct 2020) by Jacob Keller (jacob-keller).
(Merged by Junio C Hamano -- gitster -- in commit 5f8c70a, 05 Oct 2020)

format-patch: teach format.useAutoBase "whenAble" option

Signed-off-by: Jacob Keller

The format.useAutoBase configuration option exists to allow users to enable '--base=auto' for format-patch by default.

This can sometimes lead to poor workflow, due to unexpected failures when attempting to format an ancient patch:

$ git format-patch -1 <an old commit>
fatal: base commit shouldn't be in revision list  

This can be very confusing, as it is not necessarily immediately obvious that the user requested a --base (since this was in the configuration, not on the command line).

We do want --base=auto to fail when it cannot provide a suitable base, as it would be equally confusing if a formatted patch did not include the base information when it was requested.

Teach format.useAutoBase a new mode, "whenAble".

This mode will cause format-patch to attempt to include a base commit when it can. However, if no valid base commit can be found, then format-patch will continue formatting the patch without a base commit.

In order to avoid making yet another branch name unusable with --base, do not teach --base=whenAble or --base=whenable.

Instead, refactor the base_commit option to use a callback, and rely on the global configuration variable auto_base.

This does mean that a user cannot request this optional base commit generation from the command line. However, this is likely not too valuable. If the user requests base information manually, they will be immediately informed of the failure to acquire a suitable base commit. This allows the user to make an informed choice about whether to continue the format.

Add tests to cover the new mode of operation for --base.

git config now includes in its man page:

format-patch by default.
Can also be set to "whenAble" to allow
enabling --base=auto if a suitable base is available, but to skip
adding base info otherwise without the format dying.


With Git 2.30 (Q1 2021), "git format-patch --output=there"(man) did not work as expected and instead crashed.

The option is now supported.

See commit dc1672d, commit 1e1693b, commit 4c6f781 (04 Nov 2020) by Jeff King (peff).
(Merged by Junio C Hamano -- gitster -- in commit 5edc8bd, 18 Nov 2020)

format-patch: support --output option

Reported-by: Johannes Postler
Signed-off-by: Jeff King

We've never intended to support diff's --output option in format-patch.
And until baa4adc66a (parse-options: disable option abbreviation with PARSE_OPT_KEEP_UNKNOWN, 2019-01-27, Git v2.22.0-rc0), it was impossible to trigger. We first parse the format-patch options before handing the remainder off to setup_revisions().
Before that commit, we'd accept "--output=foo" as an abbreviation for "--output-directory=foo". But afterwards, we don't check abbreviations, and --output gets passed to the diff code.

This results in nonsense behavior and bugs. The diff code will have opened a filehandle at rev.diffopt.file, but we'll overwrite that with our own handles that we open for each individual patch file. So the --output file will always just be empty.
But worse, the diff code also sets rev.diffopt.close_file, so log_tree_commit() will close the filehandle itself. And then the main loop in cmd_format_patch() will try to close it again, resulting in a double-free.

The simplest solution would be to just disallow --output with format-patch, as nobody ever intended it to work. However, we have accidentally documented it (because format-patch includes diff-options). And it does work with "git log"(man) , which writes the whole output to the specified file. It's easy enough to make that work for format-patch, too: it's really the same as --stdout, but pointed at a specific file.

We can detect the use of the --output option by the "close_file" flag (note that we can't use rev.diffopt.file, since the diff setup will otherwise set it to stdout). So we just need to unset that flag, but don't have to do anything else. Our situation is otherwise exactly like --stdout (note that we don't fclose() the file, but nor does the stdout case; exiting the program takes care of that for us).

烟凡古楼 2024-11-26 19:25:19

使用 commit-id 创建 git 补丁

$ git format-patch -1 commit-id

此命令创建具有以下文件名的补丁

0001-commit-message.patch

要应用补丁:

$ git am 0001-commit-message.patch

Create a git patch using commit-id

$ git format-patch -1 commit-id

This command create patch with following file name

0001-commit-message.patch

To apply the patch:

$ git am 0001-commit-message.patch
你穿错了嫁妆 2024-11-26 19:25:19

要从特定提交(不是最后一次提交)生成补丁:

git format-patch -M -C COMMIT_VALUE~1..COMMIT_VALUE

To generate a patch from a specific commit (not the last commit):

git format-patch -M -C COMMIT_VALUE~1..COMMIT_VALUE
梦境 2024-11-26 19:25:19

凭借我的 Mercurial 背景,我将使用:

git log --patch -1 $ID > $file

但我正在考虑使用 git 格式-patch -1 $ID 现在。

With my Mercurial background I was going to use:

git log --patch -1 $ID > $file

But I am considering using git format-patch -1 $ID now.

平安喜乐 2024-11-26 19:25:19

如果你只想比较指定的文件,你可以使用:

git diff master 766eceb -- 连接/ > 000-mysql-connector.补丁

If you just want diff the specified file, you can use:

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

哽咽笑 2024-11-26 19:25:19

仅针对特定 SHA-1 值生成补丁的方法是什么?

这很简单:

选项 1. git show commitID > myFile.patch

选项 2. git commitID~1..commitID > myFile.patch

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

What is the way to generate a patch only for the specific SHA-1 value?

It's quite simple:

Option 1. git show commitID > myFile.patch

Option 2. git commitID~1..commitID > myFile.patch

Note: Replace commitID with the actual commit id (SHA-1 commit code).

一绘本一梦想 2024-11-26 19:25:19

我也在为同样的问题而苦苦挣扎。

这是我发现的

git format-patch -1 -s <commit-id>

I was also struggling with the same question.

Here is what I found out

git format-patch -1 -s <commit-id>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文