Git: partial commit
Thu 28 January 2016This post will demonstrate one of many cool features available in Git, partial commit. This feature allows add just some hunk of a file leaving other ones for future commit.
Let's suppose in a project there is the following source code:
#include <stdio.h>
void foo(void);
void bar(int);
int main(int argc, char **argv)
{
foo();
bar(100);
}
void foo()
{
printf("Hello, it's foo function here\n");
}
void bar(int x)
{
printf("Hello, it's bar function here. Wow! You send me a %d... it's such a number! ;)\n", x);
}
In this brand new repository there is only one commit:
And the first change is made:
Suppose a colleague requests another update in same file. He/She asks to change the name of the foo()
function to
xpto()
. So after both changes the diff is:
Nice, now it's time to commit the changes. However, it's necessary commit each hunk in different commits. Fortunately
git has a feature that will help on this situation. The commands git add
and git commit
allows user to select which
hunks of a file should be added. This is done by passing the -p, --patch
option. In our example, let's use git commit
to choose the hunks should be added in first commit:
As can be seen, git shows each hunk and asks the user for what should be done with it. The options are: [y,n,q,a,d,/,s,e,?].
To see help text, type ?
. The following text shall be shown:
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
In this example, it shown the first file's hunk. In the first commit, should be
committed the changes related with function bar()
only. The this hunk must be
ignored. Thus, the option n
is the right one.
In the following, git shows all further changes as an unique hunk. It's necessary
split them the smaller hunks. For do that, there is two options: s
and e
.
The first one tells git to split the hunk into smaller pieces. The e
option,
in the other hand, allows user choose manually each lines should added. In this
post the go with option s
. Git should shown something similar to this:
The previous hunk has been split into 3 hunks. Git now will iterate all of them
asking the user what should be done with each one. The first hunk should also be
ignored. The second one is the first change related with the function bar()
and
should be added. To that task, the y
is the right command.
Third hunk should be added too
Once there are no more hunks, as we used the git commit
command, the editor
will be open to the user insert the commit message. That's it.
Now with the first commit contains the only the changes within bar()
function,
further hunks might be committed in the second commit:
I hope you have enjoyed the tip. ;)