19

我有一个包含两个分支的项目:master 和 gh-pages。它们本质上是两个不同的项目,其中 gh-pages 项目依赖于主项目(反之亦然)。将其视为“master 包含源代码,gh-pages 包含从这些源文件构建的二进制文件”。定期地,我采用 master 中累积的更改,并使用提交消息“与 master commit xxxxxxxx 保持一致”对 gh-pages 分支进行新的提交。

网络图当前的样子

这样做一段时间后,我意识到如果 gh-pages 提交“与主提交 xxxxxxxx 保持一致”实际上在 git 存储库中将 xxxxxxxx 作为其父级,那就太好了。像这样(糟糕的 MSPaint 艺术):

理想的样子

有没有办法让存储库看起来像上面的第二张图片?我知道如何按照这种模式进行新提交:我可以执行“git merge -s ours 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
4

5 回答 5

17
git replace --graft $original_commit \
    $(git show --pretty=%P $original_commit) \
    $additional_parent

说明: git replace --graft允许重新指定给定提交的父级。这是通过编写一个带有相应更改的新提交并编写一个替换引用来实现的,这会导致 git 在访问时查找新提交而不是原始提交。

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

于 2016-12-20T13:37:51.013 回答
8

这些是你的魔法词:

git merge origin/master --strategy ours

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

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

于 2015-04-11T17:48:25.873 回答
2

您无法及时返回并更改现有提交。即使你做了类似的事情git commit --amend,你实际上并没有改变提交;您正在树中的同一位置创建一个新的,其中包含原始内容的所有内容(加上您的更改)。您会注意到提交哈希--amendgit reflog.

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

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

于 2012-05-30T01:07:04.910 回答
1

@rumpel 给出了正确的答案。请允许我分享我使用的片段。

首先,我创建了孤儿master分支:

git checkout --orphan master
git commit --allow-empty -m 'Init'

我的用例略有不同,我想要的站点位于分支_site目录中。develop因此我这样做:

git checkout master
git rm -rf .
git read-tree develop^{tree}:_site
git checkout -- .
git commit -m "Update from develop SHA1:$(git rev-parse --short develop) ($(git log -1 --format=%cd develop))"
git replace --graft @ $(git show --pretty=%P @ | head -n1) develop

请注意,在最后一个命令中,我必须过滤,| head -n1因为我的git输出不仅仅是父母。

于 2017-02-13T01:11:47.363 回答
0

您可以重写提交,但它需要从需要额外父级的第一个提交开始重写整个分支,直到分支提示。是(就像变基一样)一个新的分支,它只是具有相同的内容。

诀窍是使用提交树,它获取所有内容(提交者/作者信息、时间戳、提交消息、父列表),尽管以一种相当不切实际的方式。一点脚本就可以完成这项工作。

于 2014-02-25T16:00:25.697 回答