【发布时间】:2019-10-23 02:47:11
【问题描述】:
假设我有一个像这样设置的 Git 存储库:
$ git init test && cd test
$ touch a && git add . && git commit -m "add a"
$ touch b && git add . && git commit -m "add b"
$ touch c && git add . && git commit -m "add c"
$
$ git --no-pager log --pretty="%h %s" # print short SHA and message subject
176d6d0 add c
495991e add b
1d8444a add a
现在由于某些原因,我想将最近的 2 个提交(176d6d0 add c 和 495991e add b)压缩为一个 [1]:
$ git reset --soft 1d8444a # go back to the first commit ("add a")
$ git add . && git commit -m "bc"
$
$ git --no-pager log --pretty="%h %s"
c01e64a bc
1d8444a add a
是的,看起来我们已经完成了!
不完全是!
如果我们查看git reflog show,旧的提交仍然存在:
$ git --no-pager reflog show
c01e64a (HEAD -> master) HEAD@{0}: commit: bc
1d8444a HEAD@{1}: reset: moving to 1d8444a9747bd5e4176c
176d6d0 HEAD@{2}: commit: add c # old commit
495991e HEAD@{3}: commit: add b # old commit
1d8444a HEAD@{4}: commit (initial): add a
如果我们签出旧的提交,我们仍然可以恢复它。
$ git --no-pager show -s 176d6d0 # this is the "add c" commit
commit 176d6d0aa92b230f4dd1e4ed8ae028b7c5fbb2d5
Author: XXX <XXX@XXX.com>
Date: Tue Oct 22 22:19:23 2019 -0400
add c
$ git checkout 176d6d0
Note: checking out '176d6d0'.
You are in 'detached HEAD' state. You can look around
... # omitted
HEAD is now at 176d6d0 add c
我试图删除这些陈旧的旧提交,但这些都不起作用,旧提交在 git reflog show 和 git checkout-able 中仍然可见:
git gc
git gc --prune=all
git reflog expire --all
git reflog expire --expire=now
git reflog expire --expire-unreachable=now
git reflog expire --expire=now --all # tricky, see update below
问题:
- 我应该如何真的丢弃旧的提交(
176d6d0 add c和495991e add b)? - 这些旧提交(
176d6d0 add c和495991e add b)的术语是什么,例如它们真的是“无法访问的提交”、“陈旧的提交”吗?
删除它们的行为的行话是什么,例如是“修剪”、“垃圾回收”吗? - 人们一直在做
git reset或git rebase -i。如果他们不以某种方式删除这些陈旧的提交,他们是否会得到一个臃肿的 Git 存储库,尤其是对于有很多合作者(如 Chromium)的大型项目? - (很高兴)请解释为什么您对 1 的回答有效。
脚注:
[1] 我可以使用git rebase -i,但我想以编程方式而不是交互方式进行操作,以便可以通过脚本自动执行,但这不是重点)
[2] this answer 没有完全回答我的问题
更新:
这会删除
git reflog show显示的所有条目,但我不太明白为什么 阅读文档..还有其他问题(请参见上文)git reflog expire --expire=now --all然而,旧的提交虽然没有显示在
git reflog show,但仍然是git checkout——如果你记得 SHA,这意味着这些旧的提交并没有真正被删除!!所以这不是答案。
【问题讨论】:
-
实际上你的问题 is 在那里回答了,至少在 cmets 中:“除了 reflog 条目(在 reflog 条目本身被删除之前保持对象存活)之外,所有对象都得到宽限期,默认为 14 天 [...]
--prune-all" -
@o11c 我试过了,
git gc --prune=all没有删除它们..(添加到不起作用的命令列表中) -
软重置后不需要添加,索引条目仍然指向相同的位置(软重置不会触及索引)
标签: git