DEV Community

Brian P. Hogan
Brian P. Hogan

Posted on • Originally published at smallsharpsoftwaretools.com

Split Changes into Multiple Commits

When working on a project, you might make several changes before you commit. However, these changes might relate to different features or bug fixes. For example, you might change a file to fix a bug, but you might see something else in the file that bugs you, so you fix it while you're there.

Committing all changes at once can lead to a messy, hard-to-understand commit history or a more complex code review process. Git lets you selectively stage parts of your changes instead of adding the whole file. Using this feature, you'll get a cleaner history with smaller units of work for peers to review, as well as a chance to deal with any out-of-scope work you still want to keep but commit elsewhere.

In this tutorial, you'll explore this feature by creating a small HTML project and staging your changes interactively.

What You Need

Git installed on your local machine.

Creating a Git project

To start, create a new directory and initialize a Git repository:

$ mkdir interactive-commit-demo $ cd interactive-commit-demo $ git init 
Enter fullscreen mode Exit fullscreen mode

Then create a basic HTML file called index.html:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Interactive Commit Demo</title> </head> <body> <h1>Welcome to My Website</h1> <p>This is a paragraph.</p> </body> </html> 
Enter fullscreen mode Exit fullscreen mode

Add and commit the file to your repository:

$ git add index.html $ git commit -m "Initial commit with basic HTML structure" 
Enter fullscreen mode Exit fullscreen mode

Now make two distinct changes to the file; change the title and add a new paragraph to the body of the page:

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Interactive Commit Tutorial</title> </head> <body> <h1>Welcome to My Website</h1> <p>This is a paragraph.</p> <p>This is a new paragraph we'll commit separately.</p> </body> </html> 
Enter fullscreen mode Exit fullscreen mode

You made two changes to this file, but putting them in the same commit might not be best. For example, the paragraph may be a change you can get approved quickly, but the page's title might need approval by SEO experts, and you don't want it to block the publication of the paragraph.

Adding Lines Interactively with git add -p

Use Git's Interactive mode to add only the lines you need.

Run the following command to start an interactive commit:

$ git add -p 
Enter fullscreen mode Exit fullscreen mode

You'll see the patch on the screen:

diff --git a/index.html b/index.html index 7b6e59a..0d63f4e 100644 --- a/index.html +++ b/index.html @@ -3,10 +3,11 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Interactive Commit Demo</title> + <title>Interactive Commit Tutorial</title>  </head> <body> <h1>Welcome to My Website</h1> <p>This is a paragraph.</p> + <p>This is a new paragraph we'll commit separately.</p>  </body> </html> (1/1) Stage this hunk [y,n,q,a,d,s,e,?]? 
Enter fullscreen mode Exit fullscreen mode

Press s to split the patch into separate pieces. The screen updates to show just the title change:

Split into 2 hunks. @@ -3,8 +3,8 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Interactive Commit Demo</title> + <title>Interactive Commit Tutorial</title>  </head> <body> <h1>Welcome to My Website</h1> <p>This is a paragraph.</p> (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? 
Enter fullscreen mode Exit fullscreen mode

Now press y to stage the title change. The next change appears, which is the change to the paragraph:

@@ -7,6 +7,7 @@ </head> <body> <h1>Welcome to My Website</h1> <p>This is a paragraph.</p> + <p>This is a new paragraph we'll commit separately.</p>  </body> </html> (2/2) Stage this hunk [y,n,q,a,d,K,g,/,e,?]? 
Enter fullscreen mode Exit fullscreen mode

Press n to skip this change for now. You'll return to your prompt.

Use the git status command, and you'll see that there are staged changes as well as unstaged changes:

$ git status 
Enter fullscreen mode Exit fullscreen mode
On branch main Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: index.html Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: index.html 
Enter fullscreen mode Exit fullscreen mode

Commit the title:

$ git commit -m "update title" 
Enter fullscreen mode Exit fullscreen mode

You'll see one line added and one line deleted, representing the title you changed:

[main 41d01ad] update title 1 file changed, 1 insertion(+), 1 deletion(-) 
Enter fullscreen mode Exit fullscreen mode

Now, use the same process again to add the paragraph change. Execute the following command:

$ git add -p 
Enter fullscreen mode Exit fullscreen mode

This time, the paragraph change patch appears:

diff --git a/index.html b/index.html index e0059db..0d63f4e 100644 --- a/index.html +++ b/index.html @@ -8,5 +8,6 @@ <body> <h1>Welcome to My Website</h1> <p>This is a paragraph.</p> + <p>This is a new paragraph we'll commit separately.</p>  </body> </html> (1/1) Stage this hunk [y,n,q,a,d,e,?]? 
Enter fullscreen mode Exit fullscreen mode

Press y to stage the change.

When you return to your prompt, commit the change:

$ git commit -m "add paragraph" 
Enter fullscreen mode Exit fullscreen mode

Verify your commits with git log:

$ git log --oneline 
Enter fullscreen mode Exit fullscreen mode

You'll see your initial commit along with the two additional ones you made:

bb403d9 (HEAD -> main) add paragraph 41d01ad update title aaa6f92 Initial commit with basic HTML structure 
Enter fullscreen mode Exit fullscreen mode

Using this approach, you were able to split the changes you made to a single file into two separate commits.

Sometimes, the lines may be too close together to use the automatic split feature, but you can manually edit the patch information. Consult the Git documentation on editing patches for more.

Conclusion

Splitting your changes into multiple commits gives you fine-grained control and lets you maintain a cleaner, more logical commit history, making your project easier to understand and manage.

Top comments (0)