假设我有一些git存储库,其中包含文件和许多提交。如果我这样做:
git reset --soft $some_commit
然后修改一行并执行
git add file
git commit -m message
git push --force
我看到.git
文件夹中的文件实际上实际上增加了很多(与重设之前相比),尽管实际上文件并不重。想知道那里发生了什么。虽然我进行了软重置,但会还原.git
内部文件,但是似乎实际上并没有删除提交。我想念什么吗?
答案 0 :(得分:2)
为说明正在发生的情况,假设您有五次提交。
A - B - C - D - E [master]
然后您重置为C。
$ git reset --soft C
A - B - C [master]
\
D - E
还原的提交仍在本地存储库中。重置不会删除它们,但是没有引用它们。如果它们在两周后仍未被引用,则会被垃圾回收。
然后您进行一次新提交。
$ git commit
A - B - C - F [master]
\
D - E
同样,旧提交仍然存在。
从概念上讲,Git会存储整个更改的文件,而不仅仅是diff。如果对大文件进行了微小更改,则.git
可能会随着Git存储新副本而增加整个文件的大小。但是Git最终将压缩其数据库以减小大小。如果您不耐烦,可以运行git gc
。通常,Git存储非常高效。
按推对您的本地存储库没有影响。
这些提交并非完全不可到达。您仍然可以从git reflog
访问它们,并在它们上放置新标签或分支。例如,如果您意识到自己犯了一个错误并想返回,则可以将master
返回到原来的位置。
$ git reset --hard E
A - B - C - F
\
D - E [master]
还有ORIG_HEAD
。这是一个特殊的标签,设置在您移出的位置。原来的git reset --soft C
ORIG_HEAD
仍位于E上。
$ git reset --soft C
A - B - C [master]
\
D - E [ORIG_HEAD]
然后您返回那里。
$ git reset ORIG_HEAD
A - B - C
\
D - E [master]
它以这种方式工作,不仅可以提高Git的效率,而且磁盘价格便宜,并且不必在每次更改时都优化其存储,也不必改变主意。
如果要摆脱所有无法访问的对象,可以运行git gc --prune=all
。除非您确实非常缺乏磁盘空间,否则请不要这样做。通常运行git gc
足以使git压缩并打包.git
。