Git
Git

Setup & Config

Initialize a new, empty Git repository in the current directory

$git init

Create a new directory and initialize a Git repository within it

$git init <directory>

Initialize a bare repository without a working directory

$git init --bare

Create a new bare repository in the specified directory

$git init --bare <directory>

Initialize a repository with a custom initial branch name

$git init -b <branch-name>

Initialize a repository, explicitly setting the starting branch

$git init --initial-branch=<branch-name>

Clone a remote repository to your local machine

$git clone <url>

Clone a remote repository into a specific target directory

$git clone <url> <directory>

Perform a shallow clone downloading only the latest commits

$git clone --depth 1 <url>

Clone a repository and checkout a specific branch immediately

$git clone --branch <branch> <url>

Clone a repository fetching only the history of the default branch

$git clone --single-branch <url>

Clone fetching history for all branches

$git clone --no-single-branch <url>

Clone a repository and automatically initialize/update its submodules

$git clone --recurse-submodules <url>

Clone a repository as a bare repository without a working tree

$git clone --bare <url>

Create a mirror clone suitable for backup or migrating servers

$git clone --mirror <url>

Clone a repository silently without showing progress output

$git clone --quiet <url>

Clone a repository displaying detailed debug output

$git clone --verbose <url>

Clone and use a custom name instead of 'origin' for the remote

$git clone --origin <name> <url>

Shallow clone only the latest commit of a specific branch

$git clone --depth 1 --branch <branch> <url>

Shallow clone strictly isolated to a single branch

$git clone --depth 1 --single-branch --branch <branch> <url>

List all Git configuration settings applied in the current scope

$git config --list

List global Git configuration settings for the current user

$git config --global --list

List configuration settings specific to the current repository

$git config --local --list

List system-wide Git configuration settings

$git config --system --list

Read the value of a specific Git configuration key

$git config <key>

Read the value of a global Git configuration key

$git config --global <key>

Set a specific configuration key to a value in the local repo

$git config <key> <value>

Set a global Git configuration key to a value

$git config --global <key> <value>

Set the default author name for your commits globally

$git config --global user.name "<name>"

Set the default author email for your commits globally

$git config --global user.email "<email>"

Set the default text editor for Git commands globally

$git config --global core.editor <editor>

Set the default branch name for newly initialized repositories

$git config --global init.defaultBranch <name>

Configure Git to rebase by default when pulling changes

$git config --global pull.rebase true

Set Git to push only the current branch to its remote counterpart

$git config --global push.default current

Create a global shortcut alias for a Git command

$git config --global alias.<alias> <command>

Remove a specific configuration key from the local repository

$git config --unset <key>

Remove a global configuration key

$git config --global --unset <key>

Open the local Git configuration file in the default editor

$git config --edit

Open the global Git configuration file in the default editor

$git config --global --edit

Add a value to a multi-valued configuration key

$git config --add <key> <value>

Get all values assigned to a multi-valued configuration key

$git config --get-all <key>

Clone a local repository path into a new directory

$git clone <file> <directory>

Staging & Snapshots

Stage a specific file's changes for the next commit

$git add <file>

Stage all new and modified files in the current directory

$git add .

Stage all changes, including deletions, across the entire working tree

$git add -A

Stage everything: modifications, new files, and deletions

$git add --all

Interactively stage specific chunks (hunks) of changes

$git add -p

Interactively choose which parts of files to stage

$git add --patch

Stage modifications and deletions, but ignore new untracked files

$git add -u

Update the index just for files that are already tracked

$git add --update

Dry run: show what files would be staged without actually staging them

$git add -n

Simulate adding files to preview changes

$git add --dry-run

Force add a file that is otherwise ignored by .gitignore

$git add -f <file>

Forcefully stage an ignored file

$git add --force <file>

Open the interactive staging prompt menu

$git add -i

Start an interactive session to manage the staging area

$git add --interactive

Open the diff in an editor to manually edit what gets staged

$git add -e

Manually edit the patch file before staging it

$git add --edit

Stage all files matching a specific extension (e.g., .js)

$git add *.js

Stage all modified and new files within a specific directory

$git add <dir>/

Create a commit containing staged changes, opening the editor for a message

$git commit

Create a commit with a single-line message

$git commit -m "<message>"

Automatically stage all modified tracked files and open editor to commit

$git commit -a

Automatically stage modified tracked files and commit with a message

$git commit -am "<message>"

Combine staged changes with the previous commit and edit the message

$git commit --amend

Combine staged changes with previous commit and replace the message

$git commit --amend -m "<message>"

Add staged changes to the previous commit without altering its message

$git commit --amend --no-edit

Create a commit even if there are no staged changes

$git commit -m "<message>" --allow-empty

Commit while bypassing pre-commit and commit-msg hooks

$git commit --no-verify -m "<message>"

Create a GPG-signed commit

$git commit -S -m "<message>"

Force GPG signature for the commit

$git commit --gpg-sign -m "<message>"

Commit with a custom overridden author name and email

$git commit --author="<name> <email>" -m "<message>"

Commit specifying a custom timestamp

$git commit --date="<date>" -m "<message>"

Open editor with the diff of what is being committed visible

$git commit -v

Show the full unified diff in the commit message editor

$git commit --verbose

Commit quietly, suppressing standard summary output

$git commit -q

Commit with minimal output to console

$git commit --quiet

Commit with a subject line and a separate body paragraph

$git commit -m "<message>" -m "<body>"

Create a commit marked to be squashed into a specific older commit

$git commit --squash <commit>

Create a commit meant to invisibly fix an older commit during rebase

$git commit --fixup <commit>

Show the state of the working directory and staging area

$git status

Show status in a concise short format

$git status -s

Display shortened status output

$git status --short

Show current branch tracking info alongside short status

$git status -b

Include branch tracking information in the output

$git status --branch

Show concise short status alongside branch info

$git status -sb

Output machine-readable status meant for parsing by scripts

$git status --porcelain

Show untracked files explicitly in the output

$git status -u

List untracked files and untracked directories contents individually

$git status --untracked-files=all

Show status and also list ignored files

$git status --ignored

Calculate and display how far ahead or behind the remote branch is

$git status --ahead-behind

Show unstaged changes in the working directory

$git diff

Show unstaged changes for a specific file

$git diff <file>

Show changes that are currently staged for the next commit

$git diff --staged

Alias for --staged, showing changes ready to be committed

$git diff --cached

Show all changes (staged and unstaged) since the last commit

$git diff HEAD

Show changes between the working tree and the previous commit

$git diff HEAD~1

Show the differences between two branches

$git diff <branch1> <branch2>

Show the differences between two specific commits

$git diff <commit1> <commit2>

Show a summary of lines added/removed instead of the full diff

$git diff --stat

Output only the names of the files that changed

$git diff --name-only

Output filenames and their modification status (Added, Modified, etc.)

$git diff --name-status

Show differences at the word level instead of line-by-line

$git diff --word-diff

Force colored output for diffs

$git diff --color

Disable colored output for diffs

$git diff --no-color

Generate diffs with <n> lines of context

$git diff -U<n>

Set the number of unified diff context lines

$git diff --unified=<n>

Ignore changes in amount of whitespace

$git diff --ignore-space-change

Completely ignore all whitespace when comparing lines

$git diff -w

Ignore whitespace differences completely

$git diff --ignore-all-space

Filter diffs by file state (e.g., A for added, D for deleted)

$git diff --diff-filter=<filter>

List names of all files changed since the last commit

$git diff HEAD --name-only

Show a summary of the changes staged for the next commit

$git diff --staged --stat

Temporarily save unstaged and staged changes in a stack

$git stash

Explicitly push current changes onto the stash stack

$git stash push

Stash current changes with a specific descriptive message

$git stash push -m "<message>"

Stash tracked file changes along with untracked files

$git stash push -u

Include untracked files when stashing changes

$git stash push --include-untracked

Stash all changes, including untracked and ignored files

$git stash push -a

Stash literally everything in the working directory

$git stash push --all

Interactively select chunks to stash

$git stash push -p

Pick specific hunks of changes to stash interactively

$git stash push --patch

Stash only changes made to a specific file

$git stash push -- <file>

Apply the most recent stash and remove it from the stash stack

$git stash pop

Apply and remove a specific stash index from the stack

$git stash pop stash@{<n>}

Apply the most recent stash without removing it from the stack

$git stash apply

Apply a specific stash without dropping it

$git stash apply stash@{<n>}

Discard the most recent stash from the stack entirely

$git stash drop

Discard a specific stash index permanently

$git stash drop stash@{<n>}

Delete all stashed entries simultaneously

$git stash clear

List all currently saved stashes

$git stash list

Show the summary diff of the most recent stash

$git stash show

Show the summary diff for a specific stash index

$git stash show stash@{<n>}

Show the full patch diff of the most recent stash

$git stash show -p

Show the full patch diff for a specific stash index

$git stash show -p stash@{<n>}

Create a new branch and apply the most recent stash to it

$git stash branch <branch>

Create a new branch and apply a specific stash to it

$git stash branch <branch> stash@{<n>}

Remove a file from the working tree and stage the deletion

$git rm <file>

Recursively remove a directory and stage the deletions

$git rm -r <directory>

Stop tracking a file but keep it in the working directory

$git rm --cached <file>

Stop tracking a directory but leave the files locally

$git rm --cached -r <directory>

Forcefully remove a file from tracking and the working tree

$git rm -f <file>

Force delete a file ignoring local modifications

$git rm --force <file>

Dry run: test file removal without actually deleting it

$git rm -n <file>

Simulate removing a file

$git rm --dry-run <file>

Remove a file quietly without output

$git rm -q <file>

Commit changes bypassing Git hooks

$git commit --no-verify

Branching & Merging

List all local branches

$git branch

Create a new branch at the current commit but stay on current branch

$git branch <name>

List all local and remote-tracking branches

$git branch -a

Display every branch known to the repository locally and remotely

$git branch --all

List only remote-tracking branches

$git branch -r

Display branches fetched from remotes

$git branch --remotes

Safely delete a local branch if it has been merged

$git branch -d <name>

Delete a branch, aborting if unmerged changes exist

$git branch --delete <name>

Forcefully delete a local branch, losing unmerged changes

$git branch -D <name>

Rename the current branch

$git branch -m <new-name>

Rename a specific branch

$git branch -m <old-name> <new-name>

Rename a branch locally

$git branch --move <old-name> <new-name>

Copy the current branch to a new branch name

$git branch -c <new-name>

Duplicate a branch

$git branch --copy <new-name>

List branches along with their latest commit hashes and subjects

$git branch -v

Show more info for each branch in the list

$git branch --verbose

List branches with commit hashes, subjects, and remote tracking status

$git branch -vv

List branches that have been merged into the current branch

$git branch --merged

List branches containing unmerged work

$git branch --no-merged

List only branches that contain a specific commit

$git branch --contains <commit>

Set the upstream tracking branch for the current branch

$git branch -u <upstream>

Link current branch to a remote upstream branch

$git branch --set-upstream-to=<upstream>

Remove the upstream tracking link for the current branch

$git branch --unset-upstream

Forcefully reset an existing branch pointer to a specific commit

$git branch -f <name> <commit>

Explicitly list branches (default behavior of git branch)

$git branch --list

List branches matching a specific glob pattern

$git branch --list "<pattern>"

Switch the working directory to the specified branch

$git checkout <branch>

Create a new branch and immediately switch to it

$git checkout -b <new-branch>

Create a new branch or forcefully reset it if it exists, then switch

$git checkout -B <new-branch>

Create a new branch starting at a specific commit and switch to it

$git checkout -b <new-branch> <start-point>

Create a local branch tracking a remote branch and switch to it

$git checkout --track <remote>/<branch>

Shorthand to checkout and track a remote branch locally

$git checkout -t <remote>/<branch>

Discard unstaged changes to a specific file, restoring from index

$git checkout -- <file>

Discard all local changes to a file, restoring it from HEAD

$git checkout HEAD -- <file>

Restore a specific file to its state in an older commit

$git checkout <commit> -- <file>

Switch back to the previous branch you were on

$git checkout -

Create a new branch with no commit history

$git checkout --orphan <new-branch>

Checkout HEAD directly, leaving branch context (detached HEAD)

$git checkout --detach

Checkout a specific commit, resulting in a detached HEAD

$git checkout <commit>

Checkout a specific tag, resulting in a detached HEAD

$git checkout <tag>

Switch working directory to an existing branch

$git switch <branch>

Create a new branch and switch to it (modern alternative to checkout -b)

$git switch -c <new-branch>

Force create or reset a branch and switch to it

$git switch -C <new-branch>

Create a new branch from a start point and switch

$git switch -c <new-branch> <start-point>

Switch to a new local branch tracking a remote one

$git switch --track <remote>/<branch>

Switch to a commit in detached HEAD mode

$git switch --detach <commit>

Switch to a new, history-less orphan branch

$git switch --orphan <new-branch>

Switch to the previously checked out branch

$git switch -

Guess remote branch to track if local branch doesn't exist

$git switch --guess

Merge the specified branch into the current active branch

$git merge <branch>

Force a merge commit even if a fast-forward is possible

$git merge --no-ff <branch>

Merge only if a fast-forward is possible, otherwise abort

$git merge --ff-only <branch>

Stage the incoming branch's changes as a single commit, without merging history

$git merge --squash <branch>

Cancel an active merge process and restore the pre-merge state

$git merge --abort

Resume the merge process after resolving conflicts

$git merge --continue

Merge a branch and specify the merge commit message

$git merge -m "<message>" <branch>

Use a specific merge strategy (e.g., recursive, octopus)

$git merge --strategy=<strategy> <branch>

Pass strategy-specific options (e.g., -X theirs) during merge

$git merge -X <option> <branch>

Merge a branch that does not share a common ancestor

$git merge --allow-unrelated-histories <branch>

Perform the merge but stop before creating the final commit

$git merge --no-commit <branch>

Show a diffstat at the end of the merge process

$git merge --stat <branch>

Suppress the diffstat output at the end of a merge

$git merge --no-stat <branch>

Populate the merge commit message with shortlogs from merged commits

$git merge --log <branch>

Force a merge commit with a custom message

$git merge --no-ff -m "<message>" <branch>

Reapply current branch's commits on top of another branch

$git rebase <branch>

Open an interactive rebase editor for the last <n> commits

$git rebase -i HEAD~<n>

Start an interactive rebase beginning from a specific commit

$git rebase -i <commit>

Transplant a range of commits from oldbase to newbase

$git rebase --onto <newbase> <oldbase> <branch>

Cancel an in-progress rebase and revert to original state

$git rebase --abort

Resume rebasing after resolving conflicts

$git rebase --continue

Skip the current patch that is causing a conflict during rebase

$git rebase --skip

Automatically squash commits marked with 'fixup!' or 'squash!'

$git rebase --autosquash

Automatically stash and pop uncommitted changes around the rebase

$git rebase --autostash

Execute a shell command after applying each commit during rebase

$git rebase -x <command>

Run a test/command at every step of the rebase

$git rebase --exec <command>

Attempt to preserve merge commits during the rebase process

$git rebase --rebase-merges

Deprecated: Re-create merge commits during rebase

$git rebase --preserve-merges

Interactively rebase and auto-process fixup commits

$git rebase -i --autosquash HEAD~<n>

Rebase the current branch onto a new base excluding old base history

$git rebase --onto <newbase> <oldbase>

Copy a specific commit from another branch to the current branch

$git cherry-pick <commit>

Cherry-pick two specific disconnected commits

$git cherry-pick <commit1> <commit2>

Cherry-pick a continuous range of commits

$git cherry-pick <commit1>..<commit2>

Cherry-pick and append a 'cherry picked from' note to the message

$git cherry-pick -x <commit>

Apply the commit's changes to the working tree without committing

$git cherry-pick -n <commit>

Stage the cherry-picked changes but do not create a commit

$git cherry-pick --no-commit <commit>

Cherry-pick and open an editor to edit the commit message

$git cherry-pick --edit <commit>

Allow editing the commit message before completing cherry-pick

$git cherry-pick -e <commit>

Cancel an in-progress cherry-pick sequence

$git cherry-pick --abort

Resume a cherry-pick sequence after resolving conflicts

$git cherry-pick --continue

Skip the current conflicting commit in a cherry-pick sequence

$git cherry-pick --skip

Add a Signed-off-by trailer to the cherry-picked commit

$git cherry-pick -s <commit>

Sign off on the cherry-picked commit

$git cherry-pick --signoff <commit>

Use a specific merge strategy when cherry-picking

$git cherry-pick --strategy=<strategy> <commit>

Remote

Push local commits to the default tracked remote branch

$git push

Push a specific local branch to a specific remote

$git push <remote> <branch>

Push the local main branch to the origin remote

$git push origin main

Push the current branch to a branch of the same name on origin

$git push origin HEAD

Push and set the remote branch as the default upstream tracking branch

$git push -u <remote> <branch>

Explicitly link local branch to remote upon pushing

$git push --set-upstream <remote> <branch>

Force push changes, potentially overwriting remote history

$git push -f

Forcefully overwrite the remote branch with local history

$git push --force

Force push safely, aborting if remote has unseen changes

$git push --force-with-lease

Force push requiring the remote ref to hold a specific expected value

$git push --force-with-lease=<refname>:<expect>

Push all local branches to the remote

$git push --all

Push commits and automatically push any annotated tags attached to them

$git push --follow-tags

Push changes bypassing the pre-push git hook

$git push --no-verify

Simulate a push to see what would be updated without transferring data

$git push --dry-run

Delete a branch on the remote repository

$git push -d <remote> <branch>

Explicitly delete a remote branch

$git push --delete <remote> <branch>

Push an empty ref to a remote branch, effectively deleting it

$git push <remote> :<branch>

Push a local branch to a remote branch with a different name

$git push <remote> <local-branch>:<remote-branch>

Safely force push main and set upstream tracking

$git push -u origin main --force-with-lease

Delete a specific branch on the origin remote

$git push origin --delete <branch>

Push current branch to origin and link them

$git push -u origin HEAD

Fetch changes from remote and merge them into the current branch

$git pull

Pull from a specific remote and branch

$git pull <remote> <branch>

Fetch changes and rebase local commits on top of the remote changes

$git pull --rebase

Fetch and forcefully create a merge commit instead of rebasing

$git pull --no-rebase

Abort the pull if a fast-forward merge is not possible

$git pull --ff-only

Create a merge commit even if fast-forward is possible

$git pull --no-ff

Fetch and squash remote changes into the working tree without committing

$git pull --squash

Fetch all remotes and merge tracked branch

$git pull --all

Pull changes while limiting the historical depth of the fetch

$git pull --depth <depth>

Automatically stash and pop changes to allow pulling cleanly

$git pull --autostash

Pull and merge changes, but do not auto-commit the result

$git pull --no-commit

Pull changes specifically from the origin main branch

$git pull origin main

Rebase local changes on top of origin's main branch

$git pull --rebase origin main

Download new data from the default remote without merging

$git fetch

Download new data from a specific remote repository

$git fetch <remote>

Download new data from all configured remote repositories

$git fetch --all

Fetch data and remove local refs to remote branches that were deleted

$git fetch --prune

Shorthand for fetching and pruning stale remote-tracking branches

$git fetch -p

Fetch all tags from the remote repository

$git fetch --tags

Fetch branch data without downloading any tags

$git fetch --no-tags

Fetch with a shallow history limit

$git fetch --depth <depth>

Convert a shallow repository to a complete repository by fetching all history

$git fetch --unshallow

Show what would be fetched without actually downloading anything

$git fetch --dry-run

Fetch a specific branch from a remote

$git fetch <remote> <branch>

Fetch from all remotes and clean up deleted branches

$git fetch --all --prune

Download data specifically from the origin remote

$git fetch origin

Download data just for the main branch on origin

$git fetch origin main

List the short names of configured remote repositories

$git remote

List remote repositories along with their fetch and push URLs

$git remote -v

Display detailed remote repository information

$git remote --verbose

Add a new remote repository connection

$git remote add <name> <url>

Add a new remote specifically named 'origin'

$git remote add origin <url>

Delete a remote repository connection

$git remote remove <name>

Shorthand to remove a remote connection

$git remote rm <name>

Rename an existing remote connection

$git remote rename <old> <new>

Show detailed tracking and branch info for a specific remote

$git remote show <name>

Display tracking info for the origin remote

$git remote show origin

Change the URL of an existing remote

$git remote set-url <name> <url>

Update the URL for the origin remote

$git remote set-url origin <url>

Print the current URL of a specific remote

$git remote get-url <name>

Delete stale remote-tracking branches for a specific remote

$git remote prune <name>

Fetch updates from all remotes (similar to fetch --all)

$git remote update

Add a secondary push URL to a remote

$git remote set-url --add <name> <url>

Remove a specific secondary URL from a remote

$git remote set-url --delete <name> <url>

Push a specific local tag to the origin remote

$git push origin <tag>

Delete a specific tag on the remote repository

$git push origin --delete <tag>

Push git notes to the origin remote

$git push origin refs/notes/commits

Fetch git notes from the origin remote

$git fetch origin refs/notes/commits:refs/notes/commits

Inspection & History

Show the commit history for the current branch

$git log

Show commit history condensed to one line per commit

$git log --oneline

Display an ASCII graph of the branch and merge history

$git log --graph

Show the commit history for all branches and refs

$git log --all

Show branch names and tags pointing to commits in the log

$git log --decorate

Show a colorful, condensed, graphical view of all repo history

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

Limit the log output to a specific number of commits

$git log -n <number>

Shorthand to limit the log output to <number> commits

$git log -<number>

Filter the commit log by a specific author's name

$git log --author="<name>"

Show commits more recent than a specific date

$git log --since="<date>"

Show commits older than a specific date

$git log --until="<date>"

Filter commits by a specific keyword in the commit message

$git log --grep="<pattern>"

Show the full patch/diff for each commit in the history

$git log -p

Display the inline diffs introduced by every commit

$git log --patch

Show file additions and deletions statistics for each commit

$git log --stat

Show only the summary line of changes for each commit

$git log --shortstat

List only the names of the files changed in each commit

$git log --name-only

List changed files alongside their modification status (A/M/D)

$git log --name-status

Show the history of a file, tracking past renames

$git log --follow <file>

Show only the commits that modified a specific file

$git log -- <file>

Show only merge commits in the log output

$git log --merges

Exclude all merge commits from the log output

$git log --no-merges

Follow only the first parent of merge commits, simplifying history

$git log --first-parent

Customize the visual output format of the commit log

$git log --pretty=format:"<format>"

Shorthand to set a custom string format for commit logs

$git log --format="<format>"

Show shortened SHA-1 hash strings in the log

$git log --abbrev-commit

Display dates relative to now (e.g., '2 hours ago')

$git log --relative-date

Show the commit history for a specific branch

$git log <branch>

Show commits on branch2 that are not on branch1

$git log <branch1>..<branch2>

Show a condensed graphical history of all branches

$git log --oneline --graph --all

Show the last 10 commits concisely

$git log --oneline -n 10

Show history strictly from the last two weeks

$git log --since="2 weeks ago"

Show the patch diff and message of the most recent commit

$git show

Show the details and diff of a specific commit

$git show <commit>

Show details for the current HEAD commit

$git show HEAD

Show details for the <n>th commit prior to HEAD

$git show HEAD~<n>

Display information about a specific annotated tag

$git show <tag>

Show the latest commit on a specific branch

$git show <branch>

Output the raw contents of a file as it existed in a specific commit

$git show <commit>:<file>

Show only the file statistics for a specific commit

$git show --stat <commit>

List the files altered in a specific commit

$git show --name-only <commit>

Show a condensed summary of a specific commit

$git show --oneline <commit>

Display a commit using a customized text format

$git show --format="<format>" <commit>

Annotate each line of a file with its last modifying commit and author

$git blame <file>

Annotate only a specific line range within a file

$git blame -L <start>,<end> <file>

Annotate starting at a line and extending <n> lines down

$git blame -L <start>,+<n> <file>

Ignore whitespace-only changes when determining line authorship

$git blame -w <file>

Detect lines moved or copied from other files in the same commit

$git blame -C <file>

Detect lines moved or copied within the same file

$git blame -M <file>

Annotate lines modified only after a specific date

$git blame --since=<date> <file>

Ignore a specific formatting commit when assigning blame

$git blame --ignore-rev <commit> <file>

Show the author's email address instead of their username

$git blame -e <file>

Show the original line number instead of the current one

$git blame -n <file>

Show a log of all recent local HEAD movements and operations

$git reflog

Display the standard reference log for HEAD

$git reflog show

Show the reference log specifically for a local branch

$git reflog show <branch>

Explicitly view the HEAD reference log

$git reflog show HEAD

Prune old entries from the reflog

$git reflog expire

Prune reflog entries older than a specified time

$git reflog expire --expire=<time>

Prune old entries across all reference logs

$git reflog expire --all

Delete a specific entry from the reflog

$git reflog delete <ref>

Display the reflog in a concise one-line format

$git reflog --oneline

Group commit subjects by author name

$git shortlog

Provide a clean count of total commits per author

$git shortlog -s

Sort the shortlog output by number of commits instead of alphabetically

$git shortlog -n

Show a ranked tally of commit counts per author

$git shortlog -sn

Include the author's email address in the output

$git shortlog -e

Show emails alongside author names in the summary

$git shortlog --email

Show a sorted tally of commits with author emails included

$git shortlog -sne

Summarize commits made strictly after a specific date

$git shortlog --since=<date>

Summarize authors and commits within a specific revision range

$git shortlog <commit1>..<commit2>

Undoing Changes

Discard unstaged local changes in a file

$git restore <file>

Discard all unstaged changes in the current directory

$git restore .

Unstage a file, keeping the changes in the working directory

$git restore --staged <file>

Unstage all files in the current directory

$git restore --staged .

Restore a file's state to match a specific older commit

$git restore --source=<commit> <file>

Explicitly restore a file in the working tree

$git restore --worktree <file>

Shorthand to pull a file version from a specific commit

$git restore -s <commit> <file>

Unstage all files while preserving their changes in the working directory

$git reset

Remove a specific file from the staging area

$git reset <file>

Unstage a file, keeping local modifications intact

$git reset HEAD <file>

Undo the last commit but keep changes staged and in the working directory

$git reset --soft HEAD~1

Undo the last commit and unstage changes, keeping them in the working tree

$git reset --mixed HEAD~1

Permanently undo the last commit and destroy all local changes

$git reset --hard HEAD~1

Move HEAD to a commit, leaving index and working tree untouched

$git reset --soft <commit>

Move HEAD to a commit and unstage, but preserve working tree

$git reset --mixed <commit>

Force reset HEAD to a commit and forcefully overwrite working tree

$git reset --hard <commit>

Unstage all files currently added to the index

$git reset HEAD

Undo the last <n> commits, leaving changes unstaged

$git reset HEAD~<n>

Destroy all unstaged and staged changes, resetting to the last commit

$git reset --hard HEAD

Reset HEAD but keep local modifications that don't conflict

$git reset --keep <commit>

Reset HEAD and abort a conflicted merge attempt safely

$git reset --merge <commit>

Generate a new commit that applies the inverse of a specific commit

$git revert <commit>

Create a new commit undoing the changes of the last commit

$git revert HEAD

Revert the changes introduced by the <n>th previous commit

$git revert HEAD~<n>

Apply the inverse of a commit to the working tree without committing

$git revert --no-commit <commit>

Stage reverted changes but wait for manual commit

$git revert -n <commit>

Revert a commit and automatically use the default revert message

$git revert --no-edit <commit>

Revert a merge commit by specifying which parent mainline to keep

$git revert --mainline <n> <commit>

Shorthand for reverting a merge commit along a specific parent

$git revert -m <n> <commit>

Revert a continuous sequence of commits

$git revert <commit>..<commit>

Cancel an active revert process and return to the previous state

$git revert --abort

Resume the revert process after resolving file conflicts

$git revert --continue

Forcefully remove all untracked files from the working directory

$git clean -f

Remove all untracked files and untracked directories

$git clean -fd

Remove untracked files, including those ignored by .gitignore

$git clean -fx

Remove only files that are explicitly ignored by .gitignore

$git clean -fX

Nuke working tree: remove all untracked/ignored files and directories

$git clean -fdx

Perform a dry run to see which untracked files would be deleted

$git clean -n

Preview untracked file deletion safely

$git clean --dry-run

Interactively choose which untracked files to delete

$git clean -i

Remove untracked files quietly without console output

$git clean -q

Clean untracked files but explicitly exempt files matching a pattern

$git clean -e <pattern>

Remove untracked files strictly within a specific path/directory

$git clean -f -- <path>

Tags

Push all local tags to the remote repository

$git push --tags

List all tags in the local repository

$git tag

Create a lightweight tag at the current HEAD commit

$git tag <name>

Create a lightweight tag pointing to a specific older commit

$git tag <name> <commit>

Create an annotated tag with a specific message

$git tag -a <name> -m "<message>"

Create an annotated tag at a specific commit

$git tag -a <name> <commit> -m "<message>"

Create a cryptographically GPG-signed annotated tag

$git tag -s <name> -m "<message>"

Delete a specific tag from the local repository

$git tag -d <name>

Explicitly delete a local tag

$git tag --delete <name>

List local tags (same as standard git tag)

$git tag -l

List local tags explicitly

$git tag --list

List tags matching a specific glob wildcard pattern

$git tag -l "<pattern>"

List only the tags that include a specific commit in their history

$git tag --contains <commit>

List tags sorted intelligently by semantic version numbers

$git tag --sort=version:refname

Forcefully overwrite an existing tag to point to a new commit

$git tag -f <name> <commit>

Push all local tags explicitly to the origin remote

$git push origin --tags

Submodules

Add a new external repository as a submodule

$git submodule add <url>

Add a submodule and place it in a specific local path

$git submodule add <url> <path>

Initialize submodules recorded in the index

$git submodule init

Update the registered submodules to match what the superproject expects

$git submodule update

Initialize and update submodules in a single step

$git submodule update --init

Initialize and update submodules, including nested submodules

$git submodule update --init --recursive

Update submodules to the latest commit on their remote tracking branch

$git submodule update --remote

Fetch remote submodule changes and merge them into the local submodule

$git submodule update --remote --merge

Fetch remote submodule changes and rebase local changes on top

$git submodule update --remote --rebase

Show the status, commit hash, and path of all submodules

$git submodule status

Execute a specific shell command inside every submodule

$git submodule foreach <command>

Execute a command inside all submodules and nested submodules

$git submodule foreach --recursive <command>

Unregister a submodule, removing its local configuration

$git submodule deinit <path>

Unregister all submodules from the local repository

$git submodule deinit --all

Synchronize submodule URLs from .gitmodules to the local config

$git submodule sync

Synchronize submodule URLs for all nested submodules

$git submodule sync --recursive

Worktree

Create a new working tree linked to the repo in a separate directory

$git worktree add <path>

Create a new working tree and checkout a specific branch into it

$git worktree add <path> <branch>

Create a new branch and checkout into a new separate working tree

$git worktree add -b <new-branch> <path>

Create a new branch from a commit and open in a new working tree

$git worktree add -b <new-branch> <path> <commit>

Create a new working tree checked out in a detached HEAD state

$git worktree add --detach <path>

List all active worktrees linked to the current repository

$git worktree list

List worktrees in a machine-readable format

$git worktree list --porcelain

Clean up administrative files for deleted or moved worktrees

$git worktree prune

Safely delete a working tree and its associated data

$git worktree remove <path>

Force delete a working tree, ignoring uncommitted changes

$git worktree remove --force <path>

Lock a worktree to prevent it from being automatically pruned

$git worktree lock <path>

Unlock a previously locked worktree

$git worktree unlock <path>

Move an existing working tree to a new directory path

$git worktree move <path> <new-path>

Bisect

Initiate a binary search session to track down a bug

$git bisect start

Mark a specific older commit as 'good' (bug-free)

$git bisect good <commit>

Mark a specific newer commit as 'bad' (containing the bug)

$git bisect bad <commit>

Mark the currently checked-out commit as 'good'

$git bisect good

Mark the currently checked-out commit as 'bad'

$git bisect bad

Skip the current commit if it cannot be tested (e.g., won't compile)

$git bisect skip

End the bisect session and return to the original branch

$git bisect reset

Automate bisecting using a script that returns 0 for good, non-zero for bad

$git bisect run <script>

View the history of good/bad markings in the current bisect session

$git bisect log

Show the remaining suspect commits in a graphical interface or log

$git bisect visualize

Start bisect and immediately provide the known bad and good bounds

$git bisect start <bad> <good>

Sparse Checkout

Enable sparse checkout to only load parts of the repository

$git sparse-checkout init

Enable cone-mode sparse checkout for faster performance with directories

$git sparse-checkout init --cone

Define the exact patterns or directories to include in the working tree

$git sparse-checkout set <pattern>

Add additional directories or patterns to the existing sparse checkout

$git sparse-checkout add <pattern>

List the current patterns determining the sparse checkout

$git sparse-checkout list

Turn off sparse checkout and repopulate the entire working tree

$git sparse-checkout disable

Reapply the sparse checkout rules to the current working tree

$git sparse-checkout reapply

Notes

Attach a textual note to a specific commit without altering its hash

$git notes add -m "<message>" <commit>

View the note attached to a specific commit

$git notes show <commit>

Modify an existing note on a specific commit interactively

$git notes edit <commit>

Delete the note attached to a specific commit

$git notes remove <commit>

List all notes currently existing in the repository

$git notes list

Add new text to an existing note on a commit

$git notes append -m "<message>" <commit>