This article was originally published on maurobringolf.ch.
This article is part of a series where I make an effort to understand Git deeper instead of just remembering the correct order of
git commit and
git push. I started last year with two posts on Logs and Diffs and Undoing and/or fixing the last commit.
Today I continue by figuring out how to stage only parts of a modified file, specific lines that is. It is not difficult, but you should already be familiar with how files are added to commits through the staging area.
If you can do that, you a ready to learn how to only add some changes from a file to the next commit. I think the Git terminology for this feature is called patch.
The most effective way of learning a Git thing is by applying it (for me at least). Since I have a weak spot for things that reference themselves1
I will apply this Git feature to the code of Git itself. Of course you can use any other Git repository you like (and easily revert changes afterwards).
To get started we need to make changes to some existing file.
Here is what I did:
These are some arbitrary changes without meaning but let's assume I want to add just the comment but not the function. A classic
git add would only let me select the file or not, so here is where
patch comes in. Add the flag
--patch to use it2. This will drop you into an interactive mode where Git asks questions through the prompt. In this case it asks me whether I want to add the comment:
This is exactly what I wanted to be asked, so I say yes by entering
y. Git proceeds to the next questions which unsuprisingly is about my second change:
This is a change that (for whatever reason) I don't want to stage yet. So I say no by typing
n. Interactive mode finishes and I am left with the regular terminal prompt. What happened? Let's see by running
The file I modified is listed twice, once as staged and once as unstaged. This means that some changes are staged but we have additional unstaged changes on top of that version. To see this in detail we can use
git diff for both unstaged (default) and staged (
Here I see that the function is in the unstaged area. My second change, the comment, should therefore be in the staged area. Indeed:
So if I commit now it should only contain the comment but not the function:
I still have one modified file because the function has not been committed. That is basically how patching works. You might have noticed that there are more subcommands than just
n from the patch prompt. These include some neat shorthands for adding (
a) or omitting (
q) all changes from the current one to the end of the file. A really helpful one is splitting (
s): Sometimes multiple changed lines are shown to you as one piece during the patch process. If they are separated by unchanged lines you can use
s to split by them and decide for each part individually.
This was much easier than I expected and I attribute this to the fact that the patch process is interactive. At each step all my options were listed and I just chose one. Of course, you will have to look them up once or twice but then the single characters are probably enough to guide you. Happy patching!