【问题标题】:Remove a commit's parent, thereby making it the initial commit删除提交的父级,从而使其成为初始提交
【发布时间】:2016-05-05 06:40:09
【问题描述】:

注意:我知道这是改写历史,会改变所有的哈希值,把其他人搞砸。


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

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

【问题讨论】:

  • 如果您想完全断开提交与其父级的连接并且没有历史记录,为什么不直接复制所有文件并创建一个新的存储库?
  • @EdCottrell 因为我希望孩子/后代能够生存。
  • 所以,我不能 100% 确定这会有所帮助——我更像是一个 Mercurial 人而不是 git 人——但请参阅 stackoverflow.com/questions/9844082/…
  • 澄清一下——你想让你选择的提交成为根(在这之前失去一切)?否则我不确定你在问什么。
  • 还有 see here 了解如何使用 git replace 隐藏历史记录,如果您的动机是您不特别关心旧提交并且不希望它们弄乱工具的输出

标签: git commit git-commit git-rewrite-history git-plumbing


【解决方案1】:

git rebase -i HEAD~

然后在上面终端cmd之后弹出的编辑器中将child commit line的开始从pick改为squash。或分别为“p”和“s”。写入文件并退出上述命令出现的编辑器

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

Edit2: 或者你可以 git rebase -i parentcommithash 并且列表的顶部应该是父项

【讨论】:

    【解决方案2】:

    假设您希望新的初始提交为 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
    

    待办事项(适用于任何人):在说明中编辑

    【讨论】:

      【解决方案3】:
      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 仍然会反映原始提交的嫁接祖先)

      【讨论】:

      • 感谢您添加 rm ,我在重写提交后查看历史感到困惑:)
      猜你喜欢
      • 1970-01-01
      • 2016-07-21
      • 1970-01-01
      • 2015-02-13
      • 2021-04-14
      • 2013-09-10
      • 2018-02-10
      • 2010-09-30
      相关资源
      最近更新 更多