Git 删除提交';,从而使其成为初始提交

Git 删除提交';,从而使其成为初始提交,git,commit,git-commit,git-rewrite-history,git-plumbing,Git,Commit,Git Commit,Git Rewrite History,Git Plumbing,注意:我知道这是在重写历史,会改变所有的散列,并且会把其他人搞得一团糟 我要进行一次提交,并删除其父级。具体来说,提交现在应该看起来像初始提交。这意味着它的差异将改变;在历史上的那个时刻,所有文件看起来都是由该提交创建的 如何做到这一点?(当然,我可以编辑提交对象,但是提交不会指向彼此。)此外,我想在一个新分支上执行此操作(这意味着现在有两个历史记录:原始历史记录和提交为初始提交的历史记录。)git rebase-I HEAD~ 然后,在上面的终端cmd后弹出的编辑器中,将子提交行的开头从pi

注意:我知道这是在重写历史,会改变所有的散列,并且会把其他人搞得一团糟


我要进行一次提交,并删除其父级。具体来说,提交现在应该看起来像初始提交。这意味着它的差异将改变;在历史上的那个时刻,所有文件看起来都是由该提交创建的

如何做到这一点?(当然,我可以编辑提交对象,但是提交不会指向彼此。)此外,我想在一个新分支上执行此操作(这意味着现在有两个历史记录:原始历史记录和提交为初始提交的历史记录。)

git rebase-I HEAD~

然后,在上面的终端cmd后弹出的编辑器中,将子提交行的开头从pick更改为squash。或分别为“p”和“s”。写入文件并退出根据上述命令显示的编辑器

编辑:假设两次提交是最新的。如果没有,那么您可以检查孩子的子提交散列并使用git-rebase-i HEAD~2


Edit2:或者您可以只git rebase-i parentcommithash,列表的顶部应该是父级

假设您希望新的初始提交是
123456

git checkout -b new_master
git filter-branch --commit-filter '
  if git merge-base --is-ancestor 123456 $GIT_COMMIT ;
  then
   git commit-tree "$@";
  else
   skip_commit "$@";
  fi' HEAD
Todo(适用于任何人):在解释中编辑

git checkout -b newbranch
git rev-parse @ >.git/info/grafts   # any equivalent for @ will work e.g. HEAD or newbranch
git filter-branch
rm .git/info/grafts

(编辑:添加了
rm
。如果没有它,此repo仍将反映原始提交的嫁接祖先)

如果您想完全断开提交与其父级的连接,并且没有历史记录,为什么不复制所有文件并创建一个新的repo?@EdCottrell,因为我希望它的子代/后代能够存活下来。因此,我不能百分之百肯定这会有帮助——我是一个善变的人,而不是一个git人——但请澄清一下——你想让你选择的提交成为根(在“之前”失去一切)?另外,关于如何使用git replace来隐藏历史记录,如果您的动机是不特别关心较旧的提交,也不希望它们扰乱工具的输出感谢您添加了
rm
,那么在重写提交后查看历史记录,我会感到困惑:)