A while back, I was doing a lot of code changes that sprawled throughout the codebase, and when I finally completed a single chunk of work mixed in with a lot superfluous code changes, I was left with the final task of committing only a subset of un-staged changes in my local repository. I had several files that contained multiple changes which either needed to be committed or deleted, and I didn’t have a way to do it other than manually.
I’m so lazy (or just allergic to reversing changes manually) that I wondered how I could selectively check out chunks of changes from the files while leaving others in place so that I could stage and subsequently commit those changes. A minimal search yielded this great Stack Overflow post explaining how to selectively check out chunks of code. Sweet! TLDR;
git checkout -p allows you to interactively un-stage code changes in your local repository.
After finding that post, I quickly shaped up my next commit and moved on to other tasks. But that episode reminded me that another way to solve the problem would have been to execute the inverse I was trying to achieve in the above-mentioned scenario and use
git add -p to selectively stage chunks of code changes for commit (as opposed to remove unwanted code from potential commits). This is useful when you are experimenting with a lot of different code changes (perhaps you like to liberally sprinkle console logging everywhere when fixing obscure bugs?) in your local repository, and it’s more efficient to try multiple approaches and not immediately clean up after yourself because you’re trying to get in the flow of understanding or working on some hard problem. Using the
-p flag will allow you to stage one code diff and discard another in the same file. The typical work flow is to use
git add -p to selectively add ONLY the code diffs that solved your problem for a given commit. After choosing the correct code diffs, commit what you’ve staged, and then run
git checkout . to get rid of the remaining cruft that didn’t work. See how that works?
You can read more about adding commits in chunks here on the Git SCM website. You might be wondering what’s so special about
-p ? What does
p even stand for? Git repositories are sometimes described as being a tree of linked-lists where the nodes in the list are patches.
p is an abbreviation for “patch”!
On a closing note, the nice thing about git is they try (like many other UNIX commands) to maintain standard configuration flags across all operations (eg
-p!) Try using
git log -p and see what happens?