1

Say I have 100 commits in my branch that I've been working on for 3 weeks. Occasionally (every day, really) I pull from origin/master and merge it into my branch.

How could I (easily) go about squashing all of my commits into one commit without messing up history? If I squash all of my commits into one somehow, would I destroy the merged origin/master pulls when my pull request gets moved into origin/master?

tester
  • 22,441
  • 25
  • 88
  • 128

1 Answers1

8

"Squashing" and "preserving history" are approximately direct opposites in terminology.

If you mean that you want to make a single commit that includes only your changes and not the ones from upstream master, you would probably want to rebase onto origin/master and then squash from there. You could do all of this from a single invocation of interactive rebase:

git fetch origin
git rebase -i origin/master

and then change all of the lines after the first from pick to squash.

Amber
  • 507,862
  • 82
  • 626
  • 550
  • so I have my branch "foo" checked out. I run `git rebase -i origin/master` and I see a ton of commits.. If I squash them all, then push to master, the commits that i previously merged in and squashed are permanently gone from origin/master's history? (e.g. I git reset head back to commit before my squash commit. will everything be the same when i reset?) – tester Mar 06 '12 at 18:01
  • Do you see commits in the list that are already in master? If so, something is wrong. – Amber Mar 06 '12 at 18:08
  • yeah most of the commits that I see are things that I've merged/automerged during `git pull`s.. it's also in reverse order (my latest commit is at the bottom). any ideas? – tester Mar 06 '12 at 18:32
  • Latest commit being at the bottom is normal. Have you done a `git fetch origin` recently? Doing `git pull` doesn't actually automatically update the `origin/master` pointer. – Amber Mar 06 '12 at 18:42
  • ah okay that did the trick.. so now that i see just my commits, i add squash to everything but the last commit? or everything but the first commit? (seems like i should leave the last one to be pick since it's my last commit) – tester Mar 06 '12 at 19:00
  • Everything but the first should be `squash`. The way squash works is that it merges the commit into what already exists, so you need the first one to be pick so that there's a commit of yours to merge into; everything after that gets merged into that first commit. (Basically, `squash` does `commit --amend` instead of `commit` as it replays your history.) – Amber Mar 06 '12 at 19:02
  • awesome! thank you so much for your help @Amber! do you think that you could update your answer with some info about my issue (in case others run into this in the future)? something like "if you are seeing commits that aren't yours, make sure you `git fetch origin` before running `git rebase -i origin/master` – tester Mar 06 '12 at 19:05
  • 1
    I just added the `git fetch origin` bit earlier, since it's a good thing to do before starting a rebase regardless. – Amber Mar 06 '12 at 19:29