可能是重复问题:
如何完全从历史记录中删除(旧的)git提交?
Git非常有用,可以对客户网站进行每夜快照。知道所有内容(php + mysqldump +用户文件上传)都在Git存储库中,可以提供极大的安心感。
由于某些网站的大小很大,我想知道是否有人知道一种相当容易的方法可以删除(例如)30天前的所有提交?
可能是重复问题:
如何完全从历史记录中删除(旧的)git提交?
Git非常有用,可以对客户网站进行每夜快照。知道所有内容(php + mysqldump +用户文件上传)都在Git存储库中,可以提供极大的安心感。
由于某些网站的大小很大,我想知道是否有人知道一种相当容易的方法可以删除(例如)30天前的所有提交?
实际上,您确实可以这样做。 这有点棘手。 以下是一个示例...
$ cd /tmp
$ mkdir rmcommits
$ cd rmcommits
$ git init
Initialized empty Git repository in /tmp/rmcommits/.git/
$ cp /tmp/example/xy.c .
$ git add xy.c
$ git commit -m 'initial commit'
[master (root-commit) 8d5b88c] initial commit
1 files changed, 273 insertions(+), 0 deletions(-)
create mode 100644 xy.c
$ echo 'more stuff' > morestuff.txt
$ git add morestuff.txt; git commit -m 'add some stuff'
[master f971ae5] add some stuff
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 morestuff.txt
$ echo 'and still more' >> morestuff.txt
$ git add morestuff.txt; git commit -m 'add more stuff'
[master bea9192] add more stuff
1 files changed, 1 insertions(+), 0 deletions(-)
现在我挑选了一个我希望“历史终结”的地方(对于分支主线,也就是HEAD):
$ git rev-parse HEAD^
f971ae5b4225aca364223a44be8be84268385ff3
这是我将保留的最后一次提交。
$ git filter-branch --parent-filter 'test $GIT_COMMIT == f971ae5b4225aca364223a44be8be84268385ff3 && echo "" || cat' HEAD
Rewrite bea9192a53a5aeb7532aa1e174f7f642363396de (3/3)
Ref 'refs/heads/master' was rewritten
$ git log --pretty=oneline
65a246b8320382a64550d2c4b650c942d7bfba70 add more stuff
7892ab45aa33cd5ebdc3090ce2622081059fdd79 add some stuff
git filter-branch
基本上会运行在分支的所有提交中,这里是master
,因为HEAD
当前是ref: refs/heads/master
,而使用--parent-filter,您可以重写每个提交的父级。当我们找到目标提交时,我们想要历史记录停止,在此之前,我们不会输出任何内容——您不需要空白字符串,这是我的旧习惯,以前没有参数的echo什么都不做——否则我们将使用"cat"来复制现有的-p参数,正如filter-branch手册所述。这使得基于我们测试过的那个新提交没有父级,即现在是一个初始提交——分支的根。这在git存储库中很不寻常,因为现在我们有两个根提交,一个在新的master
上,一个在旧的保存的主分支上,如下所述。)git filter-branch
使用的保存名称:$ git log original/refs/heads/master --pretty=oneline
bea9192a53a5aeb7532aa1e174f7f642363396de add more stuff
f971ae5b4225aca364223a44be8be84268385ff3 add some stuff
8d5b88c468f75750d5a01ab40bfae160c654ac66 initial commit
$ git update-ref -d refs/original/refs/heads/master
$ git reflog expire --expire=now --all
$ git gc --prune=now
$ git fsck --unreachable
$
当前存储库状态中存在的文件被保存为原始添加文件加上一系列更改,因此您无法删除添加文件的提交。
TortoiseGit 有一个操作,您可以从日志中选择多个连续的提交并“合并为一个提交”,但它不是 Git 的本地提供的功能,从我从出现的窗口中推断出来,它是通过创建一个新分支,应用原始分支的更改,仅提交一次并在结果上进行变基实现的。当选择许多提交时,这肯定不是一个快速的操作,我想在大型存储库中它会更慢,并且在使用它之前我总是备份。
总的来说,我怀疑是否存在一种简单的方法来做到这一点。
git rebase --interactive
中的“squash”。是的,在底层它是通过构建一个新分支来完成的。