How to selectively add/reset/checkout specific lines

Here I’ll detail a single highly useful option associated with the git add, git reset, and git checkout commands. The most impacting thing about using this feature is that it will enable you to easily keep your commits succinct. In other words, each commit can be very specifically about something in particular. Having succinct, atomic commits will enable to you rebase with ease.

git add -p

This seems to me one of the most grossly overlooked and underutilized features of git (see also git show-branch). It can be as complex as you make it. Don’t overthink it, and you’re going to love it.

The -p stands for “patch.” This will take you step by step through each change in your set of currently-unstaged changes. It will show you each one and ask whether you’d like to add it (ie. stage it for commit) or not. There are other actions you can take, as well, but you don’t need to understand those to use this excellent feature.

Use cases

You might use the -p flag to:

  • Split up changes in order to ensure you commit atomically
  • Create a commit to encapsulate sets of trivial changes (e.g. space changes)
  • (An alternative to the above:) Undo trivial changes (e.g. space changes) that you just don’t think are worth committing.
  • Confine a commit to only the changes that affect the behavior of your code (not blankspace changes, etc.)
  • Remove (or exclude from adding) debug statements you peppered throughout your code while hacking, that you don’t need and don’t want to commit
  • Other undiscovered benefits!!
Hints
  • If you accidentally git add too much, you can always use git reset -p to get where you want to be. Or just git reset then start again.
  • If you accidentally git reset too much, you can always use git add -p to get where you want to be.
  • Be careful with git checkout -p! If you accidentally git checkout too much, you may lose uncommitted work! But if you think about it, this fact actually works as an argument in favor of using git checkout -p, it can be easy to get really relaxed about tapping through changes with a “y” or “n,” and I’ve accidentally cleared changes on occasions when I was going a little absent-mindedly.
  • If you need to stop for any reason, just respond q (“quit”) to any of the prompts, or type CTRL-C

Advantages

The -p flag has huge advantages that might not be immediately obvious:

You can add/reset/checkout individual lines in files

You can add specific hunks of changes in a file while leaving others unstaged. If you do this, you can then commit just those lines, and leave the other lines for a separate commit (or to be removed/reset/checked-out later).

You get to review each change as you add/reset/checkout

No more scrubbing through git diff output, then git adding an entire file. Hint: you can still add a whole file if you want – just answer a (for "all") when prompted at any change in that file.