Git CLI Quick Reference
Commands grouped by what you are trying to do. For the GitHub CLI, see the GitHub CLI Quick Reference.
Configuration
git config --global user.name "Your Name" # identity (required before committing)
git config --global user.email "you@example.com"
git config --global init.defaultBranch main # branch name for new repos
git config --global pull.rebase true # rebase instead of merge on pull
git config --global merge.conflictStyle zdiff3 # show the common ancestor in conflicts
git config --global rerere.enabled true # reuse recorded conflict resolutions
git config --global push.autoSetupRemote true # first push sets upstream automatically
git config --local user.email "you@company.com" # override for one repository
git config --list --show-origin # every value and the file it came from
Creating and Cloning Repositories
git init # create new repo in current directory
git clone https://github.com/user/repo.git # clone a remote repo
git clone https://github.com/user/repo.git my-dir # clone into a specific directory
git clone --recurse-submodules https://github.com/org/repo.git # clone with submodules
Checking Status and Viewing History
# Status
git status # current state of working tree
git status -s # short format
# Log
git log # full commit history
git log --oneline # one line per commit
git log --oneline --graph --all # visual branch graph
git log -5 # last 5 commits
git log -p # show diff for each commit
git log --oneline -- path/to/file.cs # history of a specific file
git log --follow -p src/OldName.cs # history including renames
git log --oneline main..feature/foo # commits on feature not on main
# Inspecting objects
git cat-file -p <hash> # read any git object
git cat-file -p HEAD^{tree} # list tree at a commit
git show v1.0.0 # show tag or commit details
Staging and Committing
# Staging
git add src/MyClass.cs # stage a specific file
git add . # stage everything in current dir and below
git add -u # stage all tracked file changes (not new files)
git add -p src/MyClass.cs # stage specific hunks interactively
# Committing
git commit -m "your message" # commit staged changes
git commit -am "your message" # stage tracked changes + commit in one step
git commit --amend -m "corrected message" # amend the last commit (rewrites history)
git commit --amend --no-edit # add staged changes to the last commit
git commit --fixup <hash> # mark a fix for an earlier commit (see autosquash)
Viewing Differences
git diff # unstaged changes (working dir vs index)
git diff --staged # staged changes (index vs HEAD)
git diff abc1234 def5678 # compare two commits
git diff main feature/my-work # compare the tips of two branches
git diff main...feature/my-work # only what the branch changed since it diverged
git diff --name-only main...feature/my-work # only show which files the branch changed
Branching
# Listing
git branch # local branches
git branch -a # all branches including remotes
# Creating and switching
git switch -c feature/my-work # create + switch
git switch main # switch to existing branch
git switch - # switch back to the previous branch
git switch -c hotfix/fix-bug v2.3.1 # branch from specific tag/commit
# Deleting
git branch -d feature/my-work # delete (safe, checks merge status)
git branch -D feature/my-work # force delete
git push origin --delete feature/old-branch # delete remote branch
Merging
git merge feature # merge into current branch
git merge --no-ff feature # force merge commit (no fast-forward)
git merge --squash feature # squash all commits into one, then commit
# After a squash merge you must commit manually
git commit -m "add feature X"
# Resolving merge conflicts
git status # list files that still conflict
git add src/ConflictingFile.cs # mark file as resolved after editing
git commit # complete the merge
git merge --abort # give up and restore the pre-merge state
Rebasing
git rebase main # replay current branch on top of main
git rebase origin/main # rebase onto remote main
# Interactive rebase (reorder, squash, edit, drop commits)
git rebase -i HEAD~4 # last 4 commits
git rebase -i main # everything since branching from main
git rebase -i --autosquash main # apply --fixup commits automatically
# Moving part of a branch
git rebase --onto main feature/base feature/child # move child's own commits onto main
git rebase --update-refs main # also move stacked branches along
# During rebase conflict resolution
git add <resolved-file>
git rebase --continue # proceed after resolving
git rebase --skip # drop the commit being applied
git rebase --abort # cancel and return to pre-rebase state
Remote Operations
# Managing remotes
git remote -v # list remotes with URLs
git remote add upstream https://github.com/org/repo.git
git remote rename origin old-origin
git remote remove upstream
# Fetch, pull, push
git fetch origin # download without merging
git pull # fetch + fast-forward; fails on divergence unless pull.rebase is set
git pull --rebase # fetch + rebase local commits on top
git pull --no-rebase # fetch + merge
git push # push current branch
git push -u origin feature/my-work # push and set upstream tracking
git push origin local-branch:remote-branch # push specific branch mapping
git push --force-with-lease # force push, but not over others' new commits
Tags
# Creating
git tag v1.0.0 # lightweight tag at HEAD
git tag v0.9.0 abc1234 # lightweight tag at specific commit
git tag -a v1.0.0 -m "Release 1.0.0" # annotated tag (recommended for releases)
git tag -s v1.0.0 -m "Release 1.0.0" # signed tag (GPG or SSH key)
# Listing and inspecting
git tag # list all tags
git tag -l "v1.*" # filter by pattern
git show v1.0.0 # show tag details
git tag -v v1.0.0 # verify signed tag
# Pushing and deleting
git push origin v1.0.0 # push a specific tag
git push origin --tags # push all tags
git push --follow-tags # push commits + their annotated tags
git tag -d v1.0.0 # delete locally
git push origin --delete v1.0.0 # delete on remote
Stashing
git stash # save uncommitted changes
git stash push -m "WIP: refactoring payments" # save with a descriptive name
git stash push --include-untracked # include new files
git stash push --all # include untracked and ignored files
git stash push -p # interactively choose hunks to stash
# Applying
git stash pop # apply most recent + remove from list
git stash apply # apply most recent, keep in list
git stash apply stash@{2} # apply a specific stash
# Managing
git stash list # list all stashes
git stash show -p stash@{0} # show diff of a stash
git stash drop stash@{1} # remove a specific stash
git stash clear # remove all stashes
git stash branch feature/recovered stash@{0} # create branch from stash
Cherry-Picking
git cherry-pick <commit-hash> # apply a single commit
git cherry-pick abc123..def456 # apply a range (exclusive of abc123)
git cherry-pick abc123 def456 ghi789 # apply specific commits
git cherry-pick --no-commit <commit-hash> # apply changes without committing
git cherry-pick -x <commit-hash> # record the source hash in the message
git cherry-pick --continue # after resolving a conflict
git cherry-pick --abort # cancel the cherry-pick
Bisect (Finding Bugs)
git bisect start # begin binary search
git bisect bad # mark current commit as broken
git bisect good v2.1.0 # mark a known-good commit
# Git checks out the midpoint; test it, then:
git bisect good # this commit works
git bisect bad # this commit is broken
git bisect skip # can't test this one, skip it
git bisect reset # done, return to original HEAD
# Automated bisect with a test script
git bisect run ./scripts/test-for-bug.sh
Undoing Changes
# Unstage a file (keep working directory changes)
git restore --staged src/MyClass.cs
# Discard working directory changes (destructive)
git restore src/MyClass.cs
# Revert a commit (creates a new commit that undoes changes)
git revert abc1234 # revert a specific commit
git revert HEAD # revert the last commit
git revert HEAD~3..HEAD # revert a range
git revert --no-commit HEAD~3..HEAD # revert without auto-committing
git revert -m 1 <merge-hash> # revert a merge, keeping the first parent's side
# Rewrite history (only on branches nobody else uses)
git reset --soft HEAD~1 # undo last commit, keep changes staged
git reset HEAD~1 # undo last commit, keep changes unstaged
git reset --hard HEAD~1 # undo last commit and discard its changes
Reflog and Recovery
git reflog # show recent HEAD movements
git reflog show feature/my-branch # reflog for a specific branch
# Recover a lost commit or branch (unreachable entries expire after ~30 days)
git switch -c recovery-branch <hash> # create branch at lost commit
git branch recovery-branch e3a12ec # same, without switching to it
git reset --hard HEAD@{1} # move back to where HEAD was one step ago
Worktrees
git worktree add ../my-app-hotfix hotfix/bug # check out branch in separate directory
git worktree add -b feature/new ../my-app-new main # create new branch in separate directory
git worktree list # see all active worktrees
git worktree remove ../my-app-hotfix # clean up (add --force if it has changes)
git worktree prune # forget worktrees whose folders were deleted
Submodules and Subtrees
# Submodules
git submodule update --init --recursive # initialize after cloning
git submodule update --remote # update to latest upstream
# Subtrees
git subtree add --prefix=libs/shared <url> main --squash
git subtree pull --prefix=libs/shared <url> main --squash
git subtree push --prefix=libs/shared <url> main
Large Repositories
git clone --filter=blob:none <url> # partial clone: file contents on demand
git clone --filter=blob:none --sparse <url> # partial clone + sparse checkout
git sparse-checkout set services/payments libs/shared # only write these directories to disk
git sparse-checkout disable # check out everything again
git clone --depth 1 <url> # shallow clone, for throwaway CI builds
git fetch --unshallow # turn a shallow clone into a full one
Signing Commits and Tags
git config --global gpg.format ssh # sign with an SSH key instead of GPG
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true # sign every commit
git config --global tag.gpgsign true # sign every annotated tag
git commit -S -m "message" # sign one commit explicitly
git log --show-signature -1 # check the signature on the last commit
Git LFS (Large File Storage)
git lfs install # one-time setup
git lfs track "*.psd" # track a file type
git lfs track "assets/large-data/*.csv" # track by path pattern
git add .gitattributes # stage the LFS config
git lfs track # list tracked patterns
git lfs ls-files # list LFS objects in current commit
git lfs pull # fetch content when only pointers were checked out
Git Hooks
mkdir .githooks # create shared hooks directory
cp pre-commit-script.sh .githooks/pre-commit # add your hook
chmod +x .githooks/pre-commit # make it executable
git config core.hooksPath .githooks # point Git at your hooks
git commit --no-verify # skip pre-commit and commit-msg hooks once
Common Multi-Step Workflows
Start a Feature (GitHub Flow)
git switch -c feature/my-feature main
# ... make changes ...
git add src/Feature.cs tests/FeatureTests.cs
git commit -m "implement feature"
git push -u origin feature/my-feature
gh pr create --title "Add my feature" --body "Description here"
Keep a Feature Branch Up to Date
git fetch origin
git rebase origin/main
# resolve conflicts if any, then:
git add <resolved-files>
git rebase --continue
Squash Messy Commits Before Merging
git rebase -i main
# in the editor: mark commits as 'squash' or 'fixup'
# save and edit the combined commit message
git push --force-with-lease # update remote (rewrites history)
Resolve a Merge Conflict
git merge feature/payments # stops with CONFLICT in some files
git status # see which files conflict
# edit each file: keep the right content, delete the <<<<<<< ======= >>>>>>> markers
git add src/PaymentClient.cs # mark each file resolved
git commit # finish the merge
Ship a Hotfix (GitHub Flow)
git switch -c hotfix/fix-bug main
# ... fix the bug ...
git add src/BugFix.cs
git commit -m "fix: null check on payment path"
git push -u origin hotfix/fix-bug
gh pr create --title "Hotfix: payment null check" --body "Fixes #200"
Backport a Fix with Cherry-Pick
git switch release/2.3
git cherry-pick -x <commit-hash-from-main>
git push origin release/2.3
Recover from Committing to the Wrong Branch
# you committed to main by mistake (commit or stash uncommitted work first)
git branch feature/my-work # save commit on a new branch
git reset --hard origin/main # reset main to remote state
git switch feature/my-work # continue on the correct branch
Undo a Pushed Commit Safely
git revert HEAD # create a reverting commit
git push
Recover a Deleted Branch
git reflog | grep 'feature/deleted-branch' # find the last commit hash
git switch -c feature/deleted-branch <hash> # recreate the branch
Split a Commit into Multiple Commits
git rebase -i HEAD~3 # mark the target commit as 'edit'
git reset HEAD^ # undo the commit, keep changes unstaged
git add path/to/first-change.cs
git commit -m "feat: add payment model"
git add path/to/second-change.cs
git commit -m "feat: add payment validation"
git rebase --continue
Stash, Switch, and Return
git stash push -m "WIP: halfway through refactor"
git switch main
# ... do other work, commit, etc. ...
git switch feature/my-work
git stash pop
GitFlow Release Cycle
# Cut release from develop
git switch -c release/2.4.0 develop
# Finish release
git switch main
git merge --no-ff release/2.4.0
git tag -a v2.4.0 -m "Release 2.4.0"
git switch develop
git merge --no-ff release/2.4.0
git branch -d release/2.4.0
Found this useful? Share it:
Share on LinkedIn