Completely remove (old) git commits from history

2019-01-17 06:47发布

I'm starting a project using git where I'll be committing very large files, but only a few times a week. I've tried to use git as-is and it seems to store the entire file in each commit where it is changed. This will not work for this project, the repository would grow out of control. So, I want to reduce the size of the repository.

My first thought was to "simply" remove all commits older than say two weeks, or only keep e.g. five commits in the history (this is probably better :)) I've googled and read a lot from The Git Community Book and I guess I'm gonna need to work with git-rebase or git-filter-branch. The thing is I just can't seem to get it to work.

Just to illustrate; I have a history H with only one branch (The master branch)

A --> B --> C --> D --> E

I want to remove some previous commits to make my history look like

C --> D --> E

Commits A and B should be completely purged. I've tried git-rebase but it seems to merge commits together rather than actually removing old ones, maybe I don't fully understand how rebase works.. Another thought I had was to remove everything from .git/objects and then build a new commit using git-hash-object -w, git-mktree and git-commit-tree, I have not yet managed to push this "artificial" tree to the server though.

I won't be working with any branches, so there's no need taking these into account.

What I'm wondering is if anyone can give me concrete usages of git-rebase if that's what I'm supposed to use? Or some other tips, examples of what I can do.

Cheers!


Edit:

The large files will not be the same large files all the time, and some files will be replaced by new files. I want these replaced files to be completely purged from the history.

1条回答
甜甜的少女心
2楼-- · 2019-01-17 07:07

This should be a simple git rebase -i where you have

p A
s B
s C
p D
p E

and then edit the commit message for A-C to be just C's commit message.

git-rebase will "squash" all the commits into a single commit, who's objects are the same as commit C's objects.

Note: It may be possible to use git filter-branch to change the big files in the previous commits to actually match the new ones, if you'd rather do that. But its a dangerous operation and I don't want to give you a bad command on accident.

查看更多
登录 后发表回答