NeuroAgent

How to Commit Partial Changes in Git: Complete Guide

Learn how to commit only part of a file's changes in Git using interactive staging with git add -p. Selectively stage specific hunks or lines for precise control over your commit history.

Question

How to commit only part of a file’s changes in Git

When I make changes to a file in Git, how can I commit only some of the changes?

For example, how could I commit only 15 lines out of 30 lines that have been changed in a file?

NeuroAgent

To commit only part of a file’s changes in Git, you can use the interactive staging feature with git add -p (or git add --patch), which allows you to selectively stage specific hunks or lines of changes before committing. This method displays your changes in chunks and lets you choose exactly which portions to include in your commit, enabling precise control over what gets saved in each commit.

Contents

Understanding Git Staging

Before diving into partial commits, it’s essential to understand how Git’s staging area works. In Git, the staging area (also called the index) acts as a buffer between your working directory and the repository. When you modify files, those changes exist in your working directory. When you run git add, you move specific changes from the working directory to the staging area, and then git commit saves those staged changes as a new commit.

The key insight here is that git add doesn’t have to add all changes in a file at once. By using the patch option, you can tell Git to add only specific portions of your changes to the staging area, which is exactly what you need when you want to commit only 15 out of 30 lines that you’ve changed.


Using git add -p for Partial Staging

The primary method for committing partial changes is using git add -p or its longer form git add --patch. This command initiates an interactive mode where you can selectively stage portions of your changes.

Basic Usage

To start staging parts of a specific file:

bash
git add -p filename.ext

Or for all modified files:

bash
git add -p

When you run this command, Git will analyze your changes and break them down into logical chunks called “hunks.” A hunk represents a contiguous block of changes that logically belong together - typically a related set of additions, removals, or modifications.

The Interactive Process

Once you run git add -p, Git will present you with each hunk of changes and prompt you with:

Stage this hunk [y,n,a,d,/,j,J,g,e,?]?

You can then respond with one of the many options to control what gets staged. Let’s explore what each of these options means and how they help you achieve your goal of committing only specific lines.


Interactive Staging Commands and Options

The interactive staging mode offers numerous options for fine-tuning what gets staged. Here’s a comprehensive breakdown of the available commands:

Basic Response Options

  • y - Stage this hunk
  • n - Don’t stage this hunk
  • q - Quit; don’t stage any more hunks
  • ? - Show help with the available options

Bulk Options

  • a - Stage this hunk and all remaining hunks in the file
  • d - Do not stage this hunk nor any of the remaining hunks in the file

Navigation and Selection

  • 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

Advanced Editing Options

  • s - Split the current hunk into smaller hunks (useful when you want to stage part of a hunk)
  • e - Manually edit the current hunk (for precise line-level control)
  • / - Search for a hunk matching the given regex pattern
  • g - Select a hunk to go to

Example Scenario

Let’s say you’ve modified a file and have 30 lines of changes that you want to split into two commits - one with 15 lines and another with 15 lines. Here’s how you’d do it:

bash
# Start interactive staging
git add -p yourfile.js

# Git will show you hunks one by one
# For the first 15 lines you want to commit, press 'y'
# For the next 15 lines you don't want in this commit, press 'n'

# Then commit the staged changes
git commit -m "Commit message for first 15 lines"

# Now stage the remaining changes
git add -p yourfile.js

# This time, stage the remaining hunks with 'y'
git commit -m "Commit message for the remaining 15 lines"

Alternative Methods for Partial Commits

While git add -p is the most common method, there are other approaches you can use depending on your workflow and preferences.

Using git add --interactive

The git add --interactive command provides a menu-driven interface for staging changes. It offers several subcommands including:

  • status - Show current changes
  • update - Add/modify files in the index (this is similar to git add -p)
  • revert - Revert changes in the index
  • add - Add files to the index
  • patch - Select hunks interactively (same as git add -p)

Editor-based Editing with git add -e

For more precise control, you can use git add -e which opens your default editor to directly edit the patch that will be staged. This method requires understanding the patch format but offers maximum precision:

bash
git add -e filename.ext

IDE/Editor Integration

If you’re using VS Code or other modern editors, you may have built-in support for partial staging:

  • VS Code: Select the range you want to stage, then use “Git: Stage Selected Ranges”
  • Other editors: Many Git GUI tools offer similar visual selection capabilities

Practical Example Workflow

Let’s walk through a complete example of committing only part of a file’s changes:

Step 1: Check Your Changes

bash
git status
git diff

This shows you what files have been modified and what the changes look like.

Step 2: Start Interactive Staging

bash
git add -p important-file.js

Step 3: Review and Select Changes

Git will now show you hunks of changes. For each hunk, you’ll see something like:

diff --git a/important-file.js b/important-file.js
index abc123..def456 100644
--- a/important-file.js
+++ b/important-file.js
@@ -10,6 +10,21 @@
   function processData() {
-    // Old implementation
+    // New improved implementation
+    const result = data.map(item => {
+      return transform(item);
+    });
+
+    return result.filter(item => item.isValid);
   }

+  function transform(item) {
+    // New helper function
+    return {
+      ...item,
+      processed: true
+    };
+  }
+
 Stage this hunk [y,n,a,d,/,j,J,g,e,?]?

Step 4: Make Your Selections

For this example, let’s say you want to commit only the new transform function but not the changes to processData. You would:

  1. Press n for the first hunk (changes to processData)
  2. Press y for the second hunk (new transform function)
  3. Press q to quit if there are no more hunks

Step 5: Commit the Staged Changes

bash
git commit -m "Add transform helper function"

Step 6: Handle the Remaining Changes

Now you need to decide what to do with the remaining changes:

bash
# Option 1: Stage and commit them separately
git add -p important-file.js
git commit -m "Improve processData function"

# Option 2: Keep them uncommitted for now
git status

Best Practices for Partial Commits

When working with partial commits, consider these best practices to maintain a clean and logical commit history:

1. Group Related Changes

Only stage hunks that belong together logically. If you’re working on multiple features in the same file, try to stage changes for one feature at a time.

2. Review Before Committing

Always review what you’ve staged before committing:

bash
git diff --staged

This shows you exactly what will be included in the next commit.

3. Use Descriptive Commit Messages

Since your commits will be more focused, make sure your commit messages clearly describe what each commit contains.

4. Consider Atomic Commits

Each commit should be atomic - meaning it should represent a single logical change or a group of closely related changes. This makes your history easier to understand and revert if needed.

5. Be Careful with Merges

When merging branches with partial commits, be aware that conflicts can be more complex since you’re dealing with partial file changes.

6. Learn the Shortcuts

Memorize the most common interactive staging options (y, n, s, e, ?) to work more efficiently.

By mastering partial commits, you gain much greater control over your Git workflow and can maintain a cleaner, more logical project history that reflects the actual progression of your work.

Sources

  1. Git - Interactive Staging - Official Git documentation explaining the interactive staging process
  2. Commit only part of a file’s changes in Git - Stack Overflow - Community discussion with practical examples
  3. How to Use Git to Partially Commit File Changes - Step-by-step guide with examples
  4. Git staging specific modifications - Detailed explanation of the staging process
  5. Using Git Line Staging to Commit Parts of Files - Advanced techniques for precise control
  6. Git add --patch and --interactive - Comprehensive explanation of patch and interactive options
  7. Git Interactive Staging — A simple way to logically separate commits - Practical approach to organizing commits
  8. Explaining the ‘git add -p’ command (with examples) - Tutorial with concrete examples

Conclusion

Committing only part of a file’s changes in Git is a powerful technique that gives you precise control over your project history. By using git add -p or git add --patch, you can interactively select which hunks or lines to stage before committing, allowing you to create atomic, focused commits that represent logical units of work.

The key steps are:

  1. Use git add -p filename to start interactive staging
  2. For each hunk presented, choose to stage (y), skip (n), split (s), or edit (e) as needed
  3. Review staged changes with git diff --staged
  4. Commit with git commit -m "descriptive message"

This approach is particularly valuable when working on multiple features in the same file, when you need to separate experimental changes from stable code, or when you want to maintain a clean, logical commit history. With practice, you’ll find that partial commits significantly improve your Git workflow and make version control more effective for your development process.