16

我将 Bazaar 存储库导入 Git(使用git bzr),但生成的存储库包含一个虚假的提交父链接:

虚假父链接

请注意,标记的提交1.02-6基于1.02-3提交,但1.02-1也不必要地标记为父级。(注意:这部分 repo 中的所有提交都被标记;显示的提交之间没有提交。)

我尝试过以多种方式(在master分支上:git rebase 1.02-3, git rebase -i upstream-1.02, git rebase --onto 1.02-1 1.02-3, git rebase --root upstream-1.02 --onto=other_branch)进行变基,但在每种情况下,它都会因合并冲突而失败。这些似乎超出了必要的尝试;历史是正确的,除了一个额外的父指针被记录在提交标记1.02-6中。

您如何删除链接以使历史线性化?有没有比手动按顺序挑选所有提交更好的方法?

4

4 回答 4

20

最简单的方法(在 git >= 1.6.5 中)是使用:

git replace --edit <sha>

并删除/添加/更改 Parent: 行。

一旦您对更改正确感到满意,您就可以重写提交以使更改永久化:

git filter-branch --tag-name-filter cat -- --all

在某些情况下,只重写所涉及的提交而不是完整的历史记录会明显更快(感谢Michael在评论中提到这一点);例如仅重写当前分支上的提交:

git filter-branch --tag-name-filter cat -- <new parent sha>..head

如果您不确定,请使用--all,否则您可能会遇到仍然引用临时替换对象的其他分支/标签。

于 2016-05-03T10:14:42.263 回答
5

您可以使用git commit-tree内部命令手动执行此操作。

我们要编辑标记的提交1.02-6以删除虚假的父指针 (to 56a2f3b5948ab54c9239c2b384a6ea9eb1f410c4)。

首先,从现有的提交对象中读取信息:

user@host:/path/repo.git$ git cat-file -p 1.02-6 
tree c658aa1ebcf2bf2a607696c7868b875be72fb01f
parent 56a2f3b5948ab54c9239c2b384a6ea9eb1f410c4
parent 4e671bf1d2298729c9e5cfd8229051cfe2c40831
author James Damour (Suvarov454) <suvarov454@users.sourceforge.net> 1146319620 -0400
committer Bazaar Package Importer <james.westby@ubuntu.com> 1146319620 -0400

The "main/" in the Section line of debian/control should be assumed.

使用 提取提交消息git log --format=%B -n 1 1.02-6

现在创建一个具有相同内容的新提交(不包括虚假的父链接和提交者信息):

git log --format=%B -n 1 1.02-6 | \
    GIT_AUTHOR_NAME="James Damour (Suvarov454)" \
    GIT_AUTHOR_EMAIL="suvarov454@users.sourceforge.net" \
    GIT_AUTHOR_DATE="1146319620 -0400" \
    git commit-tree c658aa1ebcf2bf2a607696c7868b875be72fb01f \
        -p 4e671bf1d2298729c9e5cfd8229051cfe2c40831

这创建了一个新的提交,并打印了它的哈希(cc32e66...)。现在把它变成一个新的分支:

git checkout -b fixed_commit cc32e66

并重新定位master到新分支:

git checkout master
git rebase fixed_commit

我们完成了:

完成的

您可能想要删除旧分支并重新标记适当的提交。


实际上它可能更容易使用git filter-branch --parent-filter。我没试过。

于 2013-01-11T23:26:38.497 回答
2

这将在不更改任何其他内容的情况下纠正父母(例如提交者日期):

git filter-branch --tag-name-filter cat --parent-filter 'test $GIT_COMMIT = [sha of 1.02-6] && echo "-p [sha of 1.02-3]" || cat' -- 1.02-1..master

您必须用适当的提交 ID 替换括号中的文本。如果您有更多的下游分支需要重写,请更改1.02-1..master--all准备等待。

当然,如果其他人从您要编辑的提交之后的任何提交分支,请不要使用此解决方案或任何其他解决方案。他们会恨你的。

于 2014-12-29T01:55:23.277 回答
1

你可以试试rebase。有一个示例(搜索--onto)我认为与您的情况类似。

认为你需要做

git rebase --onto 1.02-1 1.02-3

这应该将 1.02-3 之后的所有内容放到 1.02-1 上,这可能就是您想要的。

请记住,与第一次更改的提交相比,所有内容的哈希值都会有所不同,但我假设您这样做是从 bzr 迁移的第一步,因此没有其他人应该克隆它。

于 2013-01-09T20:06:30.787 回答