Tutorial Git Developer Tools DevOps Cheat Sheet

Free Git Commands Expansion Cheat Sheet Online — 120+ Advanced Git Commands Reference

· 22 min read

Most developers use Git every day, but most use only a fraction of its power. You know git add, git commit, git push. But when you need to untangle a messy rebase, recover a lost commit from the reflog, binary-search a bug with bisect, or set up Git hooks that enforce commit message conventions, the everyday commands fall short. Our free Git Commands Expansion Cheat Sheet fills this gap. It covers one hundred and twenty commands across ten categories — everything from repository initialization to advanced recovery tools. Every entry is interactive, searchable, and one click away from your clipboard. No signup, no tracking, entirely client-side.

Why Developers Need an Expansion Reference

The Git manual is over eight hundred pages. Memorizing it is neither practical nor necessary. What you need is a reference that surfaces the right command at the right moment — the flag you forgot, the workflow you use once a month, the recovery procedure you hope you will never need.

A basic Git cheat sheet answers: "How do I create a branch?" An expansion cheat sheet answers: "How do I split a commit during interactive rebase?" "How do I cherry-pick a range of commits without merge conflicts?" "How do I configure a pre-push hook that runs the full test suite?" These are the questions that separate developers who use Git from those who truly understand it.

Our Git Commands Expansion Cheat Sheet is themed "The Git Geologist's Stratigraphy Lab" — a deep-earth archaeological aesthetic with stratified mineral layers, floating dust motes, and specimen catalog cards. Each of the ten categories maps to a distinct mineral crystal color: Gold for Setup, Malachite green for Staging, Copper for Branching, Amethyst for History, Cinnabar red for Undo, Azurite blue for Stashing, Silver for Remotes, Quartz for Rebasing, Iron for Advanced Tools, and Obsidian for Hooks. The metaphor is intentional: Git commits are geological strata, and navigating them requires the same precision as excavating a fossil bed.

Repository Setup and Configuration: The Foundation Layer

Before any code enters version control, someone must initialize the repository and configure its behavior. These commands are used once per project but shape every subsequent operation.

Initializing and Cloning

git init creates a new repository in the current directory. It writes a .git subdirectory containing all the plumbing: the object database, refs, hooks templates, and configuration. For a central server repository that accepts pushes, use git init --bare — this creates a repository without a working tree, which is required because pushing to a non-bare repository causes errors.

git clone is how you obtain an existing repository. The basic form downloads the entire history:

git clone https://github.com/user/repo.git

For large repositories with years of history, a shallow clone saves time and bandwidth:

git clone --depth 1 https://github.com/user/repo.git

The --depth 1 flag downloads only the latest commit. Shallow clones are ideal for CI pipelines that only need the current state. To clone a specific branch without fetching others:

git clone --branch develop --single-branch https://github.com/user/repo.git

Configuration Management

Git configuration has three scopes: local (repository-specific, stored in .git/config), global (user-specific, stored in ~/.gitconfig), and system (machine-wide, stored in /etc/gitconfig). Local overrides global, which overrides system.

Set your identity for commit attribution:

git config user.name "Your Name"
git config user.email "email@example.com"

Configure essential behaviors globally:

git config --global core.editor "code --wait"
git config --global pull.rebase true
git config --global push.default current

The pull.rebase true setting makes git pull use rebase instead of merge by default — this keeps your history linear. The push.default current setting pushes the current branch to a remote branch with the same name, which is usually what you want.

Aliases are productivity multipliers. A few keystrokes saved across thousands of commands adds up:

git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.st status
git config --global alias.lg "log --graph --oneline --all"

Remote Management

git remote add connects your local repository to a remote:

git remote add origin https://github.com/user/repo.git

If a remote URL changes — for example, when a repository is renamed or migrated — update it without re-cloning:

git remote set-url origin git@github.com:new-org/repo.git

To see all configured remotes with their URLs:

git remote -v

Staging and Commits: The Deposition Layer

Git's staging area is its most distinctive feature. Unlike other version control systems that commit everything that has changed, Git lets you craft exactly what goes into each commit. This fine-grained control is the foundation of a clean, readable history.

Understanding the Staging Area

git status is your constant companion. It shows three categories of files: changes to be committed (staged), changes not staged for commit (modified but unstaged), and untracked files. The short format (git status -s) is ideal for scripting and for fitting more information on screen.

git add stages changes. Its most powerful variant is patch mode:

git add -p

Patch mode walks you through each change hunk and asks: stage this hunk? (y/n). You can split hunks (s), edit them (e), or skip them (n). This means you can make three logical commits from a single file's changes without ever leaving the command line.

To stage everything — modifications, deletions, and new files — in one command:

git add -A

Writing Good Commits

A commit is not just a save point. It is a communication tool. git commit -m is for short, single-line messages. For anything more complex — and most commits should be — omit -m to open your editor:

git commit

The convention for commit messages: a short summary line (50 characters or fewer), a blank line, and a detailed explanation of what changed and why. The summary line should complete the sentence "This commit will...". Write in the imperative: "Fix login validation bug" not "Fixed login validation bug".

If you forgot to include a file or need to fix a typo in the last commit:

git add forgotten-file.txt
git commit --amend --no-edit

The --amend flag rewrites the last commit to include the newly staged changes. The --no-edit flag keeps the original commit message. This rewrites history, so never amend a commit that has been pushed to a shared branch.

Inspecting Changes

git diff shows unstaged changes. git diff --staged shows staged changes. Understanding the difference is critical:

git diff              # what did I change but not yet stage?
git diff --staged     # what will go into the next commit?
git diff HEAD~1       # how does this commit differ from the last?

To remove a tracked file and stage the deletion:

git rm file.txt

To move or rename a file while preserving its history:

git mv old-name.js new-name.js

Branching and Merging: The Fork Layer

Branching is Git's superpower. Branches are lightweight — just a pointer to a commit — which makes them cheap to create and merge. This enables workflows like feature branching, where every feature, bug fix, or experiment gets its own isolated timeline.

Branch Operations

Create branches, list them, and delete them:

git branch feature/new-login       # create
git branch                          # list local
git branch -a                       # list all including remotes
git branch -d feature/old-login     # safe delete (only if merged)
git branch -D feature/broken        # force delete

The modern way to switch branches (Git 2.23+) uses git switch:

git switch main                     # switch to existing branch
git switch -c feature/experiment    # create and switch

The traditional git checkout still works and is more widely known:

git checkout develop
git checkout -b feature/experiment

Merging Strategies

A merge joins two development histories:

git checkout main
git merge feature/completed

By default, Git uses a fast-forward merge if possible — it simply moves the branch pointer forward without creating a merge commit. This produces a linear history but loses the information that a branch existed. Use --no-ff to force a merge commit:

git merge --no-ff feature/completed

When conflicts arise, Git marks the conflicting regions in the affected files with <<<<<<<, =======, and >>>>>>>. After resolving them:

git add resolved-file.txt
git merge --continue

If the conflicts are too complex and you want to start over:

git merge --abort

For a squash merge — combining all commits from a feature branch into a single commit on main:

git merge --squash feature/completed
git commit -m "Add user authentication feature"

Squash merges keep the main branch's history clean. The tradeoff is losing the granular commit history from the feature branch. This is the GitHub default for pull request merges.

History and Logs: The Stratigraphy Layer

Git's history is a directed acyclic graph of commits. Navigating it efficiently requires knowing the right log flags. The default git log output is verbose and rarely what you want.

Essential Log Formats

The most useful log format for daily use:

git log --graph --oneline --all --decorate

This shows every branch and tag as an ASCII graph with one line per commit. Many developers alias this to git lg.

To see the full diff for recent commits:

git log -p -2

Filter by author, date range, or commit message:

git log --author="Jane" --since="2 weeks ago" --oneline
git log --grep="fix" --oneline

Searching Through History

The pickaxe search (-S) finds commits that added or removed a specific string. This is invaluable for answering "when was this function introduced or removed?":

git log -S "deprecated_function" --oneline

git blame annotates each line of a file with the commit that last modified it, along with the author and date:

git blame src/main.js

For a specific line range:

git blame -L 10,50 src/main.js

git show displays the full details of any Git object — most commonly a commit:

git show HEAD~3          # show the 4th most recent commit
git show abc1234          # show a specific commit
git show --stat HEAD      # show commit with file change summary

git shortlog groups commits by author, useful for release notes:

git shortlog -sn         # commit counts by author
git shortlog v1.0..v2.0   # commits between two tags

Undoing Changes: The Excavation Layer

Mistakes happen. Git provides multiple levels of undo, from gentle to destructive. Knowing which tool to use — reset, revert, restore, or clean — is essential for working safely.

Reset: Rewinding the Branch Pointer

git reset moves the current branch pointer and optionally modifies the staging area and working tree. It comes in three modes:

git reset --soft HEAD~1    # undo commit, keep changes staged
git reset --mixed HEAD~1   # undo commit, unstage changes (default)
git reset --hard HEAD~1    # undo commit, discard all changes (DESTRUCTIVE)

--soft is safest: it undoes the commit but leaves your changes staged, ready to re-commit. --hard discards changes permanently — use it only on private branches and only when you are certain.

To unstage a specific file without losing work:

git reset HEAD file.txt

Revert: Safe Undo for Shared History

For commits that have already been pushed, git reset rewrites history and will cause conflicts for collaborators. Use git revert instead:

git revert HEAD

Revert creates a new commit that undoes the specified commit. It does not erase history — it adds to it. This is always safe for shared branches. To revert a range of commits in a single commit:

git revert --no-commit HEAD~3..HEAD
git commit -m "Revert last 3 commits"

Restore: Modern File-Level Undo

git restore (Git 2.23+) provides a clearer interface for file-level undo. It replaces the overloaded git checkout -- file and git reset HEAD file:

git restore file.txt              # discard working tree changes
git restore --staged file.txt      # unstage but keep changes
git restore --source HEAD~2 file.txt  # restore file to version from 2 commits ago

Clean: Removing Untracked Files

git clean removes untracked files — generated build artifacts, editor temp files, test outputs. Always dry-run first:

git clean -n     # show what would be removed
git clean -fd    # force remove untracked files and directories

Stashing: The Temporary Storage Layer

Stashing is Git's context-switching mechanism. You are halfway through a feature, and a critical hotfix comes in. Instead of making a half-baked commit or losing work, stash your changes, switch branches, fix the issue, and pop the stash when you return.

git stash                        # stash tracked changes
git stash push -m "WIP: auth refactor"  # stash with message
git stash -u                      # stash including untracked files
git stash list                    # see all stashes

Stashes form a stack. The most recent is stash@0:

git stash pop                    # apply and remove top stash
git stash pop stash@{2}          # apply and remove a specific stash
git stash apply                   # apply without removing
git stash drop stash@{0}         # delete without applying

To inspect what is inside a stash before applying it:

git stash show -p stash@{0}

To recover a stash as a new branch (useful if the original branch has changed significantly):

git stash branch feature/recover stash@{0}

When you are certain you will never need any stashed changes again:

git stash clear

Remote Operations: The Distributed Layer

Git is a distributed version control system. Every clone is a full backup of the repository. Remote operations synchronize these independent copies.

Fetching Without Merging

git fetch downloads objects and refs from a remote without modifying your working tree or branches. This is the safe first step — see what has changed before deciding how to integrate it:

git fetch origin
git fetch --all
git fetch --prune    # also remove tracking branches deleted on remote

Pulling: Fetch and Integrate

git pull is git fetch followed by git merge (or git rebase with --rebase):

git pull origin main
git pull --rebase origin main

The --rebase flag produces a linear history by replaying your local commits on top of the remote ones. This avoids unnecessary merge commits and is the preferred workflow for many teams.

Pushing: Sharing Your Work

git push uploads your commits to a remote:

git push origin main
git push -u origin feature/new-feature    # push and set upstream tracking
git push --tags                           # push all local tags

If you need to force-push — for example, after amending a commit or rebasing a feature branch — use --force-with-lease instead of --force:

git push --force-with-lease origin main

--force-with-lease checks that the remote branch hasn't changed since you last fetched. If someone else pushed in the meantime, the force push is rejected. This prevents accidentally overwriting a collaborator's work.

Remote Maintenance

Clean up stale remote-tracking branches:

git remote prune origin

Get detailed information about a remote's branches and configuration:

git remote show origin

Rebasing: The History Rewriting Layer

Rebasing is Git's most powerful — and most dangerous — history manipulation tool. It rewrites commit history to create a cleaner, more logical narrative.

Basic Rebase

A standard rebase replays the current branch's commits on top of another branch:

git checkout feature
git rebase main

This makes it appear as if the feature branch was created from the latest commit on main. The resulting history is linear, with no merge commits. Use this before opening a pull request to ensure a clean merge.

If conflicts occur during a rebase, resolve them and continue:

git add resolved-file.txt
git rebase --continue

To abort and return to the pre-rebase state:

git rebase --abort

Interactive Rebase: Editing History

Interactive rebase is where Git's power truly shows. It opens an editor listing the last N commits and lets you reorder, squash, edit, split, or drop them:

git rebase -i HEAD~5

The editor shows each commit with the default action pick. Change pick to: - squash or s: meld this commit into the previous one, combining messages - fixup or f: like squash but discard this commit's message - reword or r: change the commit message - edit or e: stop for amending - drop or d: remove this commit entirely

The autosquash workflow makes cleaning up fixup commits effortless:

git commit --fixup HEAD~3      # create a fixup targeting commit 3 back
git rebase -i --autosquash HEAD~10  # automatically reorder and squash

Transplanting Commits with --onto

git rebase --onto is surgical. It moves a range of commits from one base to another:

git rebase --onto main feature/old-base feature/topic

This takes the commits on feature/topic that are not on feature/old-base and replays them on top of main. Use this when a feature was built on the wrong base branch.

Cherry-Pick: Selective Commit Transfer

Cherry-pick applies a specific commit to the current branch without merging the entire history:

git cherry-pick abc1234

For multiple commits:

git cherry-pick abc1234..def5678

To cherry-pick without auto-committing (useful for combining multiple picks into one commit):

git cherry-pick -n abc1234

Cherry-pick shines when you need to backport a bug fix to a release branch without merging all the other changes from the development branch.

Advanced Tools: The Laboratory Layer

These commands solve specific, complex problems. You may not use them daily, but when you need them, nothing else will do.

Bisect: Binary Search for Bugs

git bisect performs a binary search through your commit history to identify exactly which commit introduced a regression:

git bisect start
git bisect bad              # current commit has the bug
git bisect good v1.0        # v1.0 was known good

Git checks out a commit at the midpoint. Test it. If the bug is present, mark it bad. If not, mark it good. Git narrows the range by half each time. After roughly log2(N) steps, Git identifies the problematic commit.

Automate this with a test script:

git bisect run npm test

The script should exit 0 for good (no bug) and any code from 1 to 127 for bad. After bisect finishes, return to normal:

git bisect reset

Reflog: The Commit Safety Net

The reflog records every position your HEAD has visited — commits, resets, rebases, merges, checkouts. It is your undo for commands that seem irreversible:

git reflog

Even if you delete a branch or git reset --hard past a commit, the reflog retains the SHA. To recover a lost commit:

git checkout -b recovered-branch <SHA-from-reflog>

Reflog entries expire after 90 days by default for unreachable commits. For critical repositories, consider extending this:

git config gc.reflogExpire 180.days

Worktree: Parallel Development

git worktree lets you check out multiple branches simultaneously in separate directories — all sharing the same repository data:

git worktree add ../hotfix hotfix/critical
git worktree add ../feature feature/new-module

Now you can work on the hotfix in ../hotfix and the feature in ../feature without stashing or switching branches. This is faster than the traditional stash-switch-work-commit-switch-pop cycle and dramatically reduces context-switching friction.

git worktree list       # see all linked worktrees
git worktree remove ../hotfix  # clean up when done

Submodule Management

Submodules embed external repositories inside your project:

git submodule add https://github.com/lib/dep.git libs/dep

After cloning a project with submodules, initialize and fetch them:

git submodule update --init --recursive

To update submodules to their latest remote commits:

git submodule update --remote

Git Grep: Fast Code Search

git grep searches the working tree using Git's internal engine. It is faster than system grep for large codebases because it uses Git's index:

git grep "TODO"
git grep -n "FIXME" -- "*.js"
git grep -i "error" -- "src/**/*.ts"

Hooks and Configuration: The Automation Layer

Git hooks are executable scripts that trigger at specific points in the Git workflow. They enforce standards, run checks, and automate repetitive tasks — all without external tooling.

Client-Side Hooks

The most impactful hooks for daily development:

pre-commit — runs before a commit is created. Use for linting, formatting, and fast tests:

#!/bin/sh
# .git/hooks/pre-commit
npm run lint && npm test -- --onlyChanged

commit-msg — validates commit message format. Enforce conventional commits:

#!/bin/sh
# .git/hooks/commit-msg
grep -qE "^(feat|fix|docs|style|refactor|test|chore)" "$1" || {
  echo "Commit message must start with a conventional commit type"
  exit 1
}

pre-push — runs before a push. Use for the full test suite and security checks:

#!/bin/sh
# .git/hooks/pre-push
npm run test:full && npm audit

post-merge — runs after a successful merge. Ideal for dependency updates:

#!/bin/sh
# .git/hooks/post-merge
npm install

Git Attributes and Ignore Rules

.gitignore tells Git which files to exclude from tracking entirely:

# .gitignore
node_modules/
.env
*.log
dist/
.DS_Store

.gitattributes defines per-path behaviors — line ending normalization, diff drivers, merge strategies:

# .gitattributes
*.js text eol=lf
*.png binary
*.md diff=markdown
*.lock merge=binary

To debug why a file is being ignored:

git check-ignore -v dist/bundle.js

Repository Maintenance

Over time, Git repositories accumulate loose objects and unnecessary files. Periodic maintenance keeps performance acceptable:

git gc --aggressive --prune=now

git fsck verifies the integrity of the object database:

git fsck --full

Tags: Marking Release Points

Tags are permanent references to specific commits, typically used for version releases:

git tag v1.0.0                          # lightweight tag
git tag -a v1.0.0 -m "First stable release"  # annotated tag
git tag -l "v2.*"                        # list matching tags

Annotated tags include a message, author, and date — they are full Git objects. Always use annotated tags for releases. Lightweight tags are just pointers and should be reserved for temporary or private use.

Putting It All Together: A Production Workflow

Here is a realistic workflow that combines many of the commands covered above. You are working on a feature, and a hotfix comes in:

# Save your in-progress work
git stash push -m "WIP: user dashboard refactor"

# Create and work on the hotfix
git switch main
git pull --rebase origin main
git switch -c hotfix/critical-bug
# ... fix the bug ...
git add -p                          # stage only the relevant changes
git commit -m "Fix null pointer in payment processing"
git push -u origin hotfix/critical-bug

# Return to your feature
git switch feature/dashboard
git stash pop

# Before merging, clean up your branch history
git fetch origin
git rebase -i origin/main           # squash fixup commits, reword messages
git push --force-with-lease origin feature/dashboard

This workflow uses stashing for context switching, patch staging for precise commits, interactive rebase for history cleanup, and force-with-lease for safe force-pushing. Every command serves a purpose, and each builds on the foundation of the core Git model: a directed acyclic graph of commits.

Explore More DevToolkit Git References

The Git Commands Expansion Cheat Sheet is part of a growing ecosystem of developer reference tools. For related resources, explore:

All tools are free, interactive, and 100% client-side. No signup required. Bookmark the ones you use most.

Found this useful? Check out our free developer tools or browse more articles.