If you’ve used Git for a while, you probably know the basics:
git add
git commit
git pull
git push
Enter fullscreen mode Exit fullscreen mode
These commands are enough to get started.
But as your projects become bigger and you start working with branches, pull requests, conflicts, and other developers, Git starts getting a little more interesting.
Here are 10 Git commands and techniques that I found especially useful for moving beyond the basics.
1. git merge
Let’s say you have a feature branch and the main branch has received some new changes.
You can bring those changes into your current branch using:
git merge main
Enter fullscreen mode Exit fullscreen mode
A simplified history might look like:
A---B---C main
D---E feature
Enter fullscreen mode Exit fullscreen mode
After merging:
A---B---C------M
/
D---E---
Enter fullscreen mode Exit fullscreen mode
M is the merge commit.
When is merge useful?
Use merge when you want to preserve the branch history and clearly show that two lines of development were combined.
2. git rebase
Rebase takes a different approach.
Instead of creating a merge commit, Git moves your commits and reapplies them on top of another branch.
git rebase main
Enter fullscreen mode Exit fullscreen mode
The previous history:
A---B---C main
D---E feature
Enter fullscreen mode Exit fullscreen mode
can become:
A---B---C---D'---E'
Enter fullscreen mode Exit fullscreen mode
The result is often easier to read.
But there’s an important thing to remember:
Rebase rewrites commit history.
So a simple rule is:
Rebase your own local work carefully, especially before sharing it with others.
If you’re rebasing a shared branch, you can create unnecessary problems for teammates.
3. git commit --amend
Ever made a commit and immediately realized you forgot one small change?
Instead of creating another unnecessary commit, you can add the change to the previous commit.
git add forgotten-file.js
git commit --amend --no-edit
Enter fullscreen mode Exit fullscreen mode
The --no-edit option keeps your previous commit message.
If you also want to change the message:
git commit --amend
Enter fullscreen mode Exit fullscreen mode
Important
Amending creates a new commit, which means the commit hash changes.
So this is safest when the commit hasn’t already been shared with other people.
4. git push --force-with-lease
Sometimes you rewrite your local history using:
- rebase
- amend
- interactive rebase
- squash
Then a normal push may be rejected.
You might be tempted to use:
git push --force
Enter fullscreen mode Exit fullscreen mode
But there’s a safer option:
git push --force-with-lease
Enter fullscreen mode Exit fullscreen mode
The difference is important.
--force basically says:
Replace the remote branch with my version.
--force-with-lease checks whether the remote branch has changed before replacing it.
That makes it a much safer choice when you actually need to force-push.
5. git rebase -i
This is one of my favorite Git commands for cleaning up commits.
git rebase -i HEAD~5
Enter fullscreen mode Exit fullscreen mode
This lets you interact with your last five commits.
You’ll see something similar to:
pick a111111 Add login page
pick b222222 Add validation
pick c333333 Fix typo
pick d444444 Fix validation
pick e555555 Remove debug code
Enter fullscreen mode Exit fullscreen mode
You can change pick to commands such as:
pick
Keep the commit as it is.
reword
Change only the commit message.
edit
Pause at that commit so you can modify it.
squash
Combine the commit with the previous one while keeping its commit message available for editing.
fixup
Combine the commit with the previous one and discard its commit message.
drop
Remove the commit.
For example:
pick a111111 Add login page
fixup b222222 Fix typo
fixup c333333 Remove debug code
Enter fullscreen mode Exit fullscreen mode
can turn several messy commits into a much cleaner history.
6. git stash
Imagine you’re working on a feature and suddenly need to switch to another task.
Your current code isn’t ready to commit yet.
That’s where git stash helps.
git stash
Enter fullscreen mode Exit fullscreen mode
Git temporarily stores your uncommitted changes and gives you a clean working directory.
You can then switch branches:
git switch main
Enter fullscreen mode Exit fullscreen mode
Later, you can bring your changes back.
Include untracked files
If you’ve also created new files:
git stash -u
Enter fullscreen mode Exit fullscreen mode
You can even give your stash a useful name:
git stash push -u -m "WIP authentication feature"
Enter fullscreen mode Exit fullscreen mode
To see your stashes:
git stash list
Enter fullscreen mode Exit fullscreen mode
To restore one:
git stash apply stash@{0}
Enter fullscreen mode Exit fullscreen mode
Or:
git stash pop
Enter fullscreen mode Exit fullscreen mode
The simple difference:
apply = restore the changes
pop = restore + remove the stash
Enter fullscreen mode Exit fullscreen mode
7. git cherry-pick
Sometimes you don’t need an entire branch.
You only need one specific commit.
That’s where cherry-pick comes in:
git cherry-pick <commit-hash>
Enter fullscreen mode Exit fullscreen mode
For example:
git cherry-pick a1b2c3d
Enter fullscreen mode Exit fullscreen mode
Git takes the changes from that commit and applies them to your current branch.
This is useful when:
- A bug fix exists on another branch
- You need one specific feature
- You don’t want to merge the entire branch
One important detail:
Cherry-pick creates a new commit with a different hash.
8. git reset
git reset is useful when you want to move your branch backwards.
There are three common versions:
git reset --soft HEAD~1
Enter fullscreen mode Exit fullscreen mode
git reset --mixed HEAD~1
Enter fullscreen mode Exit fullscreen mode
git reset --hard HEAD~1
Enter fullscreen mode Exit fullscreen mode
The easiest way to remember them:
--soft → keep changes staged
--mixed → keep changes unstaged
--hard → discard the changes
Enter fullscreen mode Exit fullscreen mode
For example:
Soft reset
git reset --soft HEAD~1
Enter fullscreen mode Exit fullscreen mode
Removes the last commit but keeps its changes staged.
Mixed reset
git reset HEAD~1
Enter fullscreen mode Exit fullscreen mode
Removes the last commit and keeps the changes in your working directory.
Hard reset
git reset --hard HEAD~1
Enter fullscreen mode Exit fullscreen mode
Moves the branch backwards and removes the changes from the working tree.
⚠️ Be careful with --hard.
Make sure you understand what you’re about to discard before using it.
9. git reflog
This command can be extremely useful when you think you’ve lost a commit.
git reflog
Enter fullscreen mode Exit fullscreen mode
While git log shows your reachable commit history, reflog records movements of references such as HEAD.
You might see:
e35fa12 HEAD@{0}: reset: moving to HEAD~2
821cd77 HEAD@{1}: commit: Add authentication
f992ab1 HEAD@{2}: commit: Add login page
Enter fullscreen mode Exit fullscreen mode
That previously “lost” commit may still be accessible.
Instead of immediately resetting everything again, you can create a recovery branch:
git branch rescue 821cd77
Enter fullscreen mode Exit fullscreen mode
Then inspect it safely.
Remember
reflog isn’t a magic backup.
If your work was never committed or otherwise stored by Git, reflog cannot recover it.
10. git revert
Here’s an important situation.
You pushed a commit to a shared branch, and that commit introduced a problem.
Should you rewrite the branch history?
Usually, no.
Instead, use:
git revert <commit-hash>
Enter fullscreen mode Exit fullscreen mode
Suppose your history is:
A---B---C
Enter fullscreen mode Exit fullscreen mode
And C introduced the problem.
Running:
git revert C
Enter fullscreen mode Exit fullscreen mode
creates another commit:
A---B---C---D
Enter fullscreen mode Exit fullscreen mode
D contains the opposite changes needed to undo C.
The original commit remains visible in history.
That’s why revert is generally a better choice for undoing changes on shared branches.
Quick Cheat Sheet
Command Main purposegit merge
Combine branch histories
git rebase
Reapply commits on top of another branch
git commit --amend
Modify the previous commit
git push --force-with-lease
Safer force push
git rebase -i
Clean up recent commits
git stash
Temporarily save unfinished changes
git cherry-pick
Apply one specific commit
git reset
Move branch history backwards
git reflog
Find previous HEAD/reference states
git revert
Safely undo a shared commit
Final Thoughts
Git becomes much easier once you stop thinking of it as just a collection of commands and start understanding what happens to your repository history after each command.
If you’re currently learning Git, I’d recommend becoming comfortable with these first:
git stash
git merge
git rebase
git revert
git reset
git reflog
Enter fullscreen mode Exit fullscreen mode
Then gradually add:
git rebase -i
git cherry-pick
git commit --amend
git push --force-with-lease
Enter fullscreen mode Exit fullscreen mode
The more you understand Git’s history, the less scary those inevitable conflicts and mistakes become.
Which Git command has saved you the most time? 👇