Voiced by Amazon Polly |
Git is a powerful version control tool, and while commands like git commit, git push, and git pull are commonly used, advanced Git commands can significantly enhance your workflow. In this blog, we will dive into five key Git commands that every advanced Git user should know: rebase, squash, cherry-pick, reflog, and stash.
Customized Cloud Solutions to Drive your Business Success
- Cloud Migration
- Devops
- AIML & IoT
1. Git Rebase
What is it?
git rebase is a way to move or combine a series of commits onto a new base commit. It allows you to take changes from one branch and integrate them into another in a linear fashion, avoiding the creation of merge commits.
Why use it?
- Cleaner History: It keeps your commit history cleaner compared to merge, which introduces merge commits.
- Better Collaboration: When collaborating, it helps avoid unnecessary commits and keeps the project history streamlined.
Usage Example:
# Move your branch commits on top of another branch (say, master)
1 |
git checkout feature-branch |
1 |
git rebase master |
This will take the commits from feature-branch and apply them on top of the master branch, resulting in a linear history.
2. Git Squash
What is it?
Squashing refers to combining multiple commits into one. It’s particularly useful when you want to tidy up a series of small or experimental commits before merging them into a main branch.
Why use it?
- History Cleanup: Keeps history concise by combining multiple small changes into a single meaningful commit.
- Avoiding Noise: Removes unnecessary commits like “fix typo” or “final changes”.
Usage Example:
During an interactive rebase:
1 |
git rebase -i HEAD~n |
In the editor, change the word pick to squash for the commits you want to combine:
1 2 3 4 5 |
pick abc123 First commit squash def456 Second commit squash ghi789 Third commit |
This will combine the three commits into one, letting you reword the commit message as desired.
3. Git Cherry-Pick
What is it?
git cherry-pick allows you to select specific commits from one branch and apply them onto another branch. This is extremely useful when you need just one or a few changes from another branch without merging the entire branch.
Why use it?
- Selective Commit Application: Helps apply specific changes across branches.
- Efficient Bug Fixes: Useful when you need to apply a bug fix from a feature branch to a release branch.
Usage Example:
# Apply a specific commit to the current branch
1 |
git cherry-pick <commit-hash> |
This applies the changes from <commit-hash> onto your current branch.
4. Git Reflog
What is it?
git reflog is a way to view the history of your Git commands on your local machine. It tracks every action, including commits that may have been lost or orphaned due to resets or rebases.
Why use it?
- Recover Lost Commits: If you accidentally delete or lose track of commits, reflog can help recover them.
- Undo Mistakes: It helps you navigate through previous states of the repository.
Usage Example:
# Show all recent actions, including commits, branch changes, etc.
1 |
git reflog |
From the reflog, you can use git checkout or git reset to return to a previous state.
5. Git Stash
What is it?
git stash allows you to temporarily save changes that are not yet ready to be committed and return to a clean working directory. You can then reapply these changes at a later time.
Why use it?
- Work in Progress: If you’re working on a feature but need to switch branches temporarily, you can stash your changes instead of committing half-done work.
- Quick Switch: It helps you switch contexts quickly without leaving uncommitted changes.
Usage Example:
# Save your uncommitted changes
1 |
git stash |
# Reapply the stashed changes later
1 |
git stash pop |
Hands-On: Git Workflow with Rebase, Squash, Cherry-Pick, Reflog, and Stash
In this lab, we will simulate a development workflow where all five advanced Git commands—rebase, squash, cherry-pick, reflog, and stash—are used. This will help you understand how they interact in real-world scenarios.
Lab Setup:
- Two branches: master and feature
- master has production code, while feature has development work-in-progress
- You’ll simulate fixing bugs, refactoring code, and collaborating with other developers.
Step 1: Initialize the Repository
Start by initializing a Git repository and creating two branches.
# Initialize a repository
1 2 3 |
git init advanced-git-lab cd advanced-git-lab |
# Create some initial files
1 2 3 4 5 |
echo "Initial Production Code" > file1.txt git add . git commit -m "Initial commit on master" |
# Create a feature branch
1 |
git checkout -b feature |
Now, you are on the feature branch.
Step 2: Create Multiple Commits (Prepare for Squashing)
On the feature branch, add multiple commits simulating work on a new feature.
1 2 3 4 5 |
echo "Feature Work - Part 1" > feature.txt git add feature.txt git commit -m "Feature Work Part 1" |
1 2 3 4 5 |
echo "Feature Work - Part 2" >> feature.txt git add feature.txt git commit -m "Feature Work Part 2" |
1 2 3 4 5 |
echo "Fix typo in feature" >> feature.txt git add feature.txt git commit -m "Fix typo in feature" |
At this point, your commit history contains multiple small commits. Before merging this work into master, you want to clean up the history by squashing them.
Step 3: Squash Commits
Now, you will combine the three commits into one using git rebase.
# Start interactive rebase for the last 3 commits
1 |
git rebase -i HEAD~3 |
In the editor, modify the commands so that only the first commit remains as pick and the others are set to squash.
1 2 3 4 5 |
pick 123abc Feature Work Part 1 squash 456def Feature Work Part 2 squash 789ghi Fix typo in feature |
Save and close the editor. You will be prompted to reword the commit message, so give it a clean and concise description:
1 |
Feature completed with fixes |
Now, your feature branch history is cleaned up into a single commit.
Step 4: Rebase Feature Branch onto Master
Let us say another developer has made changes to master while you were working on the feature branch. To integrate your feature branch cleanly without a merge commit, you can use git rebase.
# Switch to master and create a new commit
1 2 3 4 5 6 7 |
git checkout master echo "Bug fix on master" > file2.txt git add file2.txt git commit -m "Bug fix on master" |
# Now, switch back to feature and rebase it onto master
1 2 3 |
git checkout feature git rebase master |
This moves the feature branch’s commit to sit on top of the latest changes from master, creating a clean linear history.
Step 5: Cherry-Pick a Commit from Another Branch
Let us simulate a scenario where a bug was fixed directly on the master branch, and you want to apply that fix to the feature branch without merging all of master’s commits.
# Create a new fix on master
1 2 3 4 5 6 7 |
git checkout master echo "Critical fix" > critical.txt git add critical.txt git commit -m "Critical bug fix" |
# Cherry-pick the bug fix onto the feature branch
1 2 3 |
git checkout feature git cherry-pick <commit-hash-of-critical-fix> |
Now, the critical fix has been applied to the feature branch without merging all changes from master.
Step 6: Use Git Stash to Save Work in Progress
Imagine you are working on a feature but need to switch branches quickly to address an urgent issue. You do not want to commit your incomplete work, so you will use git stash.
# Make some changes but do not commit them
1 |
echo "Incomplete work on feature" >> feature.txt |
# Stash the changes
1 |
git stash |
# Switch to master and make a quick fix
1 2 3 4 5 6 7 |
git checkout master echo "Hotfix on master" >> file2.txt git add file2.txt git commit -m "Hotfix on master" |
# Return to feature branch and reapply stashed changes
1 2 3 |
git checkout feature git stash pop |
Your incomplete work has been saved and reapplied once the urgent fix was made.
Step 7: Use Git Reflog to Recover a Lost Commit
Let us simulate a scenario where you accidentally reset a branch and lose some important commits. Luckily, git reflog can help you recover them.
# Assume you are on the feature branch and accidentally reset to an earlier commit
1 |
git reset --hard HEAD~2 |
# Check reflog to find the lost commit
1 |
git reflog |
# Use the commit hash to recover the lost commit
1 |
git checkout <commit-hash-from-reflog> |
With git reflog, you can restore commits that seem to be lost, helping you recover from mistakes.
Common Pitfalls and How to Avoid Them in Git
While advanced Git commands enhance your workflow, they can also lead to problems if misused. Here is how to address some common issues you might face while using Git’s more advanced features.
- Losing Commits During Rebase
Pitfall: Commits can get lost during a rebase, especially if conflicts arise or you mistakenly drop commits during an interactive rebase. Resetting after a rebase can also lead to commit loss, which might make it appear that changes have vanished from history.
How to Avoid:
- Create a Backup Branch: Always create a backup branch before rebasing, so you have a fallback.
- Use git reflog: If you lose commits, reflog tracks all changes, including those not shown in git log, allowing you to recover them.
- Resolve Conflicts Carefully: During an interactive rebase, carefully review all changes, and manually resolve any conflicts. Check your final commit history to ensure no changes are missing.
- Merge Conflicts After Rebasing
Pitfall: Rebasing a feature branch onto a main branch can lead to conflicts, especially if the two branches have diverged significantly. If conflicts are not properly managed, changes can be lost or overwritten.
How to Avoid:
- Fetch and Merge Before Rebasing: To reduce potential conflicts, fetch and merge the latest changes from the main branch before starting the rebase.
- Resolve Conflicts One at a Time: Tackle conflicts one by one, making sure to review and test the results thoroughly.
- Abort the Rebase if Needed: If the rebase becomes too complex, you can always abort and return to the pre-rebase state:
- Conflicts with Stashed Changes
Pitfall: Stashed changes can cause conflicts when you attempt to pop them if the working directory has significantly diverged from when the stash was created.
How to Avoid:
- Clean Working Directory: Ensure your working directory is clean before stashing by committing all important changes. This reduces the chance of divergence.
- Use git stash apply: Instead of using git stash pop, use apply so the stash is not deleted if conflicts arise:
- Resolve Conflicts Manually: If conflicts do occur, manually resolve them, and ensure that the changes are properly integrated before continuing.
- Cherry-Picking Conflicts
Pitfall: Cherry-picking specific commits from one branch to another can lead to conflicts, especially if the selected commit relies on other commits that are not present in the target branch.
How to Avoid:
- Analyze Dependencies: Before cherry-picking, ensure that the commit being picked does not depend on other missing commits. If needed, bring in additional commits.
- Manual Conflict Resolution: If conflicts arise, manually resolve them, and double-check that the change integrates correctly within the context of the target branch.
- Accidental Reset of Important Commits
Pitfall: Using git reset –hard can be dangerous as it completely wipes out uncommitted changes and may cause the loss of important commits if done recklessly.
How to Avoid:
- Use Softer Resets: Before opting for a hard reset, consider using git reset –soft or git reset –mixed, which preserve changes in the working directory or index:
- Recover via Reflog: In case of an accidental hard reset, git reflog allows you to retrieve lost commits and restore the previous state.
Conclusion
By mastering advanced Git commands like rebase, squash, cherry-pick, reflog, and stash, you can take control of your codebase and streamline your development workflow. Each of these commands addresses a specific need in managing commits and collaborating on a shared codebase. With practice, these tools will become indispensable in maintaining a clean Git history. Mastering these commands will make you a more efficient and confident Git user!
Get your new hires billable within 1-60 days. Experience our Capability Development Framework today.
- Cloud Training
- Customized Training
- Experiential Learning
About CloudThat
CloudThat is a leading provider of Cloud Training and Consulting services with a global presence in India, the USA, Asia, Europe, and Africa. Specializing in AWS, Microsoft Azure, GCP, VMware, Databricks, and more, the company serves mid-market and enterprise clients, offering comprehensive expertise in Cloud Migration, Data Platforms, DevOps, IoT, AI/ML, and more.
CloudThat is the first Indian Company to win the prestigious Microsoft Partner 2024 Award and is recognized as a top-tier partner with AWS and Microsoft, including the prestigious ‘Think Big’ partner award from AWS and the Microsoft Superstars FY 2023 award in Asia & India. Having trained 650k+ professionals in 500+ cloud certifications and completed 300+ consulting projects globally, CloudThat is an official AWS Advanced Consulting Partner, Microsoft Gold Partner, AWS Training Partner, AWS Migration Partner, AWS Data and Analytics Partner, AWS DevOps Competency Partner, AWS GenAI Competency Partner, Amazon QuickSight Service Delivery Partner, Amazon EKS Service Delivery Partner, AWS Microsoft Workload Partners, Amazon EC2 Service Delivery Partner, Amazon ECS Service Delivery Partner, AWS Glue Service Delivery Partner, Amazon Redshift Service Delivery Partner, AWS Control Tower Service Delivery Partner, AWS WAF Service Delivery Partner and many more.
To get started, go through our Consultancy page and Managed Services Package, CloudThat’s offerings.
WRITTEN BY Komal Singh
Click to Comment