Git interactive add with --patch and --interactive

Learn how to use Git's interactive add command with --patch and --interactive flags
Published 2023-03-12 7 min read
Git interactive add with --patch and --interactive

By default git add command stages selected files. However, sometimes developers may not want to stage all changes at once. For example, they may have made changes to multiple files but only want to stage some of those changes. This is where git’s interactive add comes in handy.

Interactive add is a git command that allows developers to selectively stage changes using a user-friendly interface. Developers can choose to stage specific lines or chunks of code within a file, or choose to stage specific files altogether. It’s super useful for doing mini pre-commit review and in my opinion should be a default mode in use. Another scenario is splitting changes to more than one commit.

In this article, we’ll explore how to use git’s interactive add with the --patch and --interactive flags, and provide examples of how it can be used in practice. Also, we’ll go through scenarios for using -p with git reset and git commit commands.

 

“—patch” or “—interactive”?

As you probably expect, there are two methods to go in some kind of interactive mode while staging.

One way to use interactive add is with the --patch flag, -p for short. This flag allows developers to review changes within a file and selectively stage only the changes they want to include in the commit.

Another way to use interactive add is with the --interactive flag, -i for short. This flag allows developers to choose which files they want to stage, as well as which changes within those files they want to stage. 

--patch method is preferred in most scenarios, but --interactive is more powerful, yet also more cumbersome.

 

Git interactive add with “—patch”

The --patch flag is one way to use interactive add in Git. This flag allows developers to selectively stage changes within a file by presenting a user-friendly interface that displays the changes and allows developers to choose which changes to stage.

To use --patch interactive add, developers can use the following command:

$ git add -p

This will open up the interactive add interface for all unstaged changes, excluding ones in binary files. The interface displays the changes made to the files and allows the developer to choose which changes to stage. This looks like this:

ak:~/devel/devprogrammer (main) > git add -p
diff --git a/config/application.rb b/config/application.rb
index f49e6a9..5a00572 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -1,5 +1,4 @@
 require_relative 'boot'
-
 require 'rails/all'

 # Require the gems listed in Gemfile, including any gems
(1/1) Stage this hunk [y,n,q,a,d,e,?]?

You can see that each change is called hunk. You can also see that there are quite a few options. This is what they mean:
y - stage this hunk
n - do not stage this hunk
a - stage this and all the remaining hunks in the file
d - do not stage this hunk nor any of the remaining 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

If you are interested in reviewing only one file you can do it as follows:

$ git add -p <filename>

Using -p with revert and commit

-p flag can be used with git reset command. It works exactly the same, but it unstages the changes instead of staging them. Another option is to use -p with git commit, if you feel brave. Again - works the same as git add, but results in committing selected changes, not in staging them.

 

Git interactive add with “—interactive”

Ok, from my point of view using this mode is a waste of time in most cases, since the interface is not stellar. But… there are some scenarios, where it can be useful. For example when there is a need to commit only a few files out of a big lot.

--interactive flag allows you to manage the staging area via interactive menus and move changes to and from it with granular control. Unfortunately, the UI is cumbersome and describing the idea behind it without showing the steps is pointless.

So, let’s look at the example:

ak:~/devel/devprogrammer (main) > git add -i
           staged unstaged path
  1: unchanged +0/-1 config/application.rb
  2: unchanged +1/-1 config/environment.rb
  3: unchanged +0/-1 config/routes.rb

***Commands***
  1: status 2: update 3: revert 4: add untracked
  5: patch 6: diff 7: quit 8: help

 

You can see a list of changes, one line is information about one file. There are 3 columns:

staged - shows how many lines changed and are staged
unstaged - show how many lines changed and are unstaged
path - yup, it’s a path to a changed file

Then there are commands, to get how they work we’ll choose option u:

What now> u
           staged unstaged path
  1: unchanged +0/-1 config/application.rb
  2: unchanged +1/-1 config/environment.rb
  3: unchanged +0/-1 config/routes.rb

 

This is a list of all files with unstaged changes, let’s say we would like to add the first file, so we’ll type 1.

Update>> 1
           staged unstaged path
* 1: unchanged +0/-1 config/application.rb
  2: unchanged +1/-1 config/environment.rb
  3: unchanged +0/-1 config/routes.rb

See - now the first file has “*” on the left. To accept this choice we need to press enter with an empty prompt. This updates our file and, as our status suggests, we successfully moved the first file to staging area! 

What now> s
           staged unstaged path
  1: +0/-1 nothing config/application.rb
  2: unchanged +1/-1 config/environment.rb
  3: unchanged +0/-1 config/routes.rb

Of course, we can select multiple files with this tool. 

As you saw there were a few commands.

1: status 2: update 3: revert 4: add untracked
  5: patch 6: diff 7: quit 8: help

 

status - current status
update - will add selected files to staging area
revert - will unstage selected files
add untracked - yeah, pretty much what it says ;)
patch - will allow you to go with --patch process on selected files
diff - allows showing diff

Hope you can see the possibilities now. You can move files to and from staging area pretty easily using this mode.

 

In conclusion

And that’s it! Now you know how to use Git’s interactive add with --patch and --interactive flags to selectively stage changes. The --patch method is preferred in most scenarios as it allows you to review changes within a file and selectively stage only the changes you want to include in the commit. However, the --interactive flag is more powerful, yet more cumbersome, and can be useful in scenarios where you only want to commit a few files out of a large number of changes. Remember you can use the -p flag with git reset command to unstage changes or with git commit command to commit selected changes. Happy coding!

#git #cli