【问题标题】:git cherry-pick a diff between commits without common history?git cherry-pick 没有共同历史的提交之间的差异?
【发布时间】:2016-02-01 05:20:14
【问题描述】:

场景:具有完全断开的历史片段的存储库。例如。来自没有共同 git 历史的不同遥控器。 (这通常发生在使用 git subtree 的场景中。)

是否可以挑选这两个提交之间的差异,即使它们没有共同的历史? (并且活动提交与这两者中的任何一个都没有共同的历史)

我试过这个(进入带有-X subtree=sub/dir 选项的子目录):

git cherry-pick -X subtree=vendor/package aaa/aaa..bbb/bbb

如果没有子树,这会更简单:

git cherry-pick aaa/aaa..bbb/bbb

其中 aaa/aaa 和 bbb/bbb 是两个具有断开历史记录的提交。

不幸的是,这不起作用:aaa/aaa..bbb/bbb 不被读取为差异,而是其他内容。

git show aaa/aaa..bbb/bbb 可以显示相同的内容,这与git diff aaa/aaa bbb/bbb 完全不同。例如。如果两者有相同的文件,则 git diff 将为空,但 git show a..b 将只显示 b,而不显示 a。


注意:我的个人用例是子树背景。我提到这一点是为了避免人为的用例,人们通常会开始辩论用例的有效性而不是实际问题。

理想的答案将首先解决一般情况,然后解决子树情况。

【问题讨论】:

    标签: git git-cherry-pick


    【解决方案1】:

    @VonC 指出了一个好的方向。对此想法的赞誉和 +1。

    创建补丁并应用它会更简单:

    然而,这可以用一个简单的单线来完成(我试过这个,它对我有用):

    git diff aaa/aaa bbb/bbb | git apply --directory=vendor/package
    

    或者在非子树场景中:

    git diff aaa/aaa bbb/bbb | git apply
    

    无需 git checkout、git cherry-pick 或创建本地文件。
    然后你仍然需要提交这些东西,很明显..

    这里是如何在不添加和/或获取任何子树遥控器的情况下做到这一点。相反,您可以将包存储库克隆到主项目存储库外部的单独目录中。

    git --git-dir="/path/to/package/repo/.git" diff aaa bbb | git apply --directory=vendor/package
    

    按照我的理解,这仍然与通常的git subtree 工作流程大致相同。我的意思是,主项目的 git 历史将是相同的。如果我错了,请纠正我。

    【讨论】:

    • 当然,git diff 可能更直接(我在 diff 和cherry-pick 之间犹豫不决)。 +1
    【解决方案2】:

    由于cherry-picking应用差异,create a patch and apply it会更简单:

    git checkout aaa/aaa
    git cherry-pick -n bbb/bbb
    git diff --cached > my.patch
    

    然后检查您的常规分支和git apply my.patch

    这需要提交“bbb/bbb”,将其与其直接祖先进行比较,然后将该差异应用于“aaa/aaa”之上:可能会发生冲突。
    测试-X subtree=vendor/package 在子树的情况下是否有帮助。

    【讨论】:

    • git apply 是个好主意!但我不确定你的命令是否符合承诺。
    • 我看到的樱桃选择问题是它只会选择最后一次提交,而不是从 aaa/aaa 到 bbb/bbb 的整个提交范围(实际上并不存在 - 这是点)。
    猜你喜欢
    • 2017-07-23
    • 2016-01-08
    • 1970-01-01
    • 2017-05-31
    • 2012-11-05
    • 2021-01-18
    • 2018-04-17
    • 2012-05-21
    • 2016-10-24
    相关资源
    最近更新 更多