Reference

Git Commands Cheatsheet

A complete git commands cheatsheet with more than 60 commands organized into 11 practical categories. Every entry includes a concise description, a real-world example, and a one-click copy button. The live search at the top filters across names, descriptions, and examples so you can jump directly to what you need. Whether you're setting up your first repository, untangling a messy history, rebasing a feature branch, or managing submodules on a large monorepo, this page is designed to be the single page you keep open in a tab. Skim the 10-step learning path if you're new.

Last updated: March 2026

10-Step Learning Path for Newcomers

1.Configure your name and email with git config
2.Create a repo with git init or clone one
3.Check status and diff your changes
4.Stage files with git add
5.Commit with a clear message
6.Push and pull from a remote
7.Create and switch branches
8.Merge branches and resolve conflicts
9.Learn to undo safely (reset, revert, reflog)
10.Explore rebase, stash, and tags

Why learn git deeply?

Git is the distributed version control system that powers nearly every open-source project, every internal company codebase, and every modern deployment pipeline. It was created by Linus Torvalds in 2005 to manage Linux kernel development after the team lost access to BitKeeper, and its design reflects that origin: it's built to handle thousands of contributors working across disconnected forks with no central authority, and it's ruthlessly fast at operating on full histories of hundreds of thousands of commits. Learning git well is one of the highest-leverage investments a developer can make. Most engineers get by knowing five commands: clone, add, commit, push, and pull. That's enough to function, but it leaves you helpless when anything goes wrong — a bad merge, a lost commit, a branch you can't remember creating. The engineers who can debug git state, cherry-pick fixes across branches, and rewrite history safely are disproportionately valuable on any team.

The mental model that unlocks git

Git is not a pile of patches. It's a content-addressable filesystem with a version control interface bolted on top. Every file you commit is stored as a blob identified by a SHA-1 hash of its contents. Every directory snapshot is a tree that references blobs by hash. A commit is an object that references one tree (the state of the whole project), plus its parent commit(s), plus author metadata. A branch is just a movable pointer to a commit — nothing more. A tag is a fixed pointer. Remote-tracking branches like origin/main are pointers that mirror what the remote had at the last fetch. Once this model clicks, everything else follows. git reset moves a branch pointer. git merge creates a new commit with two parents. git rebase rewrites a series of commits so they have different parents. git cherry-pick copies the diff from one commit onto another branch as a new commit with a new hash.

Staging area: the feature that confuses everyone first

Unlike Subversion or Mercurial, git has a three-layer structure: your working directory (the files on disk), the index or staging area (a snapshot of what the next commit will contain), and the repository (the committed history). You move changes between layers with git add (working → staged), git reset (staged → working), and git commit (staged → committed). The staging area feels like extra friction when you're starting out, but it becomes indispensable when you need to split a messy working directory into several small, focused commits. Use git add -p to stage individual hunks interactively — it's one of the most underused features in git.

The golden rule of rebasing

Never rebase commits that exist outside your local repository. When you rebase, you're rewriting history — new commits are created with new SHAs, and the old commits become orphaned. If someone else has already pulled the old commits and based work on them, your rebased history will create a painful divergence that's hard to reconcile. The safe pattern: rebase your local feature branch onto the latest main before opening a PR (so history is linear), but once the PR is under review and other people may have pulled it, prefer merge commits. Some teams adopt a stricter "merge-only" policy on main to avoid any history rewriting in public branches.

Recovering from mistakes

Git almost never loses data. Commits that are no longer reachable from any branch or tag stay in the object database for at least 30 days (controlled by gc.reflogExpire) before garbage collection. The git reflog command shows every change to HEAD — every commit, checkout, reset, and merge — giving you a way to recover from almost anything. If you accidentally reset --hard and lose work, run git reflog, find the SHA of the state you want, and git reset --hard <sha> back to it. This is one of the most reassuring features in the whole tool, and it's why you should never be afraid to experiment with git commands.

Branching strategies in practice

The two dominant strategies are trunk-based development (everyone commits to main with short-lived feature branches, protected by CI) and Git Flow (long-lived develop and release branches, hotfix branches, and semver tags). Trunk-based suits teams with strong test automation and continuous deployment; Git Flow suits teams shipping versioned software to customers on slower release cadences. GitHub Flow is a lightweight variant — main is always deployable, and every change happens through a feature branch and PR. Pick the simplest model your team's release cadence supports.

Power commands worth knowing

git bisect performs a binary search through history to find the commit that introduced a bug. You mark a known-good commit and a known-bad commit, then git checks out the middle commit; you test it and mark good or bad; git narrows down, and within log₂(n) steps you've found the culprit. git blame shows who last modified each line of a file — invaluable for archaeology. git log --oneline --graph --all draws an ASCII graph of the full branch topology. git show <sha> displays a commit's diff and metadata. git diff --stat summarizes changes across many files. Master these and you can navigate any codebase's history fluently.

Configuring git for humans

A few config settings make daily git much nicer. git config --global init.defaultBranch main uses main instead of master. git config --global pull.rebase true rebases instead of merging on pull (avoids noisy merge commits). git config --global core.editor "code --wait" uses VS Code for commit messages. Set up ~/.gitignore_global for editor files and OS clutter. Add SSH key authentication to GitHub/GitLab to skip password prompts. Enable commit signing with GPG or SSH to prove commits are yours. These take ten minutes to set up once and save hours over a career.

Copied!

Frequently Asked Questions

What is the difference between git reset and git revert?
git reset rewrites history by moving the current branch pointer backward — the commits it moves past become unreachable (though recoverable via reflog for a while). git revert creates a new commit that applies the inverse of a previous commit's changes, leaving history intact. Use revert on shared branches where other people may have pulled the commits you want to undo; reset is only safe on private branches nobody else has seen.
When should I use git rebase instead of merge?
Use rebase when you want a clean linear history on a feature branch before merging it into main — it replays your commits on top of the latest base, avoiding merge commits. Use merge when you want to preserve the exact parallel history of branches including the point they joined. The golden rule: never rebase commits that exist outside your local repo and that other people may have based work on. Rebase private work; merge public work.
How do I undo the last commit in git?
If you haven't pushed yet: git reset --soft HEAD~1 keeps your changes staged, git reset --mixed HEAD~1 (the default) keeps them unstaged but in your working tree, and git reset --hard HEAD~1 discards them entirely. If you've already pushed, don't reset — use git revert HEAD to create an inverse commit that's safe to push on shared branches. To fix just the commit message, git commit --amend opens your editor to edit the previous commit.
What does git stash do?
git stash saves your uncommitted changes (tracked files by default) onto a stack and reverts your working directory back to the state of HEAD. It's perfect when you need to quickly switch branches without committing half-finished work. Restore with git stash pop (applies the top stash and removes it from the stack) or git stash apply (applies without removing). Add untracked files with git stash -u, and name stashes with git stash push -m "message".
How do I resolve a merge conflict?
When git reports a conflict, it inserts markers into the affected files: <<<<<<< HEAD, =======, and >>>>>>> branch-name surrounding the conflicting regions. Open each conflicted file, edit it to the desired final state (removing all markers), then git add the file to mark the conflict resolved. When all conflicts are resolved, git commit completes the merge. To bail out, git merge --abort returns to the pre-merge state. For rebases, use git rebase --continue or git rebase --abort.
What's the safest way to rewrite history on a shared branch?
Don't. Seriously — if other people have pulled the branch, rewriting it forces them to untangle their local state, which is error-prone and frustrating. If you must force-push (for example, to remove leaked secrets), coordinate with your team first, use git push --force-with-lease (safer than --force because it fails if someone else pushed in the meantime), and make sure everyone re-clones or runs git fetch && git reset --hard origin/branch after. For routine history cleanup, squash locally before pushing.