如何删除除最后五个之外的所有Git提交

kay*_*ahr 27 git

我有一个非常大的Git存储库,它只包含经常更改的二进制文件.当然Git仓库,高于它的实际文件大.我并不真正关心旧的历史,我只需要一些较新的历史就能够恢复一些错误的变化.所以,假设我要删除除最后五个之外的所有提交.

当然,我想这样做是为了使存储库保持较小,因此必须从repo中完全清除已删除的提交.

我想用一个命令(别名)或脚本以非交互方式完成所有这些操作.我怎样才能做到这一点?

Dan*_*ruz 13

这是一个rebase-last-five让你入门的别名.它将重新创建当前分支,因此历史记录中只有最近的五个提交.最好将这个脚本(git-rebase-last-five.sh)放在你的目录中PATH; Git将查找和使用命名git-....sh的脚本,而无需任何特殊配置.该脚本应该比这个简单的别名做更多的错误检查和处理.

$ git config --global alias.rebase-last-five '!b="$(git branch --no-color | cut -c3-)" ; h="$(git rev-parse $b)" ; echo "Current branch: $b $h" ; c="$(git rev-parse $b~4)" ; echo "Recreating $b branch with initial commit $c ..." ; git checkout --orphan new-start $c ; git commit -C $c ; git rebase --onto new-start $c $b ; git branch -d new-start ; git gc'
Run Code Online (Sandbox Code Playgroud)

CAVEAT EMPTOR:注意关于改变历史警告.

查看man页面(git help <command>在线)以获取更多信息.

示例用法:

$ git --version
git version 1.7.12.rc2.16.g034161a
$ git log --all --graph --decorate --oneline
* e4b2337 (HEAD, master) 9
* e508980 8
* 01927dd 7
* 75c0fdb 6
* 20edb42 5
* 1260648 4
* b3d6cc8 3
* 187a0ef 2
* e5d09cf 1
* 07bf1e2 initial
$ git rebase-last-five 
Current branch: master e4b2337ef33d446bbb48cbc86b44afc964ba0712
Recreating master branch with initial commit 20edb42a06ae987463016e7f2c08e9df10fd94a0 ...
Switched to a new branch 'new-start'
[new-start (root-commit) 06ed4d5] 5
 1 file changed, 1 insertion(+)
 create mode 100644 A
First, rewinding head to replay your work on top of it...
Applying: 6
Applying: 7
Applying: 8
Applying: 9
Deleted branch new-start (was 06ed4d5).
Counting objects: 35, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (35/35), done.
Total 35 (delta 4), reused 0 (delta 0)
$ git log --all --graph --decorate --oneline
* a7fb54b (HEAD, master) 9
* 413e5b0 8
* 638a1ae 7
* 9949c28 6
* 06ed4d5 5
Run Code Online (Sandbox Code Playgroud)

  • 效果很好!谢谢!但不是只使用`git gc`我不得不使用`git reflog expire --expire = now --all; git gc --prune = now`实际上使存储库更小. (4认同)

amo*_*fis 8

好的,如果你想要我想要的东西(见我的评论),我认为这应该有效:

  1. 创建分支以保存所有提交(以防万一):

    git branch fullhistory

  2. 仍然在master上,重置 - 硬件到你想要保留历史记录的提交:

    git reset --hard HEAD~5

  3. 现在重置而不是--hard历史的开头,这应该保持您的工作区不变,因此它保持在HEAD~5状态.

    git reset --soft <first_commit>

  4. 所以现在你有空的历史记录master,以及你在工作区中需要的所有变化.只是提交它们.

    git commit -m "all the old changes squashed"

  5. 现在樱桃选择fullhistory你想要的4个提交:

    git cherry-pick A..B

A比B大,并且记住A不包括在内.所以它应该是您想要包含的最早提交的父级.