|$ curl https://forge-ai.dev/api/markdown?path=docs/git/commands-reference
$cat docs/git-commands-reference.md
updated Today·35-45 min read·published

Git Commands Reference

◆Git◆Reference◆Commands◆All Levels🎯Free Tools
Introduction

This page is the Git commands encyclopedia — porcelain day-to-day tools and the plumbing underneath. Use it alongside How to Master Git and the Git Roadmap.

ℹ

info

Porcelain commands are what humans type. Plumbing commands manipulate objects and refs directly — prefer porcelain unless you are debugging or scripting internals.
Porcelain vs Plumbing

Git splits the UI into high-level porcelain and low-level plumbing. Scripts that parse porcelain output break when formats change — prefer plumbing or --porcelain machine modes.

KindExamplesAudience
Porcelainadd, commit, status, log, switch, merge, rebase, pushHumans & agents day-to-day
Plumbinghash-object, cat-file, update-index, write-tree, commit-tree, update-refInternals, recovery scripts
Machine porcelainstatus --porcelain=v1, log --pretty=format:CI parsers, tools
porcelain-machine.sh
Bash
1# Stable for scripts
2git status --porcelain=v1 -uall
3git diff --name-status --diff-filter=ACMR
4git log -1 --pretty=format:'%H %an %s'
5
6# Plumbing peek at an object
7git rev-parse HEAD
8git cat-file -t HEAD
9git cat-file -p HEAD | head
config

Read and write configuration at system, global, local, and worktree scopes. See Git Config for deep dive.

CommandPurpose
git config --global user.nameSet identity (required)
git config --list --show-originShow all keys with file source
git config --global -eEdit ~/.gitconfig
git config --unset keyRemove a key
git config --get-regexp aliasList aliases
config.sh
Bash
1git config --global user.name "Jane Doe"
2git config --global user.email "jane@example.com"
3git config --global init.defaultBranch main
4git config --global core.editor "code --wait"
5git config --global pull.rebase true
6git config --global fetch.prune true
7git config --list --show-origin | head -40
init / clone

Create new repositories or copy existing ones. Prefer clone when a remote already exists.

CommandPurpose
git init -b mainNew repo with main branch
git clone url dirCopy remote into dir
git clone --depth 1Shallow clone (CI)
git clone --filter=blob:nonePartial clone (blobs on demand)
git clone --recurse-submodulesInclude submodules
git clone --bareBare remote-style repo
init-clone.sh
Bash
1git init -b main
2git clone git@github.com:org/app.git
3git clone --depth 1 --branch main https://github.com/org/app.git app-ci
4git clone --filter=blob:none --sparse git@github.com:org/monorepo.git
status / add / commit

Move changes from working tree → index → history. Always inspect status before commit.

CommandPurpose
git status -sbShort branch + file status
git add pathStage file or directory
git add -pInteractive hunk staging
git add -uStage tracked modifications/deletes
git commit -m "msg"Create commit from index
git commit --amend --no-editAmend last (local only)
git commit --fixup HEAD~1Fixup for autosquash
git rm / git mvRemove / rename tracked paths
status-add-commit.sh
Bash
1git status -sb
2git add src/app.ts
3git add -p README.md
4git commit -m "feat(auth): add session refresh"
5git commit --amend --no-edit # only if not pushed
6git restore --staged src/app.ts # unstage
⚠

warning

Never amend commits that have already been pushed to a shared branch unless the team explicitly allows force-with-lease on that branch.
log / diff / show

Inspect history and changes. diff compares trees; show displays one object.

CommandPurpose
git log --oneline --graph --allVisual history
git log -S'symbol'Pickaxe: commits changing string
git log -p -1Patch for latest commit
git diffUnstaged vs index
git diff --stagedIndex vs HEAD
git diff main...HEADTriple-dot: changes on branch
git show HEAD:pathFile content at revision
log-diff.sh
Bash
1git log --oneline --graph --decorate -20
2git log --author='Jane' --since='2 weeks ago' --pretty=format:'%h %ad %s' --date=short
3git log -S'createHash' --oneline -- src/
4git diff main...HEAD --stat
5git diff --staged
6git show abc123 --stat
7git show HEAD:package.json | head
branch / switch / checkout

Prefer git switch for branches and git restore for files. checkout still works but overloads two jobs.

CommandPurpose
git branch -vvList local with upstream
git switch -c feature/xCreate and switch
git switch mainSwitch branch
git switch -Previous branch
git branch -d feature/xDelete merged branch
git branch -D feature/xForce delete
git checkout abc123 -- fileLegacy: restore file from rev
branch.sh
Bash
1git branch -vv
2git switch -c feature/login
3git switch main
4git branch --merged main
5git branch -d feature/login
6git push origin --delete feature/login
merge / rebase

Integrate histories. Merge preserves topology; rebase replays commits for linear history. See Merge and Rebasing.

CommandPurpose
git merge featureMerge into current branch
git merge --no-ff featureAlways create merge commit
git merge --abortAbort conflicted merge
git rebase mainReplay onto main
git rebase -i HEAD~5Interactive rewrite
git rebase --ontoAdvanced transplant
git rebase --abort / --continueConflict control
merge-rebase.sh
Bash
1git switch main
2git merge --no-ff feature/login -m "merge: feature/login"
3git switch feature/payments
4git fetch origin
5git rebase origin/main
6# conflict? fix files, then:
7git add -A && git rebase --continue
reset / restore / revert

Three different undo tools. Reset moves branch tip; restore fixes files; revert adds an inverse commit.

CommandPurpose
git reset --soft HEAD~1Undo commit, keep staged
git reset HEAD~1Mixed: undo commit, unstage
git reset --hard HEAD~1Destroy WD+index to tip
git restore fileDiscard WD changes
git restore --staged fileUnstage
git restore --source=HEAD~1 fileCheckout file from rev
git revert abc123New commit undoing abc123
git revert -m 1 mergeHashRevert a merge
undo.sh
Bash
1# Local unpublished: soft reset and recommit
2git reset --soft HEAD~1
3git commit -m "feat: better message"
4
5# Discard one file's uncommitted edits
6git restore src/buggy.ts
7
8# Public bugfix: revert
9git revert abc123 --no-edit
10git revert -m 1 def456 # merge commit
✕

danger

git reset --hard discards uncommitted work permanently (unless recoverable via stash/reflog edges). Prefer restore for single files.
stash

Temporarily shelf dirty work. Prefer named stashes; consider worktrees for longer context switches.

CommandPurpose
git stash push -m "wip"Save WD+index
git stash push -u -m "wip"Include untracked
git stash listShow stack
git stash show -p stash@{0}Show patch
git stash popApply and drop
git stash applyApply keep entry
git stash dropDelete entry
stash.sh
Bash
1git stash push -u -m "wip: login form"
2git switch main
3# hotfix...
4git switch -
5git stash pop
6git stash list
remote / fetch / pull / push

Synchronize with remotes. Fetch downloads; pull = fetch + integrate; push publishes.

CommandPurpose
git remote -vList remotes
git fetch --all --pruneUpdate remote-tracking
git pull --rebaseFetch + rebase
git push -u origin HEADPush and set upstream
git push --force-with-leaseSafer force push
git push origin :branchDelete remote branch
remote.sh
Bash
1git remote -v
2git fetch origin --prune
3git status -sb
4git pull --rebase origin main
5git push -u origin HEAD
6# Feature branch rewrite after rebase:
7git push --force-with-lease origin feature/login
✕

danger

Never git push --force to main/master. Use --force-with-lease only on your feature branches when required.
tag

Mark releases. Prefer annotated (or signed) tags for versions.

CommandPurpose
git tag -a v1.2.0 -m "..."Annotated tag
git tag -s v1.2.0Signed tag
git tag -l 'v*'List tags
git push origin v1.2.0Push one tag
git push origin --tagsPush all tags
git tag -d v1.2.0Delete local tag
tag.sh
Bash
1git tag -a v1.2.0 -m "Release 1.2.0"
2git show v1.2.0
3git push origin v1.2.0
4git tag -l 'v1.*' --sort=-v:refname
bisect

Binary search history to find the commit that introduced a bug. See Bisect.

bisect.sh
Bash
1git bisect start
2git bisect bad HEAD
3git bisect good v1.0.0
4# test, then:
5git bisect good # or: git bisect bad
6# automate:
7git bisect run npm test -- --runInBand
8git bisect reset
cherry-pick

Apply the changes from existing commits onto the current branch.

cherry-pick.sh
Bash
1git switch release/1.2
2git cherry-pick abc123
3git cherry-pick abc123 def456
4git cherry-pick -n abc123 # apply without committing
5git cherry-pick --abort
6git cherry-pick --continue
reflog

Local safety net of where HEAD and branches pointed. Primary recovery tool after destructive ops.

reflog.sh
Bash
1git reflog
2git reflog show main
3git reset --hard HEAD@{3}
4git branch recovery HEAD@{5}
5# expire (dangerous):
6# git reflog expire --expire=now --all
7# git gc --prune=now
ℹ

info

Reflog is local — it is not pushed. Recover quickly; entries expire (default ~90 days for unreachable).
worktree

Multiple working directories linked to one repository — better than stash for parallel work.

worktree.sh
Bash
1git worktree add ../app-hotfix hotfix/sev1
2git worktree list
3cd ../app-hotfix
4# fix, commit, push...
5cd -
6git worktree remove ../app-hotfix
7git worktree prune
sparse-checkout

Check out only part of a tree (monorepos). Cone mode is recommended.

sparse.sh
Bash
1git clone --filter=blob:none --sparse git@github.com:org/mono.git
2cd mono
3git sparse-checkout init --cone
4git sparse-checkout set apps/web packages/ui
5git sparse-checkout list
6git sparse-checkout add packages/config
submodule

Nest another Git repo at a pinned commit. Heavy operational cost — prefer packages when possible.

submodule.sh
Bash
1git submodule add git@github.com:org/lib.git libs/lib
2git submodule update --init --recursive
3git submodule update --remote --merge
4git submodule status
5# clone with subs:
6git clone --recurse-submodules git@github.com:org/app.git
LFS overview

Git Large File Storage replaces big binaries with pointer files. See Git LFS.

lfs.sh
Bash
1git lfs install
2git lfs track "*.psd"
3git lfs track "*.mp4"
4git add .gitattributes
5git add design.psd
6git commit -m "chore: track PSD with LFS"
7git lfs ls-files
8git lfs migrate import --include="*.psd" --everything
Plumbing Quick Reference

Useful when explaining objects or recovering manually. Full story: Internals.

CommandPurpose
git hash-object -w fileCreate blob
git cat-file -p oidPretty-print object
git ls-files -sShow index entries
git write-treeTree from index
git commit-treeCommit from tree
git update-refMove a ref
git rev-list --objectsList reachable objects
git verify-pack -vInspect packfile
plumbing.sh
Bash
1echo 'hello' > /tmp/hello.txt
2BLOB=$(git hash-object -w /tmp/hello.txt)
3git cat-file -t $BLOB
4git cat-file -p $BLOB
5git rev-parse HEAD^{tree}
6git ls-tree -r HEAD | head
Daily Driver Cheat Sheet
daily.sh
Bash
1git status -sb
2git add -p
3git commit -m "type(scope): summary"
4git fetch origin --prune
5git rebase origin/main
6git push -u origin HEAD
7git switch -c feature/x
8git restore --staged PATH
9git log --oneline --graph --decorate -15
10git diff main...HEAD
✓

best practice

Memorize the daily driver; look up rare flags. Depth comes from mastery stages, not from knowing every option.
Useful Environment Variables

Environment variables change Git behavior for a single command or shell session.

env.sh
Bash
1GIT_AUTHOR_NAME="Bot"
2GIT_AUTHOR_EMAIL="bot@example.com"
3GIT_SEQUENCE_EDITOR=:
4GIT_EDITOR=true
5GIT_TRACE=1
6GIT_LFS_SKIP_SMUDGE=1
Pretty Formats & Log Recipes
pretty.sh
Bash
1git log --pretty=format:'%h %ad %an %s' --date=short
2git log --pretty=fuller -1
3git shortlog -sn --all --no-merges
4git log --first-parent main
5git log --merges --oneline
6git log -G'todo' --oneline
7git log --follow -- path/renamed.ts
✓

best practice

Machine-readable formats beat parsing human log output in CI scripts.
Pathspecs

Limit commands to subsets of the tree with pathspecs — including magic signatures.

pathspecs.sh
Bash
1git add -- '*.ts'
2git log -- ':(exclude)vendor' -- .
3git grep -n 'TODO' -- ':!dist' ':!node_modules'
4git reset -- 'src/**/*.test.ts'
Exit Codes & Scripting
scripting.sh
Bash
1git diff --quiet || echo "dirty"
2git diff --cached --quiet || echo "staged changes"
3git merge-base --is-ancestor abc123 main && echo "already in main"
Undo Operations Matrix
  • Uncommitted file edits → git restore
  • Unstage → git restore --staged
  • Local commit → git reset --soft/--mixed
  • Published commit → git revert
  • Lost tip → git reflog + reset/branch
  • Merge in progress → git merge --abort
  • Rebase in progress → git rebase --abort
Daily Recipes

Start a feature

recipe-feature.sh
Bash
1git fetch origin
2git switch -c feature/x origin/main
3git add -p && git commit -m "feat(x): ..."
4git push -u origin HEAD
5gh pr create --fill

Update feature onto main

recipe-update.sh
Bash
1git fetch origin
2git rebase origin/main
3git push --force-with-lease

Hotfix with worktree

recipe-hotfix.sh
Bash
1git worktree add ../hotfix -b hotfix/sev1 origin/main
2cd ../hotfix
3# fix + test + PR
4git push -u origin HEAD
5gh pr create --fill
6cd - && git worktree remove ../hotfix

Safe undo on main

recipe-undo.sh
Bash
1git revert HEAD --no-edit
2git push
3# Never: git reset --hard HEAD~1 && git push --force origin main
Extended Practice Lab

Chain many porcelain commands in a disposable lab.

deep-lab.sh
Bash
1#!/usr/bin/env bash
2set -euo pipefail
3LAB=/tmp/forgelearn-cmd-lab
4rm -rf "$LAB" && mkdir -p "$LAB" && cd "$LAB"
5git init -b main
6git config user.email a@b.c && git config user.name Lab
7echo x > f && git add f && git commit -m "a"
8git switch -c feature
9echo y > f && git commit -am "b"
10git switch main
11git merge --no-ff feature -m "merge"
12git log --oneline --graph
13git rev-parse HEAD^{tree}
14git cat-file -p HEAD | head
15echo OK
Hooks Quick Commands

Full guide: Hooks. Common entry points:

hooks.sh
Bash
1ls .git/hooks
2chmod +x .git/hooks/pre-commit
3git config core.hooksPath .githooks
4# sample pre-commit
5cat > .githooks/pre-commit <<'EOF'
6#!/usr/bin/env bash
7git diff --cached --name-only | grep -E '\.env$' && exit 1
8exit 0
9EOF
10chmod +x .githooks/pre-commit
Maintenance Commands
maintenance.sh
Bash
1git maintenance run
2git maintenance start
3git gc --auto
4git prune
5git remote prune origin
6git fetch --prune
7git count-objects -vH
8git fsck --full | head
Quick Glossary
  • HEAD — pointer to current commit (usually via branch)
  • index/staging area — next commit snapshot
  • fast-forward — move branch tip without merge commit
  • detached HEAD — HEAD points at commit, not branch
  • upstream — remote tracking branch for push/pull
  • reflog — local history of tip movements
  • OID — object id (hash)
  • porcelain vs plumbing — user UI vs low-level commands
ℹ

info

Continue with Internals for object model detail.

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.