我使用 git 来备份和恢复系统上可能发生更改的文件夹,并且随着无用的历史记录的积累,它们可能会变得非常大。我只需要最后 4 次左右的提交,如何压缩或删除除最后 n 次提交之外的整个历史记录?
免责声明:不幸的是,您的第一句话可能玷污了这个问题:
我使用 git 来备份和恢复系统上可能发生更改的文件夹,并且随着无用的历史记录的积累,它们可能会变得非常大。
如果历史记录“无用”,那么 Git 可能不是正确的工具。正如评论中提到的,Git 通常不是备份系统的正确工具。话虽这么说,如果您的问题不包括第一句话,我们将无法判断您“为什么”希望这样做,而您剩下的问题当然是有效的:
我只需要最后 4 次左右的提交,如何压缩或删除除最后 n 次提交之外的整个历史记录?
这是实现此目的的一种相当直接的方法。请注意,此方法要求您在开始之前确定一些事情:
- 您要重写的分支名称。 (这个答案假设它被称为
main
.)
- 您分支的根提交。获取它:
git log main --reverse
(这个答案假设它被称为<old-repo-root-commit-id>
.)
- 您想要保留的最旧的提交 ID,即从顶部开始的第四个提交,它将成为您新的存储库根提交。 (这个答案假设它被称为
<new-repo-root-commit-id>
.)
- Your
git status
开始之前应该是干净的。如果不是,请考虑提交(或撤消)您最近的更改。
以下是要运行的命令集:
git switch --detach <new-repo-root-commit-id>
git reset --soft <old-repo-root-commit-id>
git commit --amend --reuse-message=<new-repo-root-commit-id>
git rebase <new-repo-root-commit-id> main --onto @
我看到你的标题提到你的目标是节省空间。为了也实现该目标,您的存储库中不能有任何其他指向旧提交 ID 的引用。如果您的系统中只有一个没有任何标签的分支,那么旧的提交将最终收集垃圾。如果您想立即清理它,请参阅这个问题 https://stackoverflow.com/q/1904860/184546.
命令如何工作的详细解释:
- The
switch
命令只是检查您想要成为新根提交的特定提交。这与git checkout <new-repo-root-commit-id>
但较新的switch
命令要求您指定--detach
当您检查提交 ID 而不是命名分支时。
- The
reset
命令表示更改当前指向的提交,改为根提交 ID,并且--soft
表示不要更改本地文件,并保留所有更改would由于此重置而发生,已分阶段并准备好提交。
- 请注意,重置后,您将指向存储库中的第一个提交,现在您将修改(重写)该提交以包括根提交和新根提交之间的所有更改。这本质上只是将所有先前的提交压缩为一个提交。这
--reuse-message
选项表示使用新存储库根目录中的提交消息而不是原始存储库根目录。这实际上是不需要的,但最近的提交消息更有可能比原始提交消息更好。这当然取决于你的提交消息的内容;提交时,如果您愿意,您可以从任何其他提交中设置一条消息,或者也可以创建一个新的不同消息。
- 在提交命令之后,您只有一次提交,现在您将
rebase
(重播)剩余的(例如 3)次提交main
,“到”你的新提交,只剩下 4 个提交。此时如果您执行 diffmain
与提交 IDmain
在此过程之前,结果应该是空的,因为您实际上根本没有更改您的工作文件。 (请注意,您可以使用git reflog
查看提交 IDmain
在您执行此操作之前,只要您尚未对引用日志和旧提交执行完整的垃圾收集,就已开启。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)