100+ Git Commands Every Developer MUST Know (2026 Guide)
Master 100+ Git commands every developer needs, from git init to git worktree. The ultimate Git cheat sheet covering version control, branching, and modern Git workflows.

Git is the backbone of modern version control. Every team I’ve worked with, from solo side projects on a cheap VPS to large-scale CI/CD pipelines, runs on Git. This guide covers 100+ Git commands from basics through advanced workflows, updated for 2026 (Git 2.55, with Git 3.0 on the horizon).
Whether you’re learning Git for the first time or looking for a bookmarkable cheat sheet, this article has you covered. I’ve organized the commands so you can jump to any section and find what you need. If you’re setting up a full dev environment, you’ll also want to check out essential Linux commands and Docker commands every developer should know. These pair well with Git for any development workflow. If you use AI coding tools that integrate with Git, the worktree and automation sections will be especially useful.
- Basic Git operations: init, clone, add, commit, config
- Modern branch management with git switch (replaces git checkout)
- git restore for discarding changes safely
- git worktree for parallel branch workflows
- Advanced debugging with git bisect run and git range-diff
- Repository maintenance with git maintenance and git fsck
- CI/CD automation commands and scripting snippets
- Git 3.0 readiness: SHA-256, reftable, and what’s breaking
Section 1: Basic Git Commands
These are the commands you’ll use every day. Master these first.
1.1 git init
Initializes a new Git repository. Creates the .git directory with all the metadata Git needs to track changes.
Example Usage:
mkdir my_project
cd my_project
git init
# Initialized empty Git repository in /path/to/my_project/.git/
Verify: Run git status. You should see “On branch main” (or master, depending on your default branch config) with no commits yet.
1.2 git clone
Creates a local copy of a remote repository.
Example Usage:
git clone https://github.com/user/repository.git
# Cloning into 'repository'...
# remote: Enumerating objects: 10, done.
# remote: Counting objects: 100% (10/10), done.
# remote: Compressing objects: 100% (8/8), done.
# remote: Total 10 (delta 2), reused 10 (delta 2), pack-reused 0
# Unpacking objects: 100% (10/10), done.
Verify: ls -la .git/ should show the repository structure. For extra safety, run git fsck to verify integrity.
For shallow and partial clones (useful on metered VPS or in CI), see Section 3.5.
1.3 git status
Shows the current state of the working directory and staging area.
Example Usage:
git status
# On branch main
# Your branch is up to date with 'origin/main'.
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
# newfile.txt
#
# nothing added to commit but untracked files present (use "git add" to track)
This is the command I run most often. Use it before every commit to make sure you’re staging exactly what you think you are.
1.4 git add
Adds file contents to the staging area for the next commit.
Example Usage:
# Stage a single file
git add newfile.txt
# Stage all changes
git add .
# Stage interactively (pick hunks)
git add -p
git add -p is worth learning early. It lets you stage parts of a file, which leads to cleaner commits.
1.5 git commit
Records staged changes as a new commit.
Example Usage:
git commit -m "Add newfile.txt"
# [main 1a2b3c4] Add newfile.txt
# 1 file changed, 1 insertion(+)
# create mode 100644 newfile.txt
Amend the last commit (before you’ve pushed):
git commit --amend -m "Updated commit message"
1.6 git config
Configures Git settings. In Git 2.46+ (July 2024), there’s a cleaner subcommand-based syntax:
git config set --global user.name "John Doe"
git config set --global user.email "johndoe@example.com"
git config list
git config get user.name
git config unset user.namegit config --global user.name "John Doe"
git config --global user.email "johndoe@example.com"
git config --list
git config --get user.name
git config --unset user.nameGit 2.46 config subcommands
The new git config set/get/list/unset syntax is cleaner and easier to read. The old --global/--get flags still work, Git maintains backward compatibility. But if you’re teaching new developers, use the subcommand form. Git 3.0 will lean further in this direction.
1.7 git grep
Searches tracked files for a pattern. Faster than grep -r because it operates on the Git index.
Example Usage:
# Search for "TODO" in all tracked files
git grep "TODO"
# Search with line numbers
git grep -n "function_name"
# Search in a specific commit
git grep "pattern" HEAD~3
# Case-insensitive search
git grep -i "error"
1.8 git rm
Removes files from the working directory and staging area.
Example Usage:
# Remove a tracked file
git rm oldfile.txt
# Remove from tracking but keep the file on disk
git rm --cached secret.env
The --cached flag is useful when you accidentally committed a file that should be in .gitignore.
1.9 git mv
Moves or renames a tracked file.
Example Usage:
git mv old_name.txt new_name.txt
This is equivalent to mv old_name.txt new_name.txt && git add new_name.txt && git rm old_name.txt, but cleaner.
Section 2: Branching and Merging
Branching lets you work on features, fixes, and experiments in isolation. This section uses the modern git switch as the primary command. If you’re still using git checkout for everything, read the legacy note in 2.3.
2.1 git branch
List, create, and delete branches.
Example Usage:
# List local branches
git branch
# * main
# feature-branch
# List all branches (including remote)
git branch -a
# Create a new branch
git branch new-feature
# Force-delete an unmerged branch
git branch -D experimental
2.2 git switch
The modern way to switch and create branches. Introduced in Git 2.23 (August 2019).
Example Usage:
# Switch to an existing branch
git switch main
# Create and switch to a new branch
git switch -c new-feature
# Switch to the previous branch
git switch -
# Create a branch from a specific commit
git switch -c hotfix abc1234
Why git switch over git checkout
git checkout does two unrelated things: switch branches and restore files. This causes confusion and mistakes. git switch handles branch operations only, making intent clear. Git 3.0 will strongly recommend git switch and git restore over git checkout.
2.3 git checkout (legacy)
Still works, but git switch (branches) and git restore (files) are the recommended replacements since Git 2.23.
# Legacy: switch branch (use git switch instead)
git checkout new-feature
# Legacy: create and switch (use git switch -c instead)
git checkout -b new-feature
# Legacy: restore file (use git restore instead)
git checkout -- file.txt
git checkout conflates two operations
Using git checkout for both branch switching and file restoration is a common source of mistakes. git checkout -- file.txt discards uncommitted changes to a file, while git checkout main switches branch. The same command, completely different outcomes. Use git switch and git restore to make your intent explicit.
2.4 git merge
Combines changes from one branch into the current branch.
Example Usage:
# Merge a branch into current branch
git merge feature-branch
# Merge with an explicit merge commit (even if fast-forward is possible)
git merge --no-ff feature-branch -m "Merge feature-branch"
# Abort a merge with conflicts
git merge --abort
Verify: git log --oneline --graph -10 to see the merge in the commit topology.
Failure mode (merge conflicts): When Git can’t auto-merge, it marks conflicts in the files. Edit the conflicted files, then git add them and git commit. Or git merge --abort to back out completely.
2.5 git rebase
Reapplies commits on top of another base. Creates a linear history (no merge commits).
Example Usage:
# Rebase current branch onto main
git rebase main
# Interactive rebase (squash, reorder, edit commits)
git rebase -i HEAD~5
# Abort a rebase
git rebase --abort
# Continue after resolving conflicts
git rebase --continue
Don't rebase shared branches
Never rebase commits that have been pushed and shared with others. Rebase rewrites commit hashes, which will cause conflicts for anyone else working on those commits. Rebase is safe for local-only branches.
2.6 git worktree
Lets you check out multiple branches simultaneously in separate directories, all linked to the same repository. No need to stash or clone twice.
Example Usage:
# Create a worktree for main at ../hotfix
git worktree add ../hotfix main
# Create a worktree with a new branch
git worktree add -b hotfix-123 ../hotfix-123 main
# List all worktrees
git worktree list
# /home/user/project abc1234 [main]
# /home/user/hotfix def5678 [main]
# Remove a worktree
git worktree remove ../hotfix
# Clean up stale worktree metadata
git worktree prune
Worktrees are underrated
Worktrees let you work on a feature branch while quickly fixing a bug on main, no stashing, no second clone. They’re also useful for AI coding tools that can work on parallel feature branches. Each worktree shares the same .git database, so you avoid the disk cost of a full clone. I use worktrees whenever I need to context-switch between branches.
Failure mode (detached HEAD): Running git switch to a specific commit hash (not a branch name) puts you in detached HEAD state. Your work isn’t on any branch. Fix it with:
git switch -c new-branch-name
This saves your work onto a proper branch.
Section 3: Remote Repository Commands
Working with remote repositories, GitHub, GitLab, Gitea, Forgejo, or any Git server. If you’re pushing over SSH, make sure you have your SSH key setup for GitHub configured first.
3.1 git remote
Manages remote repository connections.
Example Usage:
# List remotes
git remote
# origin
# List remotes with URLs
git remote -v
# origin https://github.com/user/repo.git (fetch)
# origin https://github.com/user/repo.git (push)
# Add a remote
git remote add upstream https://github.com/original/repo.git
# Remove a remote
git remote remove upstream
# Change a remote URL
git remote set-url origin git@github.com:user/repo.git
# Prune stale remote-tracking branches
git remote prune origin
3.2 git fetch
Downloads objects and refs from a remote repository without merging.
Example Usage:
# Fetch from origin
git fetch
# Fetch from a specific remote
git fetch upstream
# Fetch and prune deleted remote branches
git fetch --prune
# Fetch a specific branch
git fetch origin feature-branch
I use git fetch --prune as a habit. It cleans up remote-tracking branches that have been deleted on the server.
3.3 git pull
Fetches and merges changes from a remote branch. Equivalent to git fetch followed by git merge.
Example Usage:
# Pull and merge
git pull
# Pull with rebase instead of merge (cleaner history)
git pull --rebase
# Pull from a specific remote and branch
git pull upstream main
3.4 git push
Uploads local commits to a remote repository.
Example Usage:
# Push current branch to origin
git push
# Push and set upstream tracking
git push -u origin new-feature
# Delete a remote branch
git push --delete origin old-branch
3.5 git push –force-with-lease (safe force push)
Never use --force on shared branches
git push --force overwrites the remote branch unconditionally. If someone pushed commits after your last fetch, those commits are gone. Always use --force-with-lease. It checks that the remote ref hasn’t changed since your last fetch, and aborts if it has.
Example Usage:
# Safe force push (checks remote state first)
git push --force-with-lease origin main
# Even safer (also checks local reflog)
git push --force-with-lease --force-if-includes origin main
--force-with-lease has saved me more than once. It’s the difference between “I rewrote history safely” and “I just destroyed my teammate’s work.”
3.6 Shallow and partial clones
When you’re on a metered VPS, running CI, or working with a huge repo, full clones waste bandwidth and disk. These flags help.
Example Usage:
# Shallow clone - only latest commit (great for CI)
git clone --depth 1 https://github.com/user/large-repo.git
# Partial clone - download blobs on demand (saves disk)
git clone --filter=blob:none https://github.com/user/large-repo.git
# Convert a shallow clone to full history later
git fetch --unshallow
Shallow clones for CI/CD
A --depth 1 clone downloads only the latest commit and tree - no history. This cuts clone time dramatically for large repos. In CI pipelines where you only need the latest code for building/testing, shallow clones are the default for a reason. For VPS deployments, partial clones (--filter=blob:none) are a good middle ground: you get history but download file contents on demand.
Section 4: Viewing History and Comparing Changes
Understanding what happened and when. These commands are your time machine.
4.1 git log
Shows commit history. The default output is verbose - learn the flags that matter.
Example Usage:
# Basic log
git log
# One-line format (my daily driver)
git log --oneline
# Visual branch graph
git log --graph --oneline --all
# Limit output
git log -10
# Show files changed per commit
git log --stat
# Search for commits that introduced/removed a string (pickaxe)
git log -S"buggy_function"
# Trace the history of a specific function
git log -L :function_name:file.c
# Show commits since a date
git log --since="2026-01-01"
# Show commits by author
git log --author="Dragos"
# Cap graph lane width (Git 2.55+)
git log --graph --oneline --all --graph-lane-limit=5
Pickaxe search is powerful
git log -S"string" finds every commit that added or removed that string. It’s like git blame but across the entire history. I use this when tracking down when a bug was introduced. For regex matching, use git log -G"pattern" instead.
4.2 git diff
Shows changes between commits, branches, or the working directory.
Example Usage:
# Changes not yet staged
git diff
# Changes staged for commit
git diff --cached
# Diff between two branches
git diff main..feature-branch
# Summary of changes (files and line counts)
git diff --stat
# Diff for a specific file
git diff HEAD -- file.txt
4.3 git show
Displays details of a specific commit (diff, message, author).
Example Usage:
# Show the latest commit
git show
# Show a specific commit
git show abc1234
# Show only the files changed
git show --stat abc1234
4.4 git blame
Shows who last modified each line of a file and when.
Example Usage:
# Show blame for a file
git blame file.txt
# Blame a specific line range
git blame -L 10,20 file.txt
# Use a different diff algorithm (Git 2.54+)
git blame --diff-algorithm=patience file.txt
4.5 git shortlog
Summarizes git log output by author. Useful for seeing contributor activity.
Example Usage:
# Summary by author
git shortlog -sn
# Summary since a date
git shortlog -sn --since="2026-01-01"
4.6 git describe
Generates a human-readable identifier from the nearest tag.
Example Usage:
git describe --tags
# v1.2.3-14-gabc1234
# (14 commits after tag v1.2.3, commit starting with abc1234)
Use this in build scripts for versioning: the output is always unique and tells you exactly how far you are from the last release.
4.7 git range-diff
Compares two versions of a commit range. The primary use case: verifying a rebase didn’t lose or alter anything.
Example Usage:
# Compare old and new branch versions after rebase
git range-diff origin/main..old-branch origin/main..new-branch
Verify after rebase: Run git range-diff after rebasing to confirm that each commit’s diff is the same (or intentionally different). If commits are missing or their diffs changed unexpectedly, something went wrong.
Section 5: Undoing Changes and Fixing Mistakes
Everyone makes mistakes. These commands are your safety net.
5.1 git reset
Moves HEAD and optionally modifies the staging area and working directory.
Example Usage:
# Soft reset - keep changes staged
git reset --soft HEAD~1
# Mixed reset (default) - keep changes unstaged
git reset HEAD~1
# Hard reset - discard everything since that commit
git reset --hard HEAD~1
git reset --hard is destructive
git reset --hard discards uncommitted changes and moves HEAD. But commits aren’t gone immediately - they’re still in the reflog. If you accidentally hard reset, see the recovery section below.
Recovering from git reset --hard
If you just ran git reset --hard and lost commits, they’re still in the reflog:
# View the reflog (your safety net)
git reflog
# abc1234 HEAD@{0}: reset: moving to HEAD~3
# def5678 HEAD@{1}: commit: Important work here
# Restore to the commit before the reset
git reset --hard HEAD@{1}
# or
git reset --hard def5678The reflog keeps entries for 90 days by default. As long as the garbage collector hasn’t run, you can recover.
5.2 git restore
The modern way to discard working directory changes or unstage files. Replaces git checkout -- <file>.
Example Usage:
# Discard changes to a file (restore to last committed state)
git restore file.txt
# Unstage a file (move it out of the staging area)
git restore --staged file.txt
# Restore a file from a specific commit
git restore --source=HEAD~2 file.txt
# Restore all files in the working directory
git restore .
5.3 git revert
Creates a new commit that undoes a specific commit. Unlike reset, it doesn’t rewrite history.
Example Usage:
# Revert a specific commit
git revert abc1234
# Revert without committing (stage the revert)
git revert --no-commit abc1234
Use git revert on shared branches where you can’t rewrite history. Use git reset on local-only branches.
5.4 git clean
Removes untracked files from the working directory.
Example Usage:
# Dry run - show what would be deleted
git clean -n
# Remove untracked files
git clean -f
# Remove untracked files and directories
git clean -fd
# Include ignored files too
git clean -fdx
Always run with -n first to preview. There’s no undo for git clean.
5.5 git stash
Temporarily shelves changes so you can switch branches or work on something else.
Example Usage:
# Stash current changes
git stash
# Stash with a descriptive message
git stash push -m "WIP: login feature"
# List all stashes
git stash list
# stash@{0}: On main: WIP: login feature
# stash@{1}: On main: experimental changes
# Apply the most recent stash (keep it in the list)
git stash apply
# Apply and remove the most recent stash
git stash pop
# Apply a specific stash
git stash apply stash@{1}
# Create a branch from a stash
git stash branch new-feature-branch stash@{0}
# Delete a specific stash
git stash drop stash@{0}
# Delete all stashes
git stash clear
# Show stash contents
git stash show -p stash@{0}
5.6 git cherry-pick
Applies a specific commit from one branch to the current branch.
Example Usage:
# Cherry-pick a single commit
git cherry-pick abc1234
# Cherry-pick without committing
git cherry-pick --no-commit abc1234
# Cherry-pick a range of commits
git cherry-pick abc1234..def5678
Section 6: Advanced Git Commands
Debugging, automation, and power-user workflows.
6.1 git bisect
Uses binary search to find the commit that introduced a bug.
Manual bisect:
git bisect start
git bisect bad # current commit is broken
git bisect good v1.0 # this tag/commit was working
# Git checks out a middle commit. Test it, then:
git bisect good # this commit works
# or
git bisect bad # this commit is broken
# Git narrows down until it finds the bad commit
# When done:
git bisect reset
Automated bisect with a script:
git bisect start HEAD v1.0
git bisect run ./test-script.sh
The test script should exit 0 for “good” and non-zero for “bad.” Git will automatically check out commits and run the script until it finds the first bad commit. This is the real power of bisect - let the computer do the work.
git bisect run saves hours
Write a test script that reproduces the bug, make it executable, and hand it to git bisect run. It will binary-search through hundreds of commits in minutes. I’ve used this to track down regressions across months of commit history.
6.2 git tag
Creates named references to specific commits (typically for releases).
Example Usage:
# Lightweight tag
git tag v1.0.0
# Annotated tag (recommended - includes metadata)
git tag -a v1.0.0 -m "Release 1.0.0"
# Tag a specific commit
git tag -a v1.0.0 abc1234
# List tags
git tag
# List tags with messages
git tag -n
# Push tags to remote
git push origin v1.0.0
# Push all tags
git push origin --tags
6.3 git submodule
Manages external repositories embedded in your repository.
Example Usage:
# Add a submodule
git submodule add https://github.com/user/library.git libs/library
# Initialize submodules after cloning
git submodule init
git submodule update
# Or combine both
git submodule update --init --recursive
# Update submodules to latest remote commits
git submodule update --remote
6.4 git archive
Creates a tar or zip archive of a repository at a specific point.
Example Usage:
# Create a tar archive of HEAD
git archive --format=tar HEAD > project.tar
# Create a zip of a specific tag
git archive --format=zip v1.0.0 > project-v1.0.0.zip
# Archive specific paths only
git archive --format=tar HEAD src/ > src-only.tar
6.5 git reflog
Shows a log of where HEAD has been. Your safety net for recovery operations.
Example Usage:
# View reflog
git reflog
# abc1234 HEAD@{0}: commit: Latest change
# def5678 HEAD@{1}: reset: moving to HEAD~1
# ghi9012 HEAD@{2}: commit: Important work
# Reset to a reflog entry
git reset --hard HEAD@{2}
6.6 git notes
Attaches metadata to commits without rewriting history. Think of it as comments on commits.
Example Usage:
# Add a note to a commit
git notes add -m "Reviewed-by: Jane" abc1234
# View notes for a commit
git notes show abc1234
# List all notes
git notes list
# Push notes to remote (not pushed by default)
git push origin refs/notes/commits
Use cases: attaching CI results, code review metadata, or test coverage info to specific commits.
6.7 git commit –fixup and –autosquash
Clean up commit history before merging.
Example Usage:
# Create a fixup commit targeting a specific commit
git commit --fixup=abc1234
# Interactive rebase that automatically squashes fixup commits
git rebase -i --autosquash main
This is my preferred workflow for pull requests: make fixup commits as reviewers request changes, then squash them into the right places before merging.
6.8 git bundle
Creates a portable archive of a repository that can be cloned. Useful for air-gapped environments, offline transfers, or backups.
Example Usage:
# Create a bundle of all branches
git bundle create repo.bundle --all
# Create a bundle of specific branches
git bundle create repo.bundle main feature-branch
# Clone from a bundle
git clone repo.bundle new-repo
# Verify a bundle is valid
git bundle verify repo.bundle
6.9 git am
Applies patches from a mailbox (email-based workflows). Still used by the Linux kernel and other projects that rely on email-based code review.
Example Usage:
# Apply a patch file
git am < patch-file.patch
# Apply a series of patches from a directory
git am patches/*.patch
# Abort if something goes wrong
git am --abort
# Apply with 3-way merge (resolves more cases)
git am --3way < patch-file.patch
Section 7: Collaboration and Patch Workflows
Working with patches, email submissions, and code review.
7.1 git cherry
Finds commits that haven’t been applied upstream.
Example Usage:
# Show commits in the current branch not in upstream
git cherry upstream/main
# Verbose output with commit messages
git cherry -v upstream/main
7.2 git apply
Applies a patch created by git diff or git format-patch.
Example Usage:
# Verify a patch without applying
git apply --check changes.patch
# Apply a patch
git apply changes.patch
# Apply with reverse (undo a patch)
git apply -R changes.patch
Always run git apply --check first to verify the patch applies cleanly.
7.3 git format-patch
Creates patch files from commits. Each commit becomes a separate .patch file with the commit message.
Example Usage:
# Create patches for the last 3 commits
git format-patch -3
# Create patches for a range
git format-patch main..feature-branch
# Create patches in a directory
git format-patch -3 -o patches/
7.4 git send-email
Sends patch files via email. Used in projects that do email-based code review (Linux kernel, Git itself).
Example Usage:
# Send a patch series
git send-email patches/*.patch
# Send to a specific recipient
git send-email --to=maintainer@example.com patches/*.patch
7.5 git request-pull
Generates a pull request message for email-based workflows.
Example Usage:
git request-pull v1.0 https://github.com/user/repo.git main
Section 8: Repository Maintenance and Performance
Keep your repositories fast and healthy. Especially important if you’re hosting repos on a VPS with limited disk and I/O.
8.1 git gc
Garbage collection - cleans up unnecessary files and optimizes the repository.
Example Usage:
# Standard garbage collection
git gc
# Aggressive (slower but more thorough - use occasionally)
git gc --aggressive
# Auto-gc with higher thresholds (less frequent packing)
git gc --auto
Verify: Run git log -1 after gc to confirm the repo still works.
git gc --aggressive can be slow
--aggressive rewrites pack files for better compression. On large repos, this can take minutes to hours. Use it occasionally, not as a daily task. For routine maintenance, plain git gc or git maintenance is better.
8.2 git fsck
Verifies the integrity of the repository database.
Example Usage:
# Check for corrupt objects
git fsck
# Check and report dangling objects
git fsck --dangling
Run git fsck after a suspicious clone or when you suspect corruption. If it reports errors, re-clone from a known good source.
8.3 git maintenance
Schedules background tasks to keep repositories fast. Introduced in Git 2.30.
Example Usage:
# Enable background maintenance (schedules via cron/systemd)
git maintenance start
# Run maintenance tasks manually
git maintenance run
# Disable background maintenance
git maintenance stop
# Run a specific task
git maintenance run --task=commit-graph
git maintenance avoids auto-packing pauses
Without git maintenance, Git runs gc --auto during certain operations (push, merge, etc.), which can pause for seconds or minutes on large repos. With git maintenance start, background tasks run on a schedule so those operations stay fast. Since Git 2.54, geometric repacking is the default strategy - better performance for most repos.
8.4 git rerere
“Reuse recorded resolution” - remembers how you resolved a conflict and applies the same resolution automatically next time.
Example Usage:
# Enable rerere
git config set rerere.enabled true
# Once enabled, Git automatically records conflict resolutions
# and re-applies them during rebases or merges
If you rebase frequently or maintain long-lived branches, rerere saves significant time.
8.5 git count-objects
Shows disk usage of the Git object database.
Example Usage:
# Basic count
git count-objects
# Human-readable with verbose details
git count-objects -vH
# count: 0
# size: 0 bytes
# in-pack: 1523
# packs: 1
# size-pack: 2.34 MiB
# garbage: 0
# size-garbage: 0 bytes
Useful for monitoring repo size on VPS instances with limited disk.
8.6 git prune
Removes unreachable objects from the database. Normally handled by git gc, but useful for manual cleanup.
Example Usage:
# Dry run
git prune -n
# Prune unreachable objects
git prune
Section 9: Scripting and Automation Commands
Commands you’ll use in CI/CD pipelines, build scripts, and automation. If you’re writing deployment scripts or integrating Git into your CI pipeline, these are essential.
9.1 git rev-parse
Parses revision specifications. The go-to for extracting info in shell scripts.
Example Usage:
# Get full commit hash
git rev-parse HEAD
# a1b2c3d4e5f6...
# Get short hash
git rev-parse --short HEAD
# a1b2c3d
# Get current branch name
git rev-parse --abbrev-ref HEAD
# main
# Get the repository root directory
git rev-parse --show-toplevel
# /home/user/project
9.2 git rev-list
Lists commit objects in reverse chronological order.
Example Usage:
# Count total commits
git rev-list --count HEAD
# Count commits since a date
git rev-list --since="2026-01-01" --count HEAD
# List commits between two refs
git rev-list main..feature-branch
9.3 git ls-files / git ls-tree / git cat-file
Low-level inspection commands.
# List files in the index (staging area)
git ls-files
# List tree contents at a commit
git ls-tree HEAD
# Show object type and content
git cat-file -t HEAD # "commit"
git cat-file -p HEAD # commit details
# Show blob content
git cat-file -p HEAD:file.txt
9.4 CI/CD snippets
Copy-pasteable CI/CD Git snippets
# Get changed files in the last commit (for selective CI jobs)
git diff --name-only HEAD~1
# Generate version string from tags
git describe --tags --always
# List commits between deploys (for release notes)
git log --oneline <previous-deploy-ref>..<new-deploy-ref>
# Create a deploy artifact
git archive --format=tar HEAD | gzip > deploy.tar.gz
# Get the commit count since last tag (for build numbers)
git rev-list $(git describe --tags --abbrev=0)..HEAD --count
# Fast CI clone
git clone --depth 1 --branch main https://github.com/user/repo.git
# Verify repo integrity in CI
git fsck --no-danglingSection 10: Modern Git: Switch, Restore, Worktrees, and Beyond
This section consolidates the modern Git features that have matured since 2019. If you’re still running Git workflows like it’s 2015, start here.
10.1 git sparse-checkout
Work with a subset of a large repository. Essential for monorepos.
Example Usage:
# Clone with sparse checkout
git clone --filter=blob:none --sparse https://github.com/large/repo.git
cd repo
# Set which directories you want
git sparse-checkout set src/frontend docs/
# Add more directories later
git sparse-checkout add src/shared/
# List current sparse-checkout paths
git sparse-checkout list
# Disable sparse-checkout (get everything)
git sparse-checkout disable
Combined with partial clone (--filter=blob:none), you only download the files you need. Great for monorepos where you only work on one service.
10.2 SSH commit signing
GPG signing has been the traditional way to sign commits, but SSH-based signing is much simpler to set up and is supported by GitHub, GitLab, and Gitea.
# Configure Git to use SSH signing
git config set gpg.format ssh
# Set your signing key (your public SSH key)
git config set user.signingkey ~/.ssh/id_ed25519.pub
# Sign a commit
git commit -S -m "Signed commit"
# Sign all commits by default
git config set commit.gpgsign true
# Register your SSH key as a signing key on GitHub/GitLab
# GitHub: Settings → SSH and GPG keys → New SSH key (select "Signing key")# Generate a GPG key
gpg --full-generate-key
# Configure Git to use the GPG key
git config set user.signingkey YOUR_GPG_KEY_ID
# Sign a commit
git commit -S -m "Signed commit"
# Export public key for GitHub/GitLab
gpg --armor --export YOUR_GPG_KEY_IDSSH signing is simpler: you already have the keys, no key management beyond what you use for push/pull, and no GPG agent to configure. If you’re starting fresh, use SSH.
10.3 git history command (Git 2.54+)
New in Git 2.54, the git history command simplifies interactive rebase workflows.
# Reword a commit message (replaces interactive rebase for simple edits)
git history reword HEAD~3
# Split a commit into multiple commits
git history split HEAD~2
# Create a fixup commit and prepare for autosquash
git history fixup HEAD~5
git history is experimental
The git history command is still experimental as of Git 2.55. It works, but the interface may change. If you need stable behavior, use git rebase -i for now. But keep an eye on this - it’s where Git is heading.
10.4 Config-based hooks (Git 2.54+)
Hooks can now be configured via git config instead of placing scripts in .git/hooks/. This makes hooks easier to share across a team.
# Set a hook via config
git config set core.hooksPath .githooks
Place your hook scripts in .githooks/ and commit that directory. Everyone who clones the repo gets the hooks automatically.
10.5 git stash export/import
Transfer stashes between repositories or machines.
# Export stash to a file
git stash export > stash.bundle
# Import in another repo
git stash import < stash.bundle
Zsh plugins for Git productivity
Shell plugins and aliases can speed up your Git workflow significantly. If you use Zsh, check out Zsh plugins for Git productivity for tab completion, prompt integration, and shortcut aliases.
Section 11: Git 3.0 - What’s Coming
Git 3.0 is targeting late 2026. Here’s what you need to know to prepare.
11.1 SHA-256 default hash algorithm
Git has used SHA-1 since its creation, but SHA-1 has known collision attacks (the SHAttered attack in 2017 made this practical). Git 3.0 will make SHA-256 the default for new repositories.
What changes:
- Hash length goes from 40 hex characters to 64 hex characters
- New repos created with Git 2.51+ already default to SHA-256
- Existing SHA-1 repos continue to work (no forced migration)
The catch: GitHub, GitLab, and other forges don’t yet support SHA-256 repositories. The ecosystem needs to catch up before SHA-256 becomes practical for most teams.
11.2 Reftable reference backend
Reftable is a new format for storing Git references (branches, tags). It’s available today:
# Create a repo with reftable backend
git init --ref-format=reftable
Why it matters:
- Up to 22x faster fetch and 18x faster push in repos with 10,000+ references
- Atomic reference updates (no more partial writes on crash)
- No more filesystem-level branch name conflicts (case-insensitive filesystems)
- Smaller disk footprint for reference storage
For repos with many branches (monorepos, large teams), reftable is a significant improvement. If you’re self-hosting Git with Forgejo, check its reftable support status.
11.3 Rust build requirement
Git 3.0 will require Rust as a build dependency. This enables memory-safe implementations of performance-critical code paths. The Meson build system integration continues.
Impact: Most users won’t notice - they install Git from package managers. But building Git from source on platforms without Rust toolchains will require an extra step.
11.4 Breaking changes
git-whatchangedremoved. Usegit log --rawinstead (same output, more flags).git switchandgit restoreno longer experimental. Git 3.0 will strongly recommend them overgit checkout. Start migrating now.- Various deprecated options removed. Check
BreakingChanges.txtin the Git source for the full list.
Verify the Git 3.0 timeline
The late 2026 target is aspirational. Check git-scm.com for the latest status before relying on any Git 3.0 features in production.
Git 3.0 readiness checklist
- Switch to
git switchandgit restore- stop usinggit checkoutfor branch/file operations - Use the new
git config set/get/listsyntax - the old flags still work but the new form is cleaner - Test
git init --ref-format=reftableon a non-production repo to see if it works for your workflow - Update CI scripts to handle SHA-256 hashes (64 chars vs 40) if they parse commit hashes
- Monitor your forge (GitHub, GitLab, Gitea) for SHA-256 repo support announcements
- Keep Git updated - security fixes and features land in every release
Section 12: Security Essentials
Git security matters for every team. These commands and configs help protect your repository.
12.1 Verifying objects on fetch/push
Catches corrupted or malicious objects during transfer.
# Enable object verification for all fetches/pushes
git config set transfer.fsckObjects true
With this enabled, Git verifies the integrity of every object received from a remote. Enable it globally or per-repository.
12.2 Commit and tag verification
Verify that commits and tags are signed by trusted keys.
# Verify a commit's signature
git verify-commit abc1234
# Verify a tag's signature
git verify-tag v1.0.0
12.3 Keeping Git updated
Recent security vulnerabilities you should be aware of:
Update Git immediately if you're on an old version
CVE-2025-48384 (July 2025): Arbitrary file write on Linux/macOS via git clone. This is in the CISA KEV catalog - actively exploited. CVE-2024-50349 and CVE-2024-52006 (October 2024): Credential handling issues affecting all prior versions. Always upgrade to the latest stable Git release.
# Check your Git version
git --version
# Update on Ubuntu/Debian
sudo apt update && sudo apt install git
# Update on macOS
brew upgrade git
# Update on Fedora/RHEL
sudo dnf update git
Section 13: Quick Reference Table
Bookmark this section. Every command listed here works in Git 2.50+. Commands marked with ★ are especially worth learning.
| Category | Command | What It Does |
|---|---|---|
| File operations | git rm <file> |
Remove a tracked file |
git rm --cached <file> |
Untrack a file (keep on disk) | |
git mv <old> <new> |
Rename/move a tracked file | |
git grep <pattern> |
Search tracked files | |
| Staging | git add -p |
Stage changes interactively (hunks) |
git diff --cached |
Show staged changes | |
git restore --staged <file> |
Unstage a file | |
| Commit | git commit --amend |
Edit the last commit |
git commit --fixup=<hash> |
Create a fixup commit ★ | |
git rebase -i --autosquash |
Auto-squash fixup commits ★ | |
| Branching | git branch -D <branch> |
Force-delete an unmerged branch |
git switch - |
Switch to previous branch ★ | |
git worktree add <path> <branch> |
Check out branch in new directory ★ | |
git worktree list |
List all worktrees | |
git worktree remove <path> |
Remove a worktree | |
| Remotes | git remote prune origin |
Clean up stale remote-tracking refs |
git fetch --prune |
Fetch and prune ★ | |
git push --delete origin <branch> |
Delete a remote branch | |
git push --force-with-lease |
Safe force push ★ | |
| History | git log --oneline --graph --all |
Visual branch map ★ |
git log -S"string" |
Find commits that changed a string ★ | |
git log --follow <file> |
Follow file renames | |
git log -L :func:file |
Trace function history | |
git describe --tags |
Human-readable version string ★ | |
git range-diff <old> <new> |
Verify rebase correctness ★ | |
git shortlog -sn |
Commits per author | |
git blame -L 10,20 <file> |
Who changed lines 10–20 | |
| Undo | git stash push -m "msg" |
Stash with a message |
git stash pop |
Apply and remove stash ★ | |
git stash branch <name> |
Create branch from stash | |
git stash show -p |
Show stash diff | |
git revert --no-commit <hash> |
Revert without committing | |
git clean -fd |
Remove untracked files + dirs | |
git merge --abort |
Abort a merge | |
git rebase --abort |
Abort a rebase | |
| Security | git verify-commit <hash> |
Verify commit signature |
git verify-tag <tag> |
Verify tag signature | |
git config set transfer.fsckObjects true |
Verify objects on transfer ★ | |
| Maintenance | git gc |
Garbage collect |
git gc --aggressive |
Thorough repack (slow) | |
git fsck |
Verify repo integrity ★ | |
git count-objects -vH |
Disk usage summary | |
git maintenance start |
Enable background maintenance ★ | |
| Low-level | git rev-parse HEAD |
Get current commit hash |
git rev-parse --abbrev-ref HEAD |
Get current branch name | |
git rev-list --count HEAD |
Count commits | |
git ls-files |
List files in index | |
git ls-tree HEAD |
List tree at commit | |
git cat-file -p <hash> |
Show object content | |
git hash-object <file> |
Compute blob hash | |
git update-index |
Register file in index | |
| Networking | git daemon |
Simple Git server |
git update-server-info |
Update info for dumb HTTP servers | |
git bundle create <file> |
Pack repo into portable file ★ | |
git clone <bundle> |
Clone from a bundle | |
| Diff/merge tools | git difftool |
Open diff in external tool |
git mergetool |
Open merge tool for conflicts | |
| Patches | git am < patch |
Apply mailbox patch |
git format-patch -N |
Create patches from last N commits | |
git send-email |
Send patches via email | |
| Inspection | git instaweb |
Browse repo in local gitweb |
git notes add -m "text" |
Attach metadata to commit | |
git interpret-trailers |
Parse/add commit trailers | |
git rerere |
Reuse recorded resolutions ★ |
That’s 100+ commands covering every workflow from basic operations to advanced automation.
Conclusion
Git is one of those tools where knowing 15 commands well gets you through 90% of your day, but knowing 100+ gives you options when things go sideways or when you need to automate something.
- git init / clone / status / add / commit - the daily workflow
- git switch / restore - stop using git checkout for everything
- git log –oneline –graph –all - always know where you are
- git stash - context-switch without losing work
- git rebase -i - clean up before merging
- git reflog - your safety net when things go wrong
- git push –force-with-lease - the only safe way to force push
- git bisect run - automate bug hunting
- git worktree - work on multiple branches at once
- git maintenance start - keep repos fast automatically
If you’re building out your development environment, these companion guides are worth bookmarking:
- Essential Linux commands - command line fundamentals
- Docker commands - container management
- GitHub Copilot for writing Git commands - AI-assisted workflow


