59

Possible Duplicate:
How can I squash my last X commits together using git?

I have a project hosted on GitHub and I have a local clone. I have a load of small commits that I have already pushed up to GitHub. This has all been done using the default *master branch.

I got confused between merge --squash and rebase etc... What is the most straightforward way of combining several historial commits in to one commit so that it pushes up to GitHub?

Community
  • 1
  • 1
Gabe
  • 1,078
  • 1
  • 11
  • 17

1 Answers1

126

Before starting, you should make sure that git status is clean (i.e. there's no output from that command) to avoid losing work. The simplest way to do what you want is probably:

git reset --soft <LAST-COMMIT-THAT'S-OK>
git commit -m 'Many squashed commits'
git push --force origin master

You should bear in mind that this is rewriting history (that's why you need the --force option to git push) so you should avoid this if anyone else might have cloned or pulled from your repository. For some more alternatives, see this question and its answers:

Community
  • 1
  • 1
Mark Longair
  • 446,582
  • 72
  • 411
  • 327
  • 2
    What are the repercussions of doing this if other branches regularly pull from the repo (fast forwarding only)? – Gabe Nov 21 '11 at 15:23
  • 1
    @whoami: If someone else pulls that branch, they will see `(forced update)` and git will refuse to update their branch. They then need to (a) make sure that all their work is committed (b) typically either rebase (e.g. with `git rebase origin/master`) or reset their branch to the remote-tracking branch version that's just been force-updated (e.g. with `git reset --hard origin/master`). Unless you're happy explaining to people what to do, it's definitely best not to force-push rewritten history. – Mark Longair Nov 21 '11 at 15:30
  • They will all see that their local branches and the remote have diverged and will have to merge the changes in rather than just fast forward. – Noufal Ibrahim Nov 21 '11 at 15:30
  • @Noufal Ibrahim: The problem with merging in that situation is that they will still have all the small commits in their merged `master` branch, and might push them back to the repository. – Mark Longair Nov 21 '11 at 15:33
  • Urgh sounds a bit messy either way, I suppose the moral of the story is to do it all before it goes on GitHub? In that case is `reset --soft` or `rebase` most suitable? – Gabe Nov 21 '11 at 15:41
  • 1
    @whoami: Yes, it's best to restrict history rewriting to commits that you haven't pushed yet. If you know exactly that you want to squash all the last N commits, `reset --soft` and committing is probably easier, but if you want to selectively squash and reorder commits, using `git rebase -i` will give you that flexibility. (Also it depends which commands you're more familiar with...) – Mark Longair Nov 21 '11 at 15:45
  • @Gabe Whenever I force push a branch, I let everyone working on that branch know about it. Then they can `git branch -D branchname && git checkout branchname && git pull` which will delete their copy of the branch and checkout a fresh copy. We prevent any pushing to `master` and do all work on a feature branch. So only people working on the same feature branch are affected. – styfle Aug 23 '17 at 13:54
  • @MarkLongair Can you add a note about the `HEAD~5` syntax when selecting a commit? – styfle Aug 23 '17 at 13:55