21

Since asking my last question which turned out to be about rebasing with GIT, I have decided that I don't want to rebase at all. Instead I want to:

  1. Branch
  2. Work work work, checking in and pushing at all times
  3. Throw out all of those commits and pretend they never happened (so one clean commit at the end of work)

I do this currently by copying the files to a new directory and then copying them back in to a new branch (branched at the same point as my working branch), and then merging that into master or wherever.

Is this just plain bad and why? More important: Is there a better/GIT way to do this? git rebase -i forces me to merge (and pick, and squash).

Community
  • 1
  • 1
Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421

2 Answers2

25

The easiest thing to do is a soft reset.

So checkout your topic branch:

git checkout -b topic master

work, work, work.

git commit
git commit
git commit
git commit

Happy with this, you can make a new single commit on top of master

git reset --soft master
git commit

Now merge to master (it will be a fast-forward) and tidy up the topic branch. (Note that you don't need to do this if you are prepared to remember or tag where master was and just work on master without branching, you could have just done git reset --soft old-master and git commit and you wouldn't need these last clean-up steps.)

git checkout master
git merge topic
git branch -d topic
CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 4
    Excellent (+1), but that leaves the question: is this the right way (with Git or actually with any (D)VCS)? all the logical incremental steps are squashed, and if there is some nasty bug withing the commits for topic, that won't be easy to pinpoint and fix. – VonC Feb 23 '10 at 18:58
  • 2
    @Charles Bailey, thanks for that. @VonC, it depends. I check in every minute or less... too much information is just as bad as none. – Dan Rosenstark Feb 23 '10 at 19:04
  • So just to be clear, git reset --soft some_branch switches me to some_branch/some_commit without touching my files? – Dan Rosenstark Feb 23 '10 at 19:07
  • Okay, I see it now: it resets me there, but doesn't do a checkout. Strange/great! – Dan Rosenstark Feb 23 '10 at 19:16
  • 1
    `git reset --soft` just moves the current branch head to the given commit, leaving the index in tact. A normal (`--mixed`) `git reset` also resets the index to the state of the given commit but that isn't what you want for this scenario – CB Bailey Feb 23 '10 at 19:19
  • Brilliant. I now feel silly for spending so much time doing rebases in the past. Yes, rebase is more powerful, but if all you want to do is squash a branch into fewer commits, this is better. The problem with rebase is that you need to re-resolve any merge conflicts you've had before, making you do work twice. – kotoole Nov 10 '14 at 17:55
  • Hi, followed your steps, but instead of a squash I got 2 more commits in my history.. what did I do wrong? – guy mograbi Nov 03 '15 at 16:01
  • This is a very dangerous answer, as it will undo all commits added to master since the branch was created (or since the branch last pulled master). Before `git reset --soft master` you should `git pull origin master` to get the latest chnges from master into your branch. – Bernie Sumption Nov 08 '19 at 10:41
10

You can also use git merge with the --squash option.

Ionuț G. Stan
  • 176,118
  • 18
  • 189
  • 202
  • 1
    Squash happens on every commit automatically, I don't see how that helps with my question. Not that it doesn't, but I'd need more information. – Dan Rosenstark May 10 '10 at 11:58
  • 2
    I've used `git merge --squash` when I wanted to merge a topic branch with master, but also reduce the commit history to just one commit. `git merge --squash` performs the merge, but let's you supply a commit message before actually committing the merge. So the end result appears as though you have committed just once to the master branch. – Ionuț G. Stan May 10 '10 at 12:37
  • 2
    sorry it took me three years to figure out that this answer is correct. Great work! – Dan Rosenstark Jan 29 '13 at 16:40
  • @Yar haha, no problem. I'm glad it helped you in the end :) – Ionuț G. Stan Jan 29 '13 at 16:47
  • It wont work in the case of [deleted files](http://stackoverflow.com/a/14343784/281545). Maybe not the way to go - see [here](http://stackoverflow.com/questions/1464642/git-merge-squash-repeatedly) – Mr_and_Mrs_D May 08 '13 at 18:58
  • You know git is overly complicated when it takes someone 3 years to figure out this is the correct solution... – Jeff Fischer Jun 05 '15 at 18:51