Step-by-Step with Git: Advanced Commit Strategies

Let’s use a practical example to guide us through this process. By the end of this tutorial, you'll understand how to commit changes selectively, review modifications, and manage staged and unstaged changes.

Step-by-Step with Git: Advanced Commit Strategies
Photo by Farhat Altaf / Unsplash

In this post, we’ll dive deep into advanced committing in Git. We'll explore how to create and merge local commits effectively while maintaining clarity and organization in your codebase. Let’s use a practical example to guide us through this process. By the end of this tutorial, you'll understand how to commit changes selectively, review modifications, and manage staged and unstaged changes.

This post takes a more hands-on approach to mastering advanced Git commits. Rather than diving into theory, we'll explore practical examples to show how to create, manage, and refine local commits effectively in real-world scenarios. Let's get our hands dirty with Git!

1. Setting Up the Playground

We begin by setting up a sample Git repository to demonstrate advanced committing techniques.

1.1 Reviewing the Project Directory

Let’s first list the contents of our project folder:

$ ls -la 
total 9 
drwxr-xr-x 1 CZC1PR 1049089  0 Nov 30 09:18 ./ 
drwxr-xr-x 1 CZC1PR 1049089  0 Nov  9 09:27 ../ 
drwxr-xr-x 1 CZC1PR 1049089  0 Dec  1 08:46 .git/ 
drwxr-xr-x 1 CZC1PR 1049089  0 Nov 30 09:18 devops/ 
-rw-r--r-- 1 CZC1PR 1049089 32 Nov 30 09:12 README.md

The repository contains:

  • A README.md file.
  • A devops/ folder for Jenkins job examples.

1.2 Creating a Temporary Folder

For this session, let’s create a new tmp/ folder and add two files:

$ mkdir tmp
$ touch tmp/file01 tmp/file02

Verify the contents:

$ ls -la tmp/ 
total 0 
drwxr-xr-x 1 CZC1PR 1049089 0 Dec 12 08:35 ./ 
drwxr-xr-x 1 CZC1PR 1049089 0 Dec 12 08:34 ../ 
-rw-r--r-- 1 CZC1PR 1049089 0 Dec 12 08:35 file01 
-rw-r--r-- 1 CZC1PR 1049089 0 Dec 12 08:35 file02

2. Adding Content to Files

Add content to these files using the echo command:

$ echo "This is new file #1" > tmp/file01
$ echo "This is new file #2" > tmp/file02

Check the contents of the files:

$ cat tmp/file01
This is new file #1

$ cat tmp/file02
This is new file #2

3. Staging Changes

3.1 Initial git status

Run git status to see the current state of the repository:

$ git status
On branch main 
Your branch is up to date with 'origin/main'. 
Untracked files: 
  (use "git add <file>..." to include in what will be committed) 
        tmp/

3.2 Adding the tmp/ Folder to Staging

Add the folder to the Git repository:

$ git add tmp/

Now, check the status again:

$ git status 
On branch main 
Your branch is up to date with 'origin/main'. 
Changes to be committed: 
  (use "git restore --staged <file>..." to unstage) 
        new file:   tmp/file01 
        new file:   tmp/file02

3.3 Committing the Staged Changes

Commit the changes with a meaningful message:

$ git commit -m "Added tmp folder with initial files"
[main 891defa] Added tmp folder with initial files 
 2 files changed, 2 insertions(+)
 create mode 100644 tmp/file01
 create mode 100644 tmp/file02

4. Making and Staging Changes Selectively

4.1 Modifying file01

Add a new line to file01:

$ echo "This is new line for file #1" >> tmp/file01

Verify the content:

$ cat tmp/file01
This is new file #1
This is new line for file #1

Check the status:

$ git status 
On branch main 
Your branch is ahead of 'origin/main' by 1 commit. 
Changes not staged for commit: 
  (use "git add <file>..." to update what will be committed) 
        modified:   tmp/file01

4.2 Using git diff

View the differences:

$ git diff
diff --git a/tmp/file01 b/tmp/file01 
index 350b4fc..6335f6d 100644 
--- a/tmp/file01 
+++ b/tmp/file01 
@@ -1 +1,2 @@ 
 This is new file #1 
+This is new line for file #1

5. Selective Commit with git add --patch

Now let’s modify file02 to demonstrate selective staging:

$ echo "This is new line for file #2" >> tmp/file02

Run git diff again:

$ git diff
diff --git a/tmp/file01 b/tmp/file01 
@@ -1 +1,2 @@ 
 This is new file #1 
+This is new line for file #1
diff --git a/tmp/file02 b/tmp/file02 
@@ -1 +1,2 @@ 
 This is new file #2 
+This is new line for file #2

5.1 Interactive Staging with --patch

Use the --patch option to stage changes interactively:

$ git add --patch
diff --git a/tmp/file01 b/tmp/file01
@@ -1 +1,2 @@
 This is new file #1
+This is new line for file #1
(1/1) Stage this hunk [y,n,q,a,d,e,?]? y

diff --git a/tmp/file02 b/tmp/file02
@@ -1 +1,2 @@
 This is new file #2
+This is new line for file #2
(1/1) Stage this hunk [y,n,q,a,d,e,?]? n

5.2 Checking Staged and Unstaged Changes

Check the status:

$ git status
Changes to be committed:
        modified:   tmp/file01

Changes not staged for commit:
        modified:   tmp/file02

5.3 Committing Changes

Commit the staged changes:

$ git commit -m "Updated file01 with additional line"

6. Best Practices for Advanced Committing

  • Use git add --patch to stage changes selectively.
  • Keep commits small and focused on a single purpose.
  • Write descriptive commit messages to improve project traceability.
  • Use git diff and git diff --staged to review changes before committing.

Conclusion

Selective staging and advanced committing in Git are invaluable tools for managing complex projects. By breaking changes into logical commits, you make your history cleaner, debugging easier, and collaboration smoother. With practice, you’ll master these techniques, elevating your Git workflow to the next level.

Read next

Automating Tests and Builds Based on Git Branches

In modern software development, automating your testing and build processes based on different Git branches is a crucial practice. This automation ensures that your CI/CD pipelines run the right tests and builds on the right code, according to where the code lives in the Git branching strategy.

Setting Up a Git Webhook to Trigger Jenkins Jobs

Automation is the key to ensuring a efficient software development lifecycle. The most common automations is integrating Git with Jenkins to trigger builds, tests, or deployments upon changes are pushed to a repository. Using webhooks a mechanism that allows Git to notify Jenkins about events.

Recovering Lost Work Using Git Reflog

One of the most common fears when working with Git is accidentally losing work due to mistakes like resetting the repository to an older commit, overwriting changes, or mistakenly deleting a branch. Luckily, Git has a powerful tool that helps you recover from these situations: Git Reflog.