Many professionals start using Git with just three commands: git add ., git commit, and git push. That is enough until the first problematic merge appears, a branch gets deleted by mistake, you need to find which change broke production, or two urgent tasks require working on the same repository at the same time. At that point, Git stops being simply a place to save code and starts showing what it was really designed for.
The key Git commands for developers and sysadmins in 30 seconds
- Git can inspect, compare, and recover project states, not just store versions.
git add -p,git diff, andgit statushelp prevent accidental commits before they reach the repository.bisectcan locate the commit that introduced a bug using binary search.reflogcan recover references that seemed lost after aresetorrebase.worktree,range-diff,rerere, andfixupare particularly useful in more advanced workflows.
The important shift comes when you understand that commits form a linked history and that branches, tags, and HEAD are references to specific points in that history. Many commands that initially seem difficult start making much more sense.
Git has also evolved. Current versions still support checkout, but commands such as switch and restore separate operations that historically were concentrated in a single command.
These are 18 commands and combinations worth adding to your daily workflow, including several that are especially useful for sysadmins and teams maintaining large repositories.
Before changing history: inspect what is happening
1. git status: two seconds that prevent many problems
It may sound too basic to lead an advanced list, but it is still one of the best habits before making important changes.
git status
It shows the current branch, pending modifications, staged files, and files that are not yet tracked.
Before a commit, rebase, branch switch, or deployment, knowing exactly where the repository stands prevents you from working from a false assumption.
2. git diff: review before you send
To see changes that have not yet been staged:
git diff
And to review exactly what will go into the next commit:
git diff --staged
The second command should be part of almost every team’s routine. It can reveal anything from a forgotten console.log to a password, token, configuration change, or simply code that belongs to another task.
3. git add -p: stop staging everything blindly
One habit worth leaving behind is always using:
git add .
Git supports interactive staging:
git add -p
Instead of automatically staging every modification, it presents changes in chunks and lets you decide which ones belong in the commit.
This is especially useful when one file contains both an urgent fix and unrelated work.
The result is smaller, cleaner, and easier-to-understand commits.
4. git grep: search without leaving Git
Developers and sysadmins often overlook another useful command:
git grep "DATABASE_URL"Code language: JavaScript (javascript)
It searches for a pattern inside files tracked by Git.
It can also be combined with revisions:
git grep "old_server" HEAD~20Code language: JavaScript (javascript)
That is useful for finding configuration values, function names, or references inside the repository without building longer find and grep pipelines.
When something breaks, Git can help find when it happened
5. git log: make history readable
The basic version works:
git log
But for understanding branches and merges, this is often more useful:
git log --oneline --graph --decorate --all
At that point, Git starts looking less like a list of identifiers and more like the actual history of the project.
It is also worth knowing:
git log -p -- nginx.confCode language: CSS (css)
This lets you inspect the evolution of one specific file, which is particularly useful when a configuration has been changing for years.
6. git show: what exactly did this commit do?
When a suspicious commit appears:
git show <commit>Code language: HTML, XML (xml)
Git displays its metadata and changes.
It is simple, but it combines extremely well with log, blame, bisect, and reflog.
7. git blame: find where a line came from
Despite the name, blame is more useful for investigation than for assigning blame.
git blame nginx.confCode language: CSS (css)
It shows which commit changed each line.
The next step should usually be:
git show <commit>Code language: HTML, XML (xml)
That way you can understand not only who introduced a line, but what other changes were part of that commit and why it may have been made.
8. git bisect: find the commit that broke production
Suppose an application worked correctly in version v3.2.0, it is broken now, and there are 500 commits in between.
Reviewing them one by one would make no sense.
git bisect start
git bisect bad
git bisect good v3.2.0Code language: CSS (css)
Git checks out a commit roughly halfway between the known good and bad states. You test it and mark it:
git bisect good
or:
git bisect bad
Each test cuts the search space roughly in half until the problematic commit is found.
It can also be automated:
git bisect run ./test-regression.sh
If a test can automatically determine whether a version is good or bad, Git can walk the history and locate the first failing commit without manual intervention.
Recover mistakes without panicking
9. git restore: discard local changes clearly
To restore the committed version of a file:
git restore app.confCode language: CSS (css)
You can also remove a file from the staging area without deleting its modifications:
git restore --staged app.confCode language: CSS (css)
The first case deserves caution: restoring a file can discard local work that has not been saved anywhere else.
10. git stash: temporarily park unfinished work
When an urgent incident appears while you have incomplete changes:
git stash
You can then switch branches and come back later:
git stash pop
It is also possible to name the saved work:
git stash push -m "PostgreSQL configuration changes"Code language: JavaScript (javascript)
And list everything currently stored:
git stash listCode language: PHP (php)
It should not become permanent storage, but for short interruptions it remains extremely useful.
11. git reflog: recover what looked lost
This is one of the commands that most changes how people think about Git:
git reflog
The reflog records recent updates to local references. That can make it possible to find previous states after operations such as a reset, rebase, or branch movement.
Once the commit is located, a recovery branch can be created:
git switch -c recovery <commit>Code language: HTML, XML (xml)
That is often safer than immediately running more reset commands on a repository that is already in a confusing state.
12. git revert: undo without rewriting shared history
reset and revert are not the same thing.
When a commit has already been published and other people may depend on it, this is often preferable:
git revert <commit>Code language: HTML, XML (xml)
Git creates a new commit that reverses the changes introduced by the earlier one.
That preserves the existing history, which matters in shared branches and environments where traceability is important.
Work better with branches and parallel tasks
13. git switch: branches without overloading checkout
To create and switch to a new branch:
git switch -c fix/login-timeoutCode language: JavaScript (javascript)
To go back:
git switch mainCode language: JavaScript (javascript)
And there is a useful shortcut:
git switch -Code language: JavaScript (javascript)
That returns to the previous branch.
git checkout still works, but switch makes it clearer that the operation is about branches.
14. git worktree: keep two branches open at once
worktree deserves much more attention, especially now that AI coding agents are common.
It allows multiple working trees linked to the same repository, each using a different branch.
For example:
git worktree add ../hotfix fix/login-timeout
You can continue working on a feature in the original directory while opening ../hotfix to solve the incident.
To list existing worktrees:
git worktree listCode language: PHP (php)
And when finished:
git worktree remove ../hotfix
This is especially useful when several AI coding agents work on the same project. Instead of letting them manipulate one directory, each can use a separate worktree and branch.
15. git cherry-pick: bring one specific change into another branch
A bug was fixed in main, but the same correction also needs to go into a stable maintenance branch.
You do not need to merge everything:
git cherry-pick <commit>Code language: HTML, XML (xml)
Git applies the changes from that commit and creates a corresponding commit in the current branch.
This is especially useful for backports and long-lived maintenance branches.
Clean up history without turning it into a dangerous sport
16. git commit --fixup + rebase --autosquash
Suppose you created this commit:
8d71a42 Fix authentication timeout
Then you discover a small related issue. Instead of adding another commit named:
fix
you can use:
git commit --fixup 8d71a42
Later:
git rebase -i --autosquash HEAD~6
Git recognizes fixup! commits and places them next to the commit they are meant to amend.
This is convenient for working with small incremental commits during development while still presenting a clean history before merging.
17. git range-diff: compare two versions of a commit series
This command becomes particularly useful after a rebase.
A conventional diff compares files. range-diff lets you inspect how one series of commits changed compared with another.
For example:
git range-diff main...feature-v1 main...feature-v2Code language: CSS (css)
That is useful during code review when a branch has been rewritten after feedback and reviewers want to understand what changed between the first and second versions.
18. git rerere: let Git remember how you resolved a conflict
The name comes from reuse recorded resolution.
Enable it with:
git config --global rerere.enabled trueCode language: PHP (php)
When a conflict appears, you resolve it normally. If Git encounters the same conflict later, it can reuse the recorded resolution.
This is especially useful in long-running branches, repeated rebases, and integration workflows where the same conflicts keep returning.
It does not remove the need to review the result. It simply prevents you from solving exactly the same conflict over and over again.
Three extra commands for large repositories and operations teams
Sysadmins and platform teams can go one step further.
In very large monorepos, sparse-checkout lets you work with only part of the tree:
git sparse-checkout init --cone
git sparse-checkout set infrastructure ansibleCode language: JavaScript (javascript)
You should also know:
git fsck
which checks the connectivity and validity of repository objects, and:
git maintenance
which runs maintenance tasks designed to keep large repositories performing well.
These are not commands you need every hour. That is exactly why many people discover them too late.
The most useful Git workflow is not the one with the most commands
Learning Git is not about memorizing 50 commands.
A much safer workflow can start with something as simple as:
git status
git diff
git add -p
git diff --staged
git commit
Then the more specialized tools come in when needed: bisect when you need to find a regression, reflog when work appears to be lost, worktree when tasks need to run in parallel, and revert when a shared commit has to be undone safely.
There is also a growing difference now that AI coding agents are part of development workflows. Tools such as Claude Code, Codex, Gemini CLI, and OpenCode can execute Git commands very quickly. That makes it even more important to understand what each operation actually does before granting permission to run it.
An agent can type git reset --hard in a fraction of a second. That does not mean it should.
Git becomes much less intimidating when you learn first how to inspect state, then how to modify it, and finally how to recover it.
That is probably the real difference between using Git as a place to upload files and using it as an engineering tool.
Frequently asked questions
Which Git commands should I learn after add, commit, and push?
status, diff, add -p, log, show, restore, and reflog are a strong next step. After that, more specialized commands such as bisect, worktree, rebase, and cherry-pick become useful.
What is the difference between git revert and git reset?
git revert creates a new commit that reverses an earlier change and is generally suitable for shared history. reset moves references and, depending on the mode, can also modify the staging area and working tree.
What is git worktree used for?
It allows multiple branches from the same repository to be checked out simultaneously in different directories. It is useful for hotfixes, parallel testing, and separating the work of multiple coding agents.
Can a commit deleted by mistake be recovered?
In some situations, yes. git reflog can help locate previous reference states and recover a commit that no longer appears in the normal history, provided the underlying Git objects are still available.
