Typically when I work on code changes I try to keep things to a single commit. This makes it so I won’t need to squash my commits into one (you gotta keep that history clean). It even makes updating pull-requests rather easy with a force push. I have seen many people be befuddled by this kind of workflow. Hopefully this post and the examples within will help future developers who run into problems.

My workflow for such a thing is as follows:

# do some code stuff
git checkout -b feature_branch
vi files.ext
git commit -a #first commit

vi files.ext
git commit -a --amend # second commit

git push origin feature_branch # initial push

# people find something up with the PR
# fix the PR
vi files.ext
git commit -a --amend #fix the thing
git push origin feature_branch -f # final push

Note: I don’t use the single commit workflow for large changes

I recently ran into a situation where it was appropriate to split the commit into lots of very tiny commits and PR each one separately. It took a little thinking but the solution I came up with worked for me.

Splitting the commit

Assuming I have already made the PR and it was decided that I had to split that commit.

  1. Find the SHA of your commit with git log

Your commit SHA should be the top, copy it now.

  1. Reset to the previous commit (master in this case): git reset --hard origin/master

Your commit is gone! Oh no! Just kidding the SHA still works.

  1. Cherry-pick your commit back onto the branch but do not make a commit (with -n): git cherry-pick SHA -n

Now your changes are staged on top of origin/master and not committed.

  1. Unstage the files: git reset

Now all your changes are unstaged and need to be added again.

  1. Create your commits ensuring you add just the files you want: git add filename.ext

If you only add the files you want in a commit, when you make the commit it’ll only contain those changes.

  1. Commit your changes without using -a: git commit

  2. Make a new branch to push git checkout -b mini_feature_branch

  3. Push your new branch git push origin mini_feature_branch

Repeat steps 5 through 8 until you have no more files to stage!