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...