This guide covers advanced Git commands that are essential for effective version control management. Each command includes detailed explanations and practical examples.
The git stash command temporarily stores modified tracked files and staged changes, allowing you to switch branches or pull updates without committing incomplete work.
Basic stash:
git stashSaves your current changes and reverts to a clean working directory.
Stash with a descriptive message:
git stash push -m "WIP: implementing user authentication"Note: git stash save is deprecated as of Git 2.16; use git stash push -m instead.
List all stashes:
git stash listOutput example:
stash@{0}: WIP: implementing user authentication
stash@{1}: On main: bug fix for login
Apply the most recent stash:
git stash applyApply a specific stash:
git stash apply stash@{1}Apply and remove the most recent stash:
git stash popStash untracked files:
git stash -uStash including ignored files:
git stash -aCreate a branch from a stash:
git stash branch feature-branch stash@{0}Drop a specific stash:
git stash drop stash@{0}Clear all stashes:
git stash clear# You're working on a feature
git status
# Changes not staged for commit:
# modified: src/auth.js
# Urgent bug fix needed on main branch
git stash push -m "WIP: authentication feature"
# Switch to main and fix the bug
git checkout main
# ... make fixes ...
git commit -am "Fix critical bug"
# Return to your feature work
git checkout feature-branch
git stash popThe git cherry-pick command allows you to select specific commits from one branch and apply them to another branch. This is useful when you need specific changes without merging entire branches.
Cherry-pick a single commit:
git cherry-pick <commit-hash>Cherry-pick multiple commits:
git cherry-pick <commit-hash-1> <commit-hash-2>Cherry-pick a range of commits (inclusive):
git cherry-pick <start-commit-hash>^..<end-commit-hash>Note: To include all commits from A to B, use A^..B. This starts from the parent of A (denoted by ^), making commit A the first in the range, through to B. Using A..B alone would skip commit A and only cherry-pick commits after A up to B.
Cherry-pick without committing (stage only):
git cherry-pick --no-commit <commit-hash>or
git cherry-pick -n <commit-hash>Cherry-pick and edit the commit message:
git cherry-pick --edit <commit-hash>Continue after resolving conflicts:
git cherry-pick --continueAbort cherry-pick:
git cherry-pick --abort# View commits on another branch
git log feature-branch --oneline
# abc1234 Add password validation
# def5678 Update user model
# ghi9012 Fix typo in comments
# Cherry-pick the password validation commit to your current branch
git cherry-pick abc1234
# Cherry-pick multiple specific commits
git cherry-pick abc1234 ghi9012
# Cherry-pick with conflict resolution
git cherry-pick def5678
# CONFLICT (content): Merge conflict in src/user.js
# Resolve conflicts manually
git add src/user.js
git cherry-pick --continue- Backporting bug fixes to release branches
- Applying hotfixes to multiple branches
- Selectively merging commits without pulling entire branches
- Recovering commits from deleted branches
The git revert command creates a new commit that undoes the changes from a previous commit, preserving the project history. This is the safest way to undo changes that have been shared with others.
Revert the most recent commit:
git revert HEADRevert a specific commit:
git revert <commit-hash>Revert multiple commits:
git revert <commit-hash-1> <commit-hash-2>Revert a range of commits (inclusive):
git revert <start-commit-hash>^..<end-commit-hash>Note: To include all commits from A to B, use A^..B. This starts from the parent of A (denoted by ^), making commit A the first in the range, through to B. Using A..B alone would skip commit A and only revert commits after A up to B.
Revert without committing immediately:
git revert --no-commit <commit-hash>or
git revert -n <commit-hash>Revert and edit the commit message:
git revert --edit <commit-hash>Continue after resolving conflicts:
git revert --continueAbort revert:
git revert --abortRevert a merge commit:
git revert -m 1 <merge-commit-hash>The -m 1 specifies which parent to consider as the mainline (usually 1 for the branch you merged into).
# View recent commits
git log --oneline
# abc1234 (HEAD) Add new feature
# def5678 Update documentation
# ghi9012 Refactor authentication
# The new feature introduced a bug, revert it
git revert abc1234
# This creates a new commit that undoes abc1234
# Revert multiple commits without auto-committing
git revert -n def5678 abc1234
git commit -m "Revert recent changes due to integration issues"
# Revert a merge commit (suppose ghi9012 was a merge)
git log --merges
git revert -m 1 ghi9012- Changes have been pushed to a shared branch
- You want to maintain a clear history of what was undone
- You need to undo changes on a public branch safely
- Reverting changes in a collaborative environment
The git reset command moves the current branch pointer to a specified commit, optionally modifying the staging area and working directory. It's powerful but should be used carefully, especially with shared branches.
Moves HEAD to the specified commit, but keeps changes in the staging area and working directory.
git reset --soft <commit-hash>Moves HEAD to the specified commit and unstages changes, but keeps them in the working directory.
git reset <commit-hash>
# or explicitly
git reset --mixed <commit-hash>Moves HEAD to the specified commit and discards all changes in the staging area and working directory.
git reset --hard <commit-hash>Undo the last commit, keeping changes staged:
git reset --soft HEAD~1Undo the last commit, keeping changes unstaged:
git reset HEAD~1Undo the last commit and discard all changes:
git reset --hard HEAD~1Reset to a specific commit:
git reset --hard abc1234Unstage a file:
git reset HEAD <file>Reset to remote branch state:
git reset --hard origin/mainUndo multiple commits:
git reset --soft HEAD~3This undoes the last 3 commits but keeps all changes staged.
Scenario 1: Undo last commit but keep changes
# Made a commit too early
git log --oneline
# abc1234 (HEAD) Incomplete feature
# def5678 Previous commit
# Undo the commit but keep the work
git reset --soft HEAD~1
# Now changes are staged and ready to be modified/recommitted
git status
# Changes to be committed:
# modified: src/feature.jsScenario 2: Completely undo uncommitted changes
# Working directory is messy with unwanted changes
git status
# Changes not staged for commit:
# modified: file1.js
# modified: file2.js
# Discard all changes
git reset --hard HEAD
# Working directory is now cleanScenario 3: Split a large commit into smaller ones
# Last commit has too many unrelated changes
git reset --soft HEAD~1
# Now changes are staged, unstage them
git reset
# Stage and commit changes incrementally
git add src/auth.js
git commit -m "Add authentication logic"
git add src/validation.js
git commit -m "Add input validation"Scenario 4: Sync with remote branch
# Local branch has diverged from remote
git fetch origin
git reset --hard origin/main
# Local main now matches remote main exactly| Aspect | git reset |
git revert |
|---|---|---|
| History | Rewrites history | Preserves history |
| Safety | Dangerous for shared branches | Safe for shared branches |
| Use Case | Local commits not pushed yet | Published commits |
| Result | Moves branch pointer | Creates new commit |
| Collaboration | Avoid on shared branches | Safe for collaboration |
Be extremely careful with git reset --hard on shared branches. It rewrites history and can cause issues for other collaborators. Use git revert instead for commits that have been pushed to shared branches.
git stash: Temporarily save work in progress without committinggit cherry-pick: Apply specific commits from one branch to anothergit revert: Safely undo commits by creating new commits (safe for shared branches)git reset: Move branch pointer and modify staging/working directory (use carefully)
# Stash current work
git stash
git stash pop
# Apply specific commit to current branch
git cherry-pick <commit-hash>
# Safely undo a commit (for shared branches)
git revert <commit-hash>
# Undo last commit, keep changes (for local work)
git reset --soft HEAD~1
# Undo last commit and discard changes
git reset --hard HEAD~1- Use
git stashwhen you need to quickly switch context without losing work - Use
git cherry-picksparingly and document why specific commits were cherry-picked - Use
git revertfor undoing changes on shared/public branches - Use
git resetonly on local commits that haven't been pushed - Always verify your working directory state before and after using these commands
- Create backups before using destructive commands like
git reset --hard
For more information, consult the official Git documentation.