删除没有父级的Git提交

Gar*_*son 1 git history parent reset

我在Git上上课.我不知道怎么样,但是我的一个学生设法连续三次提交了以前的历史记录!学生甚至设法将这三行提交合并master(在学生研究和发现之后--allow-unrelated-histories),但在历史树中,人们可以看到master,这三个提交只是挂在那里,而不是分开,就像尾巴一样.

之前发生的一件事是,在尝试将存储库克隆fooproj到单独的目录中时fooproj-copy,学生意外地将其克隆到了子目录中fooproj,因此Bitbucket将其显示为远程存储库中的子项目.我让学生删除了这个子目录fooproj-copy,然后推送新的提交,所以我觉得一切都很顺利.我不知道他们是怎么设法得到没有父母的承诺.

所以我说我会删除这三个提交(即使它们已经合并为master).我做了一个git reset --hard HEAD~1,它走了那条提交.我又做了git reset --hard HEAD~1一次,它继续前进.但又一次git reset --hard HEAD~1,我已经走到了尽头; 由于这三个提交中没有更多的父母,我收到此错误:

fatal: ambiguous argument 'HEAD~1': unknown revision or path not in the working tree.
Run Code Online (Sandbox Code Playgroud)

所以通常如果我想丢弃一些提交,我只是在提交之前对提交进行硬重置.但在这种情况下,在我想要丢弃的提交之前没有提交.我怎么能摆脱他们?

tor*_*rek 5

将其绘制为图形:

       D
        \
A--B--C--M--N   <-- master
           /
          E
Run Code Online (Sandbox Code Playgroud)

提交A,D并且E都是root提交(没有父提交).

Root提交很容易实现:git checkout --orphan将您置于未出生的分支上,以便该分支上的下一个提交创建分支本身并创建新的根提交.或者,git fetch从具有不相关历史记录的另一个存储库获取以root提交终止的提交的链(或复杂图形).或者,git commit-tree可以使用任意父项编写新的提交.

您无法真正直接删除这些提交或任何提交.你所能做的就是让它们无法到达.

一个提交X是可达的,如果有至少一个名称指向至少一个承诺,通过其祖先链,最终导致你X.在这种情况下,名称master直接指向提交N,合并. N点背到两EM,这样既可达. M点背到两CD,这样既可达.

在这种情况下,如果你点masterC,所有的D,M,E,和N不可达.因此,它们最终将过期并被垃圾收集.但是如果在N-let的调用之后有一个提交F- 你希望保留,那么你无能为力.您可以复制该提交:

       D
        \
A--B--C--M--N--F   [abandoned]
       \   /
        \ E
         \
          F'       <-- master
Run Code Online (Sandbox Code Playgroud)

并开始使用F',F作为提示的副本master- 但这意味着你没有保留F.您只保留不同的提交F'.