Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git rebase. How Do I Use it to Collapse Reams of Ancient Commits

I now have a big honking, bloated, Git repository consuming mucho disk space on GitHub that I want to put on a diet. I need to discard ancient commits made early in the history of the project that are are essentially irrelevant to the current direction the project is going.

I am - and will always be - the sole user of this private repo.

Ideally I could do something like:

git rebase from-birth-of-repo-until-one-month-ago

Thanks,
Doug

like image 986
dugla Avatar asked Jul 25 '10 11:07

dugla


People also ask

How do I drop a commit in rebase?

Interactive Rebase allows you to delete one or multiple commits. With you HEAD branch selected in the sidebar, choose the commits in question and right-click them. The contextual menu will then contain an option to Delete "<hash>" (or, in case you selected multiple commits: Delete N Revisions).

How do I use git rebase command?

Checkout to the desired branch you want to rebase. Now perform the rebase command as follows: Syntax: $git rebase <branch name>

How does rebase handle merge commits?

The rebase operation itself combines resets, labels, merges to preserve the same structure. The tool itself rewinds before each merge tree, picks commits, then creates a merge commit. The very same steps can be done manually to achieve the same result.


1 Answers

The --squash option to git merge might be useful, and is available in git 1.4.1 and later. This stages the effects of a merge, but doesn't create a commit. So, if 143eff is the oldest commit you want to include in the squashed commit, your current branch is master and the "one month ago" commit is dcb7e5, you could do:

# Save the old position of "master" by creating a branch old-master:
$ git checkout master
$ git branch old-master

# Create and checkout a branch called "new-master" that's at the old commit:
$ git checkout -b new-master 143eff

# Stage the effects of merging the "one month ago" commit:
$ git merge --squash dcb7e5
Updating 143eff3..dcb7e5b
Fast-forward
Squash commit -- not updating HEAD
[... status output showing the staged changes ..]

# Create the squashed commit:
$ git commit -m "A commit squashing history up to a month ago"
# (You could use --amend if you want them to be squashed into 143eff
# instead of being a commit after that.)

Now you can check with git diff dcb7e5 new-master that they really are the same.

Next, you want to rebase the rest of your work onto new-master:

$ git rebase --onto new-master dcb7e5 master

That will leave you on a rebased master which should have the history you want. (Again, you can check this with git diff old-master master and git log. When pushing master to github you will need to add --force since you've rewritten history:

# Push master to github, with "--force", since you've rewritten history:
$ git push --force origin master

You can now remove new-master, which is at the squash commit, with:

git branch -d new-master

Apparently github runs git gc --auto on pushes, so you should see some space saving soon...

like image 96
Mark Longair Avatar answered Oct 09 '22 07:10

Mark Longair