Git Cheat Sheet

20 commands to practise⏱ 10 min readUpdated

The 20 Git commands you will actually use at work, from first commit to safely undoing mistakes on a shared branch.

0 of 21 done

Every engineering team runs on Git, and interviewers notice quickly whether you are comfortable with branches, rebases and undoing mistakes. Being fluent here also makes take-home assignments and pair-programming rounds far less stressful.

Work through the sheet in a scratch repository: run each example, break something on purpose, then fix it. Tick an item only once you can use the command without looking it up.

Start a repo

Get a project under version control or grab an existing one.

  1. 1git init

    Turns the current folder into a Git repository by creating a hidden .git directory. Use it when starting a brand-new project locally.

    • Set the default branch name with -b main so it matches GitHub.
    • Add a .gitignore before the first commit to keep secrets and build output out.
    • Link it to a remote later with git remote add origin <url>.
    bash
    mkdir todo-api && cd todo-api
    git init -b main
    echo "node_modules/" > .gitignore
    git remote add origin git@github.com:you/todo-api.git
    git remote -v
    
  2. 2git clone

    Copies a remote repository, its full history and all branches, onto your machine and sets origin to point at it.

    • --depth 1 makes a shallow clone: fast, but history is missing.
    • -b <branch> checks out a specific branch straight away.
    • SSH URLs avoid typing a token on every push.
    bash
    git clone git@github.com:you/todo-api.git
    git clone --depth 1 https://github.com/torvalds/linux.git
    git clone -b develop git@github.com:team/app.git app-dev
    

Daily loop

Check, stage, commit, push: the rhythm of every working day.

  1. 3git status

    Shows which files are modified, staged or untracked and how your branch compares with its upstream. Run it before and after almost every other command.

    • -s gives a compact two-column view (staged / unstaged).
    • -sb also shows ahead/behind counts for the branch.
    bash
    git status
    git status -sb
    
  2. 4git add

    Moves changes into the staging area, the snapshot your next commit will contain. Staging lets you commit only part of your work.

    • git add -p lets you pick individual hunks; great for clean, focused commits.
    • git add . stages everything under the current folder, including files you may not want.
    • git add -u stages modifications and deletions but skips new files.
    bash
    git add src/routes/todo.js
    git add -p
    git add -u
    
  3. 5git commit -m

    Records the staged snapshot with a message. Good commits are small, focused and explain why the change was made.

    • Write messages in the imperative: "Add pagination to todo list".
    • --amend rewrites the last commit; only do it before pushing.
    • -am stages tracked files and commits in one go (new files are skipped).
    bash
    git commit -m "Add pagination to GET /todos"
    git commit --amend --no-edit   # add a forgotten file to the last commit
    git commit -am "Fix off-by-one in page size"
    
  4. 6git push

    Uploads your local commits to the remote branch so others can see them and open a pull request.

    • -u origin <branch> sets the upstream once; afterwards plain git push works.
    • Never --force a shared branch. If you must rewrite your own branch, use --force-with-lease, which refuses if someone else pushed.
    bash
    git push -u origin feature/pagination
    git push
    git push --force-with-lease   # after rebasing your own branch
    

Branching

Work in isolation and bring changes together cleanly.

  1. 7git branch

    Lists, creates, renames and deletes branches. A branch is just a movable pointer to a commit, so creating one is instant and cheap.

    • -vv shows each branch's upstream and ahead/behind status.
    • -d deletes only merged branches; -D force-deletes (unmerged work can be lost).
    • -a includes remote-tracking branches.
    bash
    git branch -vv
    git branch feature/search
    git branch -m old-name new-name
    git branch -d feature/pagination
    
  2. 8git switch

    Moves you to another branch, or creates and moves in one step. It is the clearer, branch-only replacement for the overloaded git checkout.

    • -c creates a new branch from where you are (or from a given start point).
    • git switch - jumps back to the previous branch.
    • Uncommitted changes travel with you; stash them if they conflict.
    bash
    git switch main
    git switch -c feature/search origin/main
    git switch -
    
  3. 9git merge

    Combines another branch's history into the current one. If histories diverged, Git creates a merge commit; otherwise it simply fast-forwards.

    • --no-ff always records a merge commit, keeping the feature visible in history.
    • On conflicts: fix the files, git add them, then git commit; or bail out with git merge --abort.
    • Merging never rewrites existing commits, so it is safe on shared branches.
    bash
    git switch main
    git pull
    git merge --no-ff feature/search
    # conflict? edit files, then:
    git add src/search.js && git commit
    
  4. 10git rebase -i

    Replays your commits on top of another base and lets you reorder, squash, reword or drop them first. Use it to tidy a feature branch before review.

    • It creates new commits, so only rebase branches nobody else has built on.
    • In the editor: pick, squash/fixup (merge into previous), reword, drop.
    • Stuck? git rebase --abort returns everything to how it was.
    bash
    git fetch origin
    git rebase -i origin/main
    # in the editor:
    # pick a1b2c3 Add search endpoint
    # fixup d4e5f6 typo
    # reword 789abc Add tests
    git push --force-with-lease
    

Sync with remote

Know exactly what comes down and when it gets merged.

  1. 11git fetch

    Downloads new commits and branches from the remote without touching your working files. It is always safe, so use it to look before you merge.

    • fetch = download only; pull = fetch + merge (or rebase) into your branch.
    • --prune removes remote-tracking branches that were deleted on the server.
    • Compare afterwards with git log HEAD..origin/main.
    bash
    git fetch --all --prune
    git log --oneline HEAD..origin/main   # what's new upstream
    
  2. 12git pull

    Fetches from the upstream branch and immediately integrates it into your current branch. Convenient, but it can surprise you with merge commits or conflicts.

    • --rebase puts your local commits on top of upstream for a linear history.
    • --ff-only refuses anything but a clean fast-forward; a safe default for main.
    • Commit or stash local changes first.
    bash
    git pull --rebase origin main
    git config --global pull.ff only
    git pull
    

Inspect

Read history and changes before you act on them.

  1. 13git log --oneline

    Shows commit history, one line per commit. Add a graph and decorations to see how branches split and joined.

    • --graph --decorate --all draws every branch as an ASCII tree.
    • Filter with --author, --since, -- <path> or -S "text" (commits that added/removed text).
    • -n 10 limits the output.
    bash
    git log --oneline --graph --decorate --all -n 20
    git log --oneline --since="2 weeks ago" --author="Asha"
    git log --oneline -S "MAX_PAGE_SIZE" -- src/
    
  2. 14git diff

    Shows line-by-line differences. With no arguments it compares working files to the staging area; with arguments it compares commits or branches.

    • --staged shows what will go into the next commit.
    • main...feature shows only what the feature branch changed since it split off.
    • --stat gives a per-file summary.
    bash
    git diff
    git diff --staged
    git diff --stat main...feature/search
    git diff HEAD~3 -- src/routes/todo.js
    

Undo safely

Fix mistakes without losing work or breaking teammates.

  1. 15git stash

    Shelves uncommitted changes so you get a clean working tree, for example to switch branches for an urgent fix, then restores them later.

    • -u also stashes untracked files.
    • pop applies and removes the stash; apply keeps it in the list.
    • Name stashes with -m so git stash list stays readable.
    bash
    git stash push -u -m "half-done search filters"
    git switch main   # fix the urgent bug...
    git switch feature/search
    git stash list
    git stash pop
    
  2. 16git restore

    Discards changes to files. It can unstage a file or throw away working-tree edits, replacing the confusing file uses of git checkout.

    • --staged unstages but keeps your edits.
    • Without --staged it overwrites the file; uncommitted edits are gone for good.
    • --source=<commit> restores a file as it was in an older commit.
    bash
    git restore --staged config.yml     # unstage
    git restore src/app.js              # discard local edits
    git restore --source=HEAD~2 README.md
    
  3. 17git reset

    Moves the current branch pointer to another commit. The mode decides what happens to your staged and working changes.

    • --soft keeps changes staged; --mixed (default) keeps them unstaged; --hard deletes them.
    • --hard permanently discards uncommitted work. Double-check git status first.
    • It rewrites history: use it only on commits you have not pushed. Lost something? git reflog can usually find it.
    bash
    git reset --soft HEAD~1    # undo last commit, keep it staged
    git reset HEAD~2           # undo 2 commits, keep edits
    git reset --hard origin/main   # DANGER: match remote exactly
    git reflog                 # find a commit you 'lost'
    
  4. 18git revert

    Creates a new commit that undoes an earlier one. History stays intact, which makes it the right way to undo something already pushed to a shared branch.

    • revert = safe for shared branches; reset = only for local, unpushed commits.
    • Reverting a merge commit needs -m 1 to say which parent to keep.
    • --no-edit accepts the default message.
    bash
    git revert --no-edit a1b2c3d
    git revert -m 1 9f8e7d6    # undo a merged PR
    git push
    

Power tools

Less frequent, but they save hours when you need them.

  1. 19git cherry-pick

    Copies one or more specific commits from another branch onto the current one, for example to back-port a bug fix to a release branch.

    • -x appends "cherry picked from ..." to the message for traceability.
    • Ranges work: A^..B includes A through B.
    • Overuse leads to duplicate commits; prefer merging when you need the whole branch.
    bash
    git switch release/2.3
    git cherry-pick -x 4c5d6e7
    git cherry-pick a1b2c3d^..f0e9d8c
    # on conflict: fix, git add, then
    git cherry-pick --continue
    
  2. 20git bisect

    Binary-searches history to find the commit that introduced a bug. You mark commits good or bad and Git halves the range each step.

    • Finds the culprit among 1,000 commits in about 10 steps.
    • git bisect run <script> automates it if a test exits non-zero on failure.
    • Always finish with git bisect reset.
    bash
    git bisect start
    git bisect bad                # current commit is broken
    git bisect good v2.1.0        # this tag worked
    git bisect run npm test -- search.spec.js
    git bisect reset
    
  3. 21Everyday workflowWorkflow

    Most team work is the same loop: branch from fresh main, commit small steps, rebase on the latest main, push and open a pull request. Practise it end to end until it feels automatic.

    • Keep branches short-lived to avoid painful conflicts.
    • Delete merged branches locally and remotely to stay tidy.
    bash
    git switch main && git pull --ff-only
    git switch -c feature/export-csv
    # ...edit, test...
    git add -p && git commit -m "Add CSV export for todos"
    git fetch origin && git rebase origin/main
    git push -u origin feature/export-csv
    # after the PR is merged:
    git switch main && git pull && git branch -d feature/export-csv
    

Quick tips

  • Create a throwaway repo and practise destructive commands (reset --hard, rebase) there first.
  • Run git status and git log --oneline -n 5 before anything that rewrites history.
  • git reflog is your safety net: almost nothing committed is truly lost for about 90 days.
  • Never rewrite history on shared branches; use revert there and keep rebase for your own branches.
  • Small, well-named commits make code review, revert and bisect dramatically easier.

Topic list based on the free Everything You Need to Get Placed checklist by Mohammad Fraz. Explanations and examples are original.