Advanced Git Workflows for DevOps: Stash, Rebase, Diff, and Cherry-Pick

Welcome back, folks! I hope you had a solid grasp of Branching and Merging from our last blog. Building on that foundation, today, we’re diving into some powerful advanced Git techniques that will take your workflow to the next level.

As a DevOps Engineer, mastering Git isn’t just about version control—it’s about managing infrastructure as code, optimizing CI/CD pipelines, and ensuring smooth collaboration. While you’re already familiar with commits, merges, and add, techniques like Rebasing, Stashing, Diff, and Cherry-Picking will help you keep your workflow clean, efficient, and error-free.

So, buckle up! This is going to be fun. Let’s get started.


Git Stash: Save Work Without Committing

What is Git Stash?

git stash allows you to temporarily save uncommitted changes without committing them, so you can switch branches or pull updates without losing your work.

When to Use Git Stash in DevOps?

  • When you need to quickly switch branches but don’t want to commit incomplete work.

  • When working on a hotfix branch and need to temporarily save ongoing work.

  • Before pulling the latest changes to avoid conflicts with uncommitted work.


Git Stash Example (Step-by-Step)

Scenario:
You're working on a new feature in a shell script (deploy.sh) on a feature branch (feature-branch). Before committing, you realize you need to switch to another branch (main), but Git won't allow it because of uncommitted changes.
This is where git stash helps.

Step 1: Create a New Feature Branch

git checkout -b feature-branch

This creates and switches to a new branch named feature-branch.

Step 2: Create a New File (deploy.sh)

echo "echo Deploying application..." > deploy.sh

This creates a shell script file with a simple echo statement.

Step 3: Add the File to Staging

git add deploy.sh

Now the file is staged but not yet committed.

Step 4: Modify the File Again (Without Committing)

echo "echo Application deployed successfully!" >> deploy.sh

You've added another line to, deploy.shbut it’s still uncommitted.

Step 5: Try Switching to main

git checkout main

🚫 Error: Git won’t let you switch branches because of uncommitted changes.

Step 6: Use Git Stash to Save Changes Temporarily

git stash

Now, deploy.sh is stashed, and your working directory is clean.

Step 7: Switch to main Successfully

git checkout main

Now you can switch without issues.

Step 8: Switch Back to feature-branch and Apply Stash

git checkout feature-branch
git stash apply

This restores the uncommitted changes.

Step 9: Commit the Changes

git add deploy.sh
git commit -m "Add deploy script"

Step 10: Verify Stash is Removed

git stash list

The stash no longer exists because git stash apply restores the changes but does not remove them from the stash list.
If you want to apply and remove the stash in one step, use:

git stash pop

Git Rebase: Clean Alternative to Merging & Clean Commit History

What is Git Rebase?

Git rebase allows you to integrate changes from one branch into another by rewriting the commit history, making it appear as if the changes were developed sequentially. Compared to merging, this results in a cleaner and more linear commit history.

🔹 Merge vs. Rebase

  • Merging creates a new merge commit, preserving the original history.

  • Rebasing moves the entire branch to the latest base, rewriting commit history as if changes were made on top of the latest main branch.

When to Use Rebase in DevOps?

  • To keep feature branches updated with the latest changes from main.

  • Maintaining a linear commit history and avoiding unnecessary merge commits.


Git Rebase Example (Step-by-Step)

Scenario:
You're working on feature-branch, and main has new updates. You need to update your branch with the latest changes while keeping a clean history.

Step 1: Switch to main and Make Changes

git checkout main
echo "echo Welcome to the application!" > welcome.sh
git add welcome.sh
git commit -m "Add welcome script"

Now, the main branch has a new commit.

Step 2: Switch Back to feature-branch

git checkout feature-branch

Step 3: Rebase feature-branch onto main

git rebase main

  • Git will move all your commits on feature-branch to the top of main, keeping a linear history.

  • If there are conflicts, Git will prompt you to resolve them.

Step 4: Resolving Conflicts (If Any)

If there's a conflict, Git will show a message like:

CONFLICT (content): Merge conflict in deploy.sh

To fix it:

  1. Open the file and manually resolve the conflict.

  2. Stage the resolved file:

     git add deploy.sh
    
  3. Continue the rebase:

     git rebase --continue
    

Step 5: Successfully Rebasing

Once rebase is complete, feature-branch will be updated with main, and all your commits will appear on top.

Verify Linear History

git log --oneline --graph
# Output:  
# * a022151 (HEAD -> feature-branch) Add deploy script
# * 9096640 (main) Add welcome script

🚨 Avoid --force unless necessary, as it can overwrite others' work.


DevOps Use Cases for Git Rebase

🔹 Use Case 1: Keeping Infrastructure as Code (IaC) Up to Date
In a Terraform-based infrastructure project, multiple engineers work on different branches. Instead of merging their changes, rebasing ensures their local changes are always on top of the latest main, avoiding unnecessary merge commits.

🔹 Use Case 2: Smoother CI/CD Pipeline Updates
If a DevOps team is modifying a Jenkins pipeline (Jenkinsfile) in a feature branch, rebasing ensures they always build on the latest pipeline improvements, reducing conflicts and maintaining a clean history.


Git Diff: Compare Changes in Git

The git diff command helps you compare changes between different states in Git—working directory, staging area, commits, and branches.

Understanding Git Diff Output

  • a -> file 1 and b -> file 2

  • ---- indicates the file 1

  • +++ indicates the file 2

  • @@ indicates the line number

Here, files 1 and 2 are the same file but in different versions.

Git will show you the changes made in the file 1 and the file 2. It will also show you the line number where the change occurred, along with a little preview of the change.

Example Output:

--- a/script.sh
+++ b/script.sh
@@ -1,2 +1,3 @@
 echo "Deploying..."
+echo "Deployment successful!"

🔹 + echo "Deployment successful!" → New line added.


Common Git Diff Commands

View Unstaged Changes

git diff

🔹 Shows changes not yet staged.

View Staged Changes (Ready to Commit)

git diff --staged

🔹 Compares staged files with the last commit.

Compare Two Branches

git diff main feature-branch

🔹 Shows changes in feature-branch compared to main.

Compare Two Commits

git diff <commit1> <commit2>

🔹 Shows differences between two specific commits.


Summary Table

CommandPurpose
git diffCompare working directory with the last commit
git diff --stagedCompare staged changes with the last commit
git diff branch1 branch2Compare two branches
git diff commit1 commit2Compare two commits

Git Cherry-Pick: Selectively Applying Commits

What is Git Cherry-Picking?

Cherry-picking in Git allows you to apply specific commits from one branch to another without merging the entire branch.

When to Use Cherry-Picking in DevOps?

  • When you need to apply a critical fix from a feature branch to main without merging all changes.

  • When specific commits from a long-running branch need to be applied elsewhere without integrating the entire branch.


Step-by-Step: Using Git Cherry-Pick

1️⃣ Identify the commit you want to cherry-pick

git log --oneline

(Find the commit hash of the change you need.)

2️⃣ Switch to the target branch

git checkout main

3️⃣ Cherry-pick the commit

git cherry-pick <commit-hash>

(This applies the selected commit to main without merging the entire branch.)

4️⃣ Push the changes to the remote repository

git push origin main

DevOps Use Cases for Git Cherry-Pick

🔹 Use Case 1: Hotfix Deployment Without Merging Unfinished Work
Imagine you’re working on a new feature branch, but a bug fix is needed immediately. Instead of merging the entire feature branch (which isn’t finished), you cherry-pick the bug fix commit and push it to main for deployment.

🔹 Use Case 2: Selective CI/CD Pipeline Changes
If a specific commit improves the Jenkins pipeline but isn’t yet part of a completed feature branch, cherry-picking lets you apply just that commit to main without merging all changes.


Best Practices

Best PracticesWorkflowWhen to UseDevOps Example
RebaseLocal feature branches.Sync with the latest main.Sync Terraform modules with the latest main.
StashUnfinished work needing interruption.Pause work temporarily.Pause Ansible updates to fix a server.
DiffCompare working directory.Check code changes before commit.Compare infrastructure changes in an AWS CloudFormation template.
Cherry-PickSelective commits across branches.Apply specific changes without merging everything.Apply a Dockerfile fix to multiple environments.

Final Thoughts

  • Git Rebase helps maintain a clean, linear commit history, reducing merge commit clutter.

  • Git Stash allows DevOps engineers to save work-in-progress changes temporarily without committing.

  • Git Diff helps identify code changes between commits, branches, or the working directory, ensuring better version control and troubleshooting.

  • Git Cherry-Pick helps selectively apply specific commits without merging entire branches.

By mastering these techniques, DevOps teams can ensure a smoother development workflow, better CI/CD practices, and efficient collaboration.


Alright, folks! We’ve covered some powerful advanced Git commands today. I know, I know—some of you might still be wrapping your head around these commands. But hey, don’t stress! Mastery comes with practice, and the more you use these in real-world scenarios, the more intuitive they’ll become. So take your time, experiment, and make Git your best friend.

What’s next?
Our final blog in this Git & GitHub series is up next—‘Collaborating with GitHub’! This is where we tie everything together and learn how teams work efficiently using GitHub. Excited? Me too! See you in the next one.

Until next time, keep coding, automating, and advancing in DevOps! 😁

Peace out ✌️

0
Subscribe to my newsletter

Read articles from Rajratan Gaikwad directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rajratan Gaikwad
Rajratan Gaikwad

I write about the art and adventure of DevOps, making complex topics in CI/CD, Cloud Automation, Infrastructure as Code, and Monitoring approachable and fun. Join me on my DevOps Voyage, where each post unpacks real-world challenges, explores best practices, and dives deep into the world of modern DevOps—one journey at a time!