Sometimes when coding, you start doing a couple cascading refactorings because you need to update several behaviours. Or you just do a few fixes while the file is open1. Then you realize that you did all these changes without committing. This can result in git commits containing much more than the change you were initially in for, which in turn can make it hard to revert / cherry pick anything, and increase the load on pull request reviews.

Fortunately, git comes with a nice interactive feature that lets you pick what you want to stage in your commits: git add --patch.

Example

When running it, git will interactively go over all the changes you did, and ask what to do with them. There’s tons of actions available. Those you will care the most about are:

  • y: add to stage
  • n: do not add to stage. To be clear, it will just ignore the change for now.
  • s: split the change. If git presents you things you want to add along things you don’t, this can split into smaller changes.

Once you’re done adding to stage, it’s a regular process of committing changes and pushing to remotes.

There are 2 nice things with that approach:

  1. You can review what you’re committing, which is always a good thing
  2. It can help you greatly facilitate reviews, by spreading changes in several pull requests. Typically, one PR could contain refactoring, renaming and noisy changes, and another could contain significant issue-related changes.

There are several ways to do so. Here is an easy one: suppose all then changes were done in a new branch that as not been committed yet. Let’s call it 123.

  1. stage and commit all the changes regarding refactoring to 123.
  2. push and create a pull request for that, from 123 to master2, and be specific that it’s limited to refactoring by titling it “Refactoring”
  3. create a new branch specific to the issue being solved in 123. Let’s call it 123-feature
  4. stage and commit all the changes specific to feature.
  5. push and create a pull request for that, from 123-feature to 1233, and be specific that refactoring has been made and also needs review.

Small pull requests, with a specific goal in mind are easier and faster to review. This process can be inverted based on what is being done (have feature in base branch and refactoring in another one). More branches can be added (123-renaming, 123-adding_tests_for_file_saving, 123-feature).

This process is not always applicable, but when it is, making things easier for people reviewing your code is a sign of care and love.

Notes

  1. While not necessarily being the best thing to do, it happens. 

  2. Or whatever you usually merge to. 

  3. The point here is that you want only your changes related to feature to show in that branch. As changes related to refactoring are not yet merged to master2, if you create the PR against master then both feature-related and refactoring-related changes are going to show up.