删除虚假提交父指针

Mec*_*ail 12 git merge git-rebase

我将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.

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

Jos*_*phH 18

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

git replace --edit <sha>
Run Code Online (Sandbox Code Playgroud)

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

一旦你感到高兴,改变是正确的,你可以重写提交以使更改成为永久性的:

git filter-branch --tag-name-filter cat -- <parent sha>..head
Run Code Online (Sandbox Code Playgroud)

或者只重写所涉及的提交而不是完整的历史记录(感谢Michael评论):

git replace --edit <sha>
Run Code Online (Sandbox Code Playgroud)

  • 注意我们可以运行第二个命令为`git filter-branch --tag-name-filter cat - <parent sha> .. head`所以我们只重写所需的提交而不是每次提交.支持的参数在此处记录https://www.kernel.org/pub/software/scm/git/docs/git-rev-list.html (3认同)
  • 谢谢,这是将合并提交(2个父级)重写为常规提交(1个父级)的一种干净方法。在我看来,迈克尔的补充是不重写整个历史,这非常有用。我会建议对答案进行修改 (2认同)

Mec*_*ail 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.
Run Code Online (Sandbox Code Playgroud)

使用提取提交消息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
Run Code Online (Sandbox Code Playgroud)

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

git checkout -b fixed_commit cc32e66
Run Code Online (Sandbox Code Playgroud)

并重新master加入新分支:

git checkout master
git rebase fixed_commit
Run Code Online (Sandbox Code Playgroud)

我们完成了:

成品

您可能希望删除旧分支并重新标记相应的提交.


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