Most developers reach a point where a few Git commands start to feel almost unfair. They clear hours of confusion in minutes and provide a level of control that seems impossible the first time you see it in action. My own introduction to these commands explained why experienced Git users describe the tool as both intimidating and strangely reassuring. You break something, you feel the panic rise, you run a short sequence of commands, and the entire mess dissolves as if it never existed.
The commands below are the ones I have relied on for personal projects, work, and open-source contributions. They are easy to learn, surprisingly powerful, and capable of saving entire days of effort. The same power also makes them risky, so it helps to understand when to use them and when to back away.
Below are the commands that genuinely feel like cheating, along with the moments when they will cause more harm than good:
git add -p: stage only the good parts
When I look through someone else's Git history, I can usually spot the developers who learned the tool through trial and error. Their commits mix unrelated changes, half finished work, and debugging prints that slipped in by mistake (I have done the same more times than I want to admit). What they truly need is a way to separate the useful edits from the accidental ones, and Git already includes a feature designed for exactly that.
The git add -pbreaks your modified files into small sections called hunks and then asks whether you want to stage each one. It turns your changes into a simple checklist, letting you include the pieces that belong in your current commit while leaving the experimental or messy parts for later. In practice, it feels like the ability to rewrite your work in place without directly editing anything. Clean commits become a natural habit (eventually), and anyone reading your history benefits from it, including your future self who will one day wonder why you slipped a stray variable into what was supposed to be a routine styling fix.
When not to use it
If you are working with huge auto-generated files or code bases where line-driven changes do not make sense, interactive staging will turn into a slow and annoying experience. There are situations where staging entire files is not only cleaner but more accurate.
git commit -- amend: rewrite the history without anyone looking
Whenever you move too quickly and run git commit, you usually notice a mistake as soon as it is too late. Sometimes I forget to stage a file, or I spot a simple typo that slipped through. Rather than creating a separate commit for something trivial, you can correct the previous one with a single git commit --amend command which updates the staged changes and lets you rewrite the message in one step.
Using it feels a bit like controlled time travel. The old commit disappears, a corrected version takes its place, and the history suggests that the error never existed in the first place. Reviewers avoid a stream of tiny fix-up commits, and you get the pleasant illusion that you consistently deliver perfect work on the first attempt.
When not to use it
Never amend a commit that has already been pushed to a shared repository unless you are completely sure everyone is comfortable with rewritten history. Changing public commits forces other contributors to deal with diverged branches and confusing merges.
git reflog: recover lost commits
When people say that Git rarely loses data, they are referring to the reflog. It keeps a record of every change your branches go through. If you reset a branch, delete one by mistake, or move past a commit during a rebase, the reflog stores each step in order. This record allows you to trace your actions and recover work that appears to be gone.
The first time I used git reflog, I had just performed a reset that removed several hours of work. I assumed the changes were lost. Looking at the reflog showed the exact commit I needed, and checking it out restored everything. The situation resolved quickly, and the entire incident changed how I think about recovery in Git.
When not to use it
Reflog entries eventually expire, especially in shallow clones or when garbage collection has run aggressively. It is not a substitute for proper backups, and you should not rely on it for long-term recovery.
git cherry-pick: grab one commit and ignore the rest
Cherry picking allows you to take a single commit from any point in your history and apply it to your current branch. The rest of the branch that contains the commit is not brought in. If you only need one fix from a feature branch, you can apply it without merging the entire set of changes.
This becomes useful when a production issue appears, and you remember that the fix is already present in a development branch. Instead of merging a large amount of work that is still in progress, you can apply only the commit that resolves the issue. Your stable branch remains focused, and you avoid forcing a merge that is not ready for review.
When not to use it
Cherry picking creates new commit hashes and if you cherry pick frequently (don't do it, you do know that it is looked down upon?) across long-running branches, you can create duplicated commits that later cause merge conflicts or confusing histories.
git reset - hard: nuclear undo
Most people avoid this command and the concern is reasonable as it removes all unstaged changes, resets the working directory, and moves the branch pointer to the selected commit. It is useful when the current state of your work is no longer worth keeping, and you want to return to a clean directory as fast as possible.
Days spent experimenting often lead to a working tree filled with abandoned attempts and partial edits (cleaning that by hand is wayyy too slow). After using git add -pto keep your commits focused, this command lets you erase the rest of the changes in a single step. The result is a fresh start without any of the noise that accumulated during the earlier work.
When not to use it
Never use this command if you have uncommitted work you care about. If you want to keep your work but remove it from the branch, use git stash instead. Hard reset is only meant for situations where you want to erase the current state without hesitation.
git clean -fd: remove everything that was not committed
Sometimes the project directory collects leftover files such as build artifacts, temporary logs, editor backups, and compiled binaries. Git clean removes them all in one stroke. It deletes any untracked file or directory so that you can return to a clean repository that matches the actual version control state.
When you work with large projects or frameworks that generate layers of build files, cleaning the workspace can fix errors that seem unrelated at first glance. It is the quickest method I know for clearing out garbage without risking the files I actually changed.
When not to use it
Be careful not to run it inside a directory that contains important untracked files (I have done that), such as configuration files that you intentionally keep out of version control. A quick git clean -nwill show what will be deleted before you proceed.
git rerere: reuse recorded resolution
The first time I heard about rerere, I assumed it was a joke. The name stands for reuse recorded resolution and it is both a feature and git command. Git can remember how you resolved a particular conflict and automatically apply the same resolution the next time the same conflict appears. If you work with a long-running branch that you often rebase, this tool saves enormous amounts of time.
The best part is that rerere works quietly in the background. You resolve a conflict once and Git notes the pattern. Later, when you merge or rebase again, Git instantly reuses the fix. It is like having a tiny assistant who takes notes during your merge battles and steps in when the same enemy returns. To use it in a repo, you can enable it using the following commands:
When not to use it
If your conflict resolutions change frequently or depend on context, rerere may apply a resolution that no longer makes sense and mess up things as with other commands in this list review before using them.
Git encourages you to treat history as something you can shape instead of something that happens to you. Other version control systems also provide basic undo functions, but Git gives you tools that completely reshape your branches, recover lost work, preview changes line by line, and time travel when needed. However, with great power comes great confusion (as of now the Git man page is 1514 lines), which is why many developers grow up fearing Git more than they fear their prod servers.
The secret is not to use these commands all the time but knowing when they give you the most influence with the least risk. It feels like cheating because you gain the upper hand in situations that used to be painful. The fix is not always obvious, but once you know the command, your confidence grows quickly.
