Explaining the ‘git add -p’ command (with examples)

Updated: January 27, 2024 By: Guest Contributor Post a comment

The ‘git add’ command is a vital part of any Git user’s workflow, allowing for staged changes to be included in the next commit. However, what can one do when they need more control over exactly which changes get staged? This is where the power of partial staging with ‘git add -p’ comes into play. This tutorial covers the basics and progresses to advanced usage, providing practical examples to illustrate how ‘git add -p’ can enhance your version control workflow.

Introduction to ‘git add -p’

Git is a distributed version control system designed to handle projects ranging from small to very large with speed and efficiency. One of its main features is the staging area, where you can prepare your changes before committing them. With the ‘git add’ command, you can add file changes to the staging area, but this command adds all changes in a file by default.

To add more precision to this process, Git supports the ‘-p’ (or ‘–patch’) option with the ‘git add’ command. Using ‘git add -p’, you can stage parts of a file—hunks of changes—rather than the whole file. This is especially useful when you’ve made multiple changes to a file but want to commit them separately to keep the project history clean and coherent.

Basic Usage of ‘git add -p’

To demonstrate the ‘git add -p’ command, consider a simple file named ‘example.txt’ with the following content:

Line 1
Line 2
Line 3

Let’s say you’ve made changes to ‘example.txt’, resulting in the following lines:

Line 1 - modified
Line 2 - unchanged
Line 3 - added new content

To start an interactive staging session, run the following command:

git add -p example.txt

Git will now display the first ‘hunk’ of changes and prompt you for an action:

diff --git a/example.txt b/example.txt
index 46d5f99..3ae4f6b 100644
--- a/example.txt
+++ b/example.txt
@@ -1,3 +1,3 @@
-Line 1
+Line 1 - modified
 Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? 

Here, you can decide to stage (‘y’), skip (‘n’), quit (‘q’), and more. If you press ‘y’, Git will stage this change and proceed to the next hunk.

Explanation of Options

During ‘git add -p’, you’re presented with several options for handling each hunk. The most common are:

  • y – stage this hunk for the next commit
  • n – do not stage this hunk
  • q – quit; do not stage this hunk or any of the remaining hunks
  • 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
  • e – manually edit the current hunk
  • ? – print help

Edit a Hunk Manually

Sometimes, the suggested hunk does not match exactly what you want to stage. In this case, you can edit the hunk manually by typing ‘e’. This will open the hunk in your text editor. Lines starting with a ‘+’, ‘-‘, or space character are additions, deletions, or unchanged. You can manually edit this by changing:

  • + to – to unstage an addition
  • to – to discard a deletion
  • to + – to split or reduce

Here’s an example where we choose to only stage part of the changes:

--- a/example.txt
+++ b/example.txt
@@ -1,3 +1,3 @@
-Line 1
+Line 1 - modified
 Stage this hunk [y,n,q,a,d,e,?]? e

After typing ‘e’, the editor might show something like:

-Line 1
+Line 1 - modified

To stage only the addition without the modification, you could change it to:

 Line 1
+Line 1 - modified

Advanced Options

For more nuanced control over staging, a few advanced options exist within ‘git add -p’, such as:

  • Splitting hunks: ‘git add -p’ may group changes closely together into a large hunk. If you only want to stage part of these changes, you can split the hunk into smaller, more manageable pieces.
  • Staging untracked files: You can initiate an interactive add session with untracked files by running ‘git add -N’ followed by ‘git add -p’.

Real-World Example

Here’s a detailed example to illustrate how git add -p (patch mode) can be used in a real-world scenario where you want to stage and commit different sections of changes in a file separately.

Let’s say you have a file named code.js, and you’ve made three distinct modifications in different sections of this file. Each modification relates to a different feature or bug fix. To commit these changes separately for better clarity and history management, you can use git add -p.

# Check the current status of the repository
git status

# Start interactive staging for a specific file
git add -p code.js

# Interactive mode begins
# For each hunk, choose 'y' to stage, 'n' to skip, 'q' to quit, '?' for help

# Commit the staged changes with a descriptive message for the first feature
git commit -m "Feature 1 related changes in code.js"

# Repeat the interactive staging for the same file
git add -p code.js

# Commit the staged changes for the second feature
git commit -m "Feature 2 related changes in code.js"

# Repeat for other features or fixes, as needed
# ...

# Final status check
git status

# Optionally, commit or stash any remaining changes
# git commit -m "Remaining changes in code.js"
# or
# git stash

Repeat the process as necessary for each distinct set of changes you want to commit separately.

Conclusion

Throughout this guide, we’ve explored how ‘git add -p’ offers precise control when staging changes. By understanding and leveraging the interactive options available with ‘git add -p’, you can create cleaner commits that are easier to review and maintain.