Brian Dunagan

June 11 2014
Git Tip: Logical commits with git stash

Commits should always be logical, atomic changes, but parceling out your working copy into logical commits is often a struggle. Adding individual files to a certain commit is straight-forward, but adding just a subset of changes in a given file while not losing the other changes is more difficult.

In the past, I had two strategies. Sometimes, I copied a file from Xcode into TextMate, reverted unrelated changes in Kaleidoscope, committed the logical piece, then pasted the original file back into Xcode. Bit of a pain, and it didn’t scale well to many files. Other times, I counted on Undo (Command-Z) to remember what Kaleidoscope clobbered. Undo didn’t always remember what I thought it should.

Recently, I came up with a cleaner strategy using git stash apply:

  1. Make many overlapping changes and decide to commit a number of chunks.
  2. git stash – This saves your working copy as a temporary commit.
  3. git stash apply – This restores your working copy while keeping the temporary commit.
  4. Revert all unrelated changes and commit the first piece.
  5. git stash apply – This restores the original working copy again and silently merges in your matching changes.
  6. Repeat (4) and (5) until your commits match the working copy.
  7. git stash pop – If your commits match your original working copy, the stash will be dropped without issue, and your working copy will remain empty.

Update: As @cocoadog and @glebd point out on Twitter, there are other alternatives. You can use GitHub for Mac or SourceTree, which both have this selected-lines feature. And, for the brave, you can do interactive staging using git add -p or git add -i.

Making Remote Work Dollar Clock 5.0
LinkedIn GitHub Email