单个 Git 提交如何打成 bundle?

4
我想应用包含提交信息的补丁,如何捆绑单个提交并应用它?
给定示例历史:
0a8b835 intel_pmc_ipc: Add Intel Apollo Lake PMC IPC driver
0d44b41 tc1100-wmi: Delete an unnecessary check before the function call "kfree"
b8830a4 dell-laptop: Fix allocating & freeing SMI buffer page
2ec1e9e target: Bump core version to v5.0
  • 如果我想把0d44b41捆绑成001.bundle并应用它,怎么办?
  • 如果我想把b8830a40d44b41捆绑成002.bundle并应用它,怎么办?

注意:我已经可以使用补丁文件做到这一点,但我也想自动包含提交消息。

我尝试按照git-scm文档上的指示使用以下命令,但失败了:

$ git bundle create 001.bundle 0d44b41^ 0d44b41 
fatal: Refusing to create empty bundle.

...并使用“git am”来应用补丁。 - larsks
2个回答

5
我不确定为什么你特意想要限制使用 git bundle,但假设你确实想要这样做,请注意文档中的这句话:

git-rev-list-args

一个参数列表,可接受 git rev-parsegit rev-list(包含命名引用,请参见下面的指定引用), 指定要传输的特定对象和引用。...

指定引用

git bundle 只会打包由 git show-ref 显示的引用: 这包括头、标签和远程头。

现在考虑你的命令:

$ git bundle create 001.bundle 0d44b41^ 0d44b41

create 001.bundle 指定要创建的文件。您命令行中的其余部分 0d44b41^ 0d44b41git-rev-list-args。您在此处使用了哪个引用(分支或标签名称)?1


请注意,git format-patch 包括提交消息(和作者),使用 git am 将应用包括原始消息(和作者)的提交(尽管您将成为提交者,除非您进行一些额外的设置工作)。

1这是一个修辞问题,当然你没有使用任何引用。我不确定为什么git bundle如此坚持要求一个引用,因为你可以轻松地附加一个原始SHA-1的引用,制作捆绑包,然后再次删除引用,而不会干扰刚创建的捆绑包。这将允许您完成您所尝试的操作。或者,当然,如果有一个指向您想要捆绑的单个提交的名称(分支或标签),则可以直接使用该现有名称。


非常感谢,我之前并不知道 git am 能够满足我的需求,因为我是从这个 stackoverflow 页面中了解到使用 git bundle 来打包提交记录。 - ThorSummoner
2
这就是Git,做任何事情总有至少十种方法,其中六种是错误的,另外三种则非常痛苦。 :-) - torek

0
在 Git 2.31 (Q1 2021) 中, "git bundle"(man) 不会丢失指向相同对象的引用。

请查看提交 5bb0fd2, 提交 ce1d6d9, 提交 9901164 (2021年1月11日) 由Jiang Xin (jiangxin)提交。
(由Junio C Hamano -- gitster --合并于提交 8b48981, 2021年1月25日)

bundle:在删除重复挂起时丢失对象

签名作者:江欣

git rev-list(man) will list one commit for the following command:

$ git rev-list 'main^!'
<tip-commit-of-main-branch>

But providing the same rev-list args to git bundle(man), fail to create a bundle file.

$ git bundle create - 'main^!'
# v2 git bundle
-<OID> <one-line-message>

fatal: Refusing to create empty bundle.

This is because when removing duplicate objects in function object_array_remove_duplicates(), one unique pending object which has the same name is deleted by mistake.

The revision arg 'main^!' in the above example is parsed by handle_revision_arg(), and at lease two different objects will be appended to revs.pending, one points to the parent commit of the "main" branch, and the other points to the tip commit of the "main" branch.
These two objects have the same name "main".
Only one object is left with the name "main" after calling the function object_array_remove_duplicates().

And what's worse, when adding boundary commits into pending list, we use one-line commit message as names, and the arbitrary names may surprise git-bundle.

Only comparing objects themselves (".item") is also not good enough, because user may want to create a bundle with two identical objects but with different reference names, such as: "HEAD" and "refs/heads/main".

Add new function contains_object() which compare both the address and the name of the object.


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接