如何在旧的git提交中添加其他父项?

Quu*_*one 13 git git-rewrite-history

我有一个包含两个分支的项目:master和gh-pages.它们本质上是两个不同的项目,其中gh-pages项目依赖于主项目(反之亦然).可以把它想象成"master包含源代码,gh-pages包含从这些源文件构建的二进制文件".我定期地接受在master中累积的更改,并使用提交消息"与主提交xxxxxxxx一致"对gh-pages分支进行新提交.

网络图形当前的外观

经过一段时间的这样做,我意识到,如果gh-pages提交"与主提交xxxxxxxx一致"实际上将xxxxxxxx作为其git存储库中的父项,那将会很好.像这样(糟糕的MSPaint艺术):

理想的外观

有没有办法让存储库看起来像上面的第二个图像?我知道如何使新的提交遵循这种模式:我可以做"git merge -s our master"(设置其他空提交的父项),然后是"git commit --amend adv550.z8"(其中adv550.z8)是实际正在改变的二进制文件).但git是否可以让您轻松回过头来为旧提交添加新父母?

一旦我让我的本地回购看起来正确,我完全愿意"git push -f"并且吹走我的Github存储库的当前历史.现在的问题是,可以让我的本地回购找吧?


编辑年后再添加:我最终放弃了尝试使git历史gh-pages看起来像这样的尝试; 我认为零收益太过分了.我的新做法是积极地压缩提交gh-pages,因为在我的情况下保存这些提交消息并不重要.(这只是"与主提交相符......"的长线,其中没有一个在历史上很有意思.)但是,如果我需要再次这样做,我会听到所说的答案

git merge $intended_parent_1 $intended_parent_2
git checkout $original_commit -- .
git commit --amend -a -C $original_commit
Run Code Online (Sandbox Code Playgroud)

rum*_*pel 7

git replace --graft $original_commit \
    $(git show --pretty=%P $original_commit) \
    $additional_parent
Run Code Online (Sandbox Code Playgroud)

说明: git replace --graft允许重新指定哪个是给定提交的父级.这通过编写具有相应更改的新提交并编写替换引用来工作,该替换引用使git在访问时查找新提交而不是原始提交.

git show --pretty=%P $original_commit 只列出原来的父母.

  • 这是[几乎]正确的答案。差不多,因为我不得不使用`git show --pretty=%P $original_commit | head -n1` — 我的 git (2.11.1) 输出的不仅仅是父行。 (3认同)
  • 请注意,通过这种方式添加的家长不会出现在 Github 上 (2认同)

krl*_*mlr 5

这些是你的神奇话语:

git merge origin/master --strategy ours
Run Code Online (Sandbox Code Playgroud)

gh-pages分支中执行此操作以记录关系,master而不实际更改任何内容.当我创建gh-pages分支时,这对我有用--orphan,就像在这个答案中一样.

之后您甚至可以进行--amend此空合并提交,以便将您实际想要进行的更改引入"页面".有关GitHub的实际示例,请参阅https://github.com/krlmlr/pdlyr/network.

  • 现在需要一个 `--allow-unrelated-histories` 标志才能工作,因为自 Git 2.9 以来 git 不再允许默认合并不相关的历史记录 (2认同)

ell*_*eth 3

您无法回到过去并更改现有的提交。即使你做了类似的事情git commit --amend,你实际上并没有改变提交;您将在树中的同一位置创建一个新内容,其中包含原始内容(加上您的更改)的所有内容。您会注意到,提交哈希值在 后发生了变化--amend,并且原始哈希值仍然存在于您的存储库中——您可以使用 来返回它git reflog

另一方面,你可以回到过去并创建另一个宇宙。本质上,您将返回到gh-pages分支点并将整个事物(例如git cherry-pick或其他事物)重新创建为并行分支。哈希值会改变,因为提交是不同的对象。

(我很好奇为什么你将存储库设置为单独的分支,而不是同一分支中的单独目录。似乎代码 - >构建过程会变得乏味。)

  • 提交哈希涵盖了与该提交有关的所有内容。内容、家长参考、评论、日期/时间。如果更改提交中的一位,将会生成一个新的哈希值。 (3认同)