Home/Tools/Git Command Reference

Git Command Reference

Git Command Reference

Practical, task-driven Git recipes that help you ship with confidence. Search by scenario, filter by skill level, and copy ready-to-run commands without leaving your terminal.

Task-focused recipes
Ready-to-run command sequences for daily Git workflows.
Undo without panic
Clear guidance on reverting commits or restoring files safely.
Branching best practices
Know when to merge, rebase, cherry-pick, or squash.
Searchable knowledge base
Filter by topic or skill level to jump straight to the answer.
⌘K

Showing 50 of 50 command guides

Initialize or Clone a Repository

Start fresh with `git init` or copy an existing project with `git clone`, then confirm remotes before making changes.

Setup & BasicsBeginner

Create a brand-new repository in this folder

git init

Initializes the .git directory so Git can track history. Use it only once per project directory.

Clone an existing repository

git clone https://example.com/org/project.git

Copies the full history and sets up the default `origin` remote. Replace the URL with your repository.

Verify remote configuration

git remote -v

Shows the fetch/push URLs tied to each remote so you can confirm you are pushing to the right place.

Use this when

  • You are starting a new project locally and want Git to begin tracking files.
  • You need a local working copy of an existing shared repository.

Pro tips

  • Avoid running `git init` inside a directory that is already within another repository; nested repos are rarely intentional.
  • After cloning, run `git status` to ensure you are on the expected default branch.

Common pitfalls

  • Cloning large repos can take time—consider a shallow clone (`git clone --depth 1`) for CI or experimentation.
Related

Stage and Unstage Changes Precisely

Understand the staging area so you can curate commits and undo `git add` without losing work.

Setup & BasicsBeginner

Inspect what changed

git status --short

Shows staged (`A`/`M`) and unstaged changes side by side so you know exactly what will commit.

Stage hunks interactively

git add -p

Walks through each change hunk so you can include only the lines that belong in the next commit.

Unstage a file without discarding edits

Path to unstage
git reset HEAD src/app.ts

Removes src/app.ts from the index but keeps the working copy intact, reversing an accidental `git add`.

Alternatives

Unstage with the modern syntax

Path to unstage
git restore --staged src/app.ts

Equivalent to `git reset` for un-staging src/app.ts, but often easier to remember with newer Git versions.

Stop tracking a file but keep it locally

Path to stop tracking
git rm --cached src/app.ts

Removes src/app.ts from Git while leaving it on disk—useful for large artifacts or newly ignored files.

Use this when

  • You staged changes too aggressively and need to back them out before committing.
  • You want to build small, focused commits and must select only part of a file.

Pro tips

  • Run `git diff --staged` before committing to review exactly what you are about to record.
  • Pair `git add -p` with `git commit --amend` to refine commits without creating new ones.

Common pitfalls

  • `git reset` without a path touches the entire index—remember to specify the file you intend to unstage.
Related

Manage Git Credential Helpers

Configure how Git stores and reuses credentials for HTTPS remotes.

Setup & BasicsBeginner

Use the built-in credential store (OS specific)

git config --global credential.helper osxkeychain # or wincred/libsecret

Leverages the operating system’s secure storage so you do not re-enter passwords every push.

Cache credentials temporarily

git config --global credential.helper "cache --timeout=3600"

Keeps credentials in memory for an hour—useful on shared machines where permanent storage is risky.

Clear saved credentials for one remote

git credential reject <<EOF
protocol=https
host=github.com

EOF

Forces Git to prompt next time. Replace host/protocol as needed.

Use this when

  • You are repeatedly prompted for HTTPS credentials.
  • You need to rotate tokens or switch authentication methods.

Pro tips

  • Prefer SSH keys when possible; credential helpers are most helpful for legacy HTTPS workflows.
  • Set helper configs at the repo level when different projects require different credential strategies.

Common pitfalls

  • Storing credentials in plain text (e.g., helper=store) is risky on shared systems.
  • Remember to update or remove cached credentials when tokens expire to avoid authentication loops.
Related

Configure Git Identity per Machine or Repository

Set user name/email globally or per project so commits are attributed correctly.

Setup & BasicsBeginner

Set global identity

User name
Email address
git config --global user.name "Taylor (Work)"
git config --global user.email "[email protected]"

Applies to every repository on this machine unless overridden locally.

Set repo-specific identity

User name
Email address
git config user.name "Taylor (Work)"
git config user.email "[email protected]"

Overrides the global identity for the current repository only.

List effective configuration values

git config --show-origin --get-regexp "^user"

Shows where values were defined (system, global, local).

Use this when

  • You contribute to open source with one email and company projects with another.
  • You need to audit where an incorrect identity is coming from.

Pro tips

  • Use conditional includes in `~/.gitconfig` to set identities based on directory (`[includeIf "gitdir:~/work/"]`).
  • Verify identity before committing with `git config user.name` inside the repo.

Common pitfalls

  • Global configs apply to all repos; forgetting to override them can leak personal information into corporate repos (and vice versa).
Related

Create a New Commit

Stage the exact changes you want and record them with a clear, imperative commit message.

CommitsBeginner

Review what changed

git status -sb

Shows tracked, untracked, and staged files with a concise summary before you commit.

Stage specific files (repeat per file)

File or folder to stage
git add src/components/Button.tsx

Stage only src/components/Button.tsx (repeat per path) so this commit stays focused. Use `git add -p` to review hunks interactively.

Commit staged changes

Commit message
git commit -m "Explain what this change does"

Write subject lines like "Explain what this change does": imperative mood, < 72 characters. Add body text with `-m` again or your editor if needed.

Use this when

  • You have grouped related changes that should live together in the history.
  • Tests or checks for the staged files have passed locally.

Pro tips

  • Use `git add -p` for an interactive staging review.
  • Include issue or ticket references in the body, not the subject line.
Related

Amend the Most Recent Commit

Update the previous commit when you forgot a file or need to adjust the message.

CommitsIntermediate

Stage the fix

Path to add
git add src/missing-file.ts

Stage src/missing-file.ts (or any other files) so they join the last commit.

Amend commit with new content/message

git commit --amend

Opens your editor with the previous message prefilled so you can update it.

Use this when

  • The prior commit is not yet pushed to a shared branch.
  • You need to tweak the commit message or include a small fix.

Pro tips

  • Run `git commit --amend --no-edit` if only the content changed and the message is still accurate.

Common pitfalls

  • Avoid amending commits that teammates may already have pulled; it rewrites history.
Related

Revert a Commit Safely

Create a new commit that undoes the changes introduced by an earlier commit without rewriting history.

Fix MistakesIntermediate

Revert a single commit

git revert <commit-sha>

Runs the inverse of the target commit and creates a new revert commit. Great for public branches.

Revert a merge commit

git revert -m 1 <merge-commit-sha>

Use `-m` with the parent number the merge should keep (usually 1 for the main branch).

Use this when

  • You already pushed the problematic commit to a shared branch.
  • You want a transparent fix without rewriting history.

Pro tips

  • If the revert conflicts, resolve them manually, `git add` the files, and `git revert --continue`.

Common pitfalls

  • A revert keeps the original commit in history; use `git reset` if you truly want to drop it and it is safe to rewrite.
Related

Restore a Single File

Throw away changes in one file or unstage it without touching the rest of your work.

Fix MistakesBeginner

Discard local edits and match HEAD

Path to restore
git restore src/app.ts

Replaces the working tree version with the version from the current branch head.

Unstage a file but keep edits

Path to unstage
git restore --staged src/app.ts

Removes the file from the index so it will not be committed, leaving worktree changes intact.

Alternatives

Older syntax (Git < 2.23)

Path to restore
git checkout -- src/app.ts

Legacy command; `git restore` is clearer but this remains widely used.

Use this when

  • You changed the wrong file and want it back to the last commit.
  • You staged a file but decided it should not go in the next commit.

Common pitfalls

  • Restoring discards work permanently. Stash first if you might need the changes later.
Related

Squash Multiple Commits

Combine a series of commits into one clean commit before merging or sharing.

Fix MistakesAdvanced

Interactive rebase N commits

Commits to include3
git rebase -i HEAD~3

Opens the last 3 commits in your editor. Change `pick` to `squash` or `fixup` for commits you want to combine.

Finish the rebase

git rebase --continue

After resolving conflicts (if any), continue until the rebase completes.

Alternatives

Quick squash into previous commit

git reset --soft HEAD~2 && git commit -m "Combined change"

Moves HEAD back and keeps changes staged so you can recommit as one snapshot.

Use this when

  • You have work-in-progress commits that should be a single logical change.
  • You are preparing a branch for review and want a tidy history.

Pro tips

  • Interactive rebase preserves individual commit messages, letting you merge them thoughtfully.

Common pitfalls

  • Only squash commits that are not yet shared or that teammates expect to be rewritten.
Related

Squash Commits in the Middle of History

Use interactive rebase starting at the parent of the series you want to collapse, then continue the replay.

Fix MistakesAdvanced

Start the rebase from the commit before the block

git rebase -i <base-commit>^

Replace `<base-commit>` with the commit that precedes the runs you want to squash. Using `^` opens the todo list starting at the first commit you intend to keep separate.

Mark commits to squash

# In the todo list change lines to
pick 1234567 First commit to keep
squash 89abcde Middle commit
squash fedcba9 Final commit to collapse

Change `pick` to `squash` (or `fixup`) for every commit you want folded into the previous one. Leave later commits as `pick` so they replay normally.

Rewrite messages and finish the rebase

git rebase --continue

After resolving conflicts (if any), edit the combined commit message and continue replaying the remainder of history.

Use this when

  • You have a noisy series of commits in the middle of the branch that should become a single commit.
  • You want to clean up history before merging a long-running feature branch.

Pro tips

  • Use `git log --oneline --graph` to identify the SHA just before the block you want to squash.
  • If you accidentally squash too much, abort with `git rebase --abort` and start again with the correct base commit.

Common pitfalls

  • Interactive rebase rewrites commit SHAs; coordinate with teammates before squashing shared history.
  • Conflicts can occur on every squashed commit—resolve them and run `git rebase --continue` each time.
Related

Interactive Rebase Cookbook

Reorder, split, or drop commits in one rebase session to tidy a feature branch before sharing.

Fix MistakesAdvanced

Launch interactive rebase for the last N commits

Commits to include5
git rebase -i HEAD~5

Opens an editor where you can reorder commits and choose actions (pick, reword, edit, squash, fixup, drop) for the last 5 commits.

Edit a commit in the middle of history

git rebase -i HEAD~5 # mark commit as edit
git commit --amend
git rebase --continue

Pause on the selected commit, amend it, then continue replaying the rest of the branch.

Split a large commit into smaller ones

git rebase -i HEAD~5 # mark commit as edit
git reset HEAD^
# create new commits
git add <subset> && git commit -m "Part 1"
# repeat for remaining changes
git commit -am "Part 2"
git rebase --continue

Reset the commit and create new commits for each logical chunk before continuing the rebase.

Drop an unwanted commit

# In the todo list change `pick` to `drop` (or delete the line)

Removes the commit entirely. Only safe on branches that are not yet shared.

Use this when

  • You want to polish a branch before requesting review or merging.
  • You need to split or reorder commits to make history easier to understand.

Pro tips

  • Enable autosquash (`git config rebase.autosquash true`) so fixup! commits are placed automatically.
  • If the rebase becomes messy, run `git rebase --abort` to return to the original branch state.

Common pitfalls

  • Interactive rebases rewrite commit SHAs—coordinate with teammates before rewriting shared branches.
Related

Create a Feature Branch

Branch off from the current commit to isolate new work.

Branching & MergingBeginner

Create and switch

git checkout -b feature/awesome-change

Creates the branch and moves your HEAD to it in one step.

Use this when

  • Starting new work without affecting the main branch.
  • Keeping experimental changes isolated.

Pro tips

  • Base your branch on an up-to-date `main` to reduce merge conflicts later.
Related

Switch Between Branches

Change your working tree to match another branch or commit.

Branching & MergingBeginner

Switch with the modern command

git switch main

Changes the working tree to match `main`. Use `git switch -c` to create a new branch.

Alternatives

Older syntax

git checkout main

Still widely used; both commands are equivalent for branch switching.

Use this when

  • You finished a task and need to return to the trunk branch.
  • You are reviewing work on a teammate’s branch.

Common pitfalls

  • Git refuses to switch if you have uncommitted changes that would be overwritten—commit, stash, or restore first.
Related

Merge a Branch

Bring the work from another branch into your current branch using a merge commit.

Branching & MergingIntermediate

Update your base branch first

git fetch origin && git checkout main && git pull --ff-only

Make sure your base branch has the latest remote commits before merging.

Merge the feature branch

git merge --no-ff feature/awesome-change

Creates a merge commit so the feature branch history stays visible.

Use this when

  • You want to keep the full branch history and context.
  • The branch has already been reviewed or tested and is ready to integrate.

Common pitfalls

  • Resolve conflicts carefully and run tests before finalizing the merge.
  • The `--no-ff` flag creates an extra commit even if a fast-forward is possible—omit it if you prefer a linear history.
Related

Guard Merges Before Committing

Stage a merge result for review or testing before finalizing the merge commit.

Branching & MergingIntermediate

Merge without committing immediately

git merge --no-commit --no-ff feature/branch

Applies the merge but leaves the index/working tree staged so you can inspect or test before committing.

Abort the guarded merge if not ready

git merge --abort

Restores the pre-merge state if tests fail or the merge is not desired.

Commit after validation

git commit

Finalizes the merge once you are satisfied with the staged result.

Use this when

  • You want CI or manual QA to run before recording the merge commit.
  • You need to make last-minute adjustments or add documentation inside the merge commit.

Pro tips

  • Combine with `git diff --cached` to review exactly what will land in the merge commit.
  • Consider `--signoff` when committing to note who performed the guarded merge.

Common pitfalls

  • Do not forget to commit—leaving a merge in progress blocks other operations.
Related

Apply Specific Files from Another Branch

Copy changes from a commit or branch without performing a full merge or cherry-pick.

Branching & MergingIntermediate

Restore a file from another branch

Source branch or commit
Path to restore
git restore --source feature/login -- src/app/Login.tsx

Copies the file from the source branch into your working tree and stages it for commit.

Restore a directory or set of files

Source branch or commit
Path to restore
git restore --source abc1234 -- src/components

Pulls specific paths from a commit (given by SHA) without touching other files.

Classic syntax for older Git

Source branch or commit
Path to restore
git checkout feature/login -- src/app/Login.tsx

Same effect using legacy syntax—still handy when working on older Git versions.

Use this when

  • You only need a subset of files from another branch (e.g., hotfix code).
  • You want to preview changes locally before deciding whether to cherry-pick or merge fully.

Pro tips

  • Follow selective restores with tests and a normal commit (`git commit -m "Import login fix"`).
  • Combine with `git diff --staged` to review exactly what was imported before committing.

Common pitfalls

  • Selective restores do not bring over history—document where the change originated in your commit message.
  • Be mindful of dependencies; importing one file may require related changes you did not copy.
Related

Rebase a Branch

Replay your branch commits on top of a newer base to keep a linear history.

Branching & MergingAdvanced

Update local tracking branch

git fetch origin main

Fetch the latest commits so you have an up-to-date rebase target.

Rebase your branch

git rebase origin/main

Applies your commits onto the latest `origin/main`. Resolve conflicts and continue with `git rebase --continue`.

Use this when

  • You have not yet shared your branch and want a clean history.
  • You prefer to avoid merge commits in long-running feature branches.

Pro tips

  • If rebasing a shared branch, coordinate with teammates to avoid duplicate commits.

Common pitfalls

  • Rebasing rewrites commit IDs. Avoid it on branches others already pulled unless everyone is aligned.
Related

Pull with Rebase

Fetch remote changes and replay local commits on top to avoid merge commits.

CollaborationIntermediate

Configure rebase-by-default

git config --global pull.rebase true

Optional: makes `git pull` default to rebasing instead of merging.

Pull with rebase this time only

git pull --rebase origin main

Fetches and rebases in one command. Resolve conflicts and continue with `git rebase --continue` if needed.

Use this when

  • You want to keep your feature branch linear after fetching upstream work.
  • You are catching up with `main` before opening a pull request.

Common pitfalls

  • If the rebase fails, you can abort with `git rebase --abort` and try again after fixing issues.
Related

Sync with Remotes Without Surprises

Fetch first, clean stale references, then choose how to integrate updates before pushing your own commits.

CollaborationBeginner

Fetch new commits without changing your worktree

git fetch origin

Downloads remote updates into your local tracking branches so you can inspect them before integrating.

Prune deleted remote branches

git fetch origin --prune

Removes local references to remote branches that no longer exist, keeping `git branch -r` tidy.

Integrate and update the upstream branch

git pull --rebase origin main

Fetches and rebases in one step to avoid merge commits. Swap `--rebase` for `--ff-only` if you prefer merges.

Alternatives

Quickly push local commits

git push

Uploads your branch to the remote. Configure tracking (`git push -u origin feature`) the first time.

Rewrite remote history safely

git push --force-with-lease

Force-pushes only if the remote still points to the commit you expect, protecting teammates from clobbered work.

Use this when

  • Before opening a pull request, you want to ensure your branch includes the latest upstream changes.
  • Your remote branch list is cluttered with references to branches that no longer exist.

Pro tips

  • Set `git config pull.rebase true` if your team standardizes on rebasing to keep histories linear.
  • Review incoming work with `git log origin/main..HEAD` before pushing to catch conflicts early.

Common pitfalls

  • `git pull` defaults to a merge; configure your default or always pass `--rebase`/`--ff-only` to avoid unexpected merge commits.
Related

Manage Remote URLs and Upstreams

Add, inspect, and retarget remotes so pushes go to the correct locations.

CollaborationBeginner

List configured remotes

git remote -v

Shows each remote’s fetch and push URL—use this to verify where work is going.

Add a new remote

git remote add upstream https://example.com/org/project.git

Adds a remote pointing to another repository (commonly `upstream` for forks).

Update an existing remote URL

git remote set-url origin [email protected]:org/project.git

Changes the remote endpoint—handy when switching from HTTPS to SSH or migrating hosting providers.

Alternatives

Remove an obsolete remote

git remote remove old-origin

Deletes the remote reference so it no longer appears in `git remote -v`.

Use this when

  • You forked a repository and need to sync with the upstream source.
  • Your organization moved repositories and the push URL changed.

Pro tips

  • Use descriptive remote names when collaborating with multiple upstreams (e.g., `github`, `gitlab`).
  • Combine with `git fetch --all` to pull the latest refs after adding or retargeting remotes.

Common pitfalls

  • Changing a remote URL does not migrate existing clones—make sure teammates update their remotes too.
  • Accidentally pushing to the wrong remote can leak work; always verify with `git remote -v` after changes.
Related

Reconcile Diverged Local and Remote Commits

Your branch has unique commits locally and remotely. Fetch, replay your work, and push the resolved history.

CollaborationIntermediate

Fetch remote updates

git fetch origin

Downloads the latest commits without changing your working tree so you can rebase against an up-to-date target.

Replay your commits on the remote branch

git rebase origin/main

Replace `main` with your branch name. Resolve conflicts, then `git add` the files and run `git rebase --continue` until the rebase finishes.

Push updated history

git push

After a successful rebase the remote is behind your rewritten commits, so a normal push fast-forwards it. Use `--force-with-lease` only if teammates may have based work on your branch.

Alternatives

One-step rebase and fetch

git pull --rebase origin main

Combines fetch + rebase. Resolve conflicts then continue as prompted.

Merge instead of rebase

git merge origin/main

If your team avoids history rewrites, merge will create a commit that keeps both histories.

Use this when

  • Git reports “your branch and origin/main have diverged” or shows commits on both sides.
  • You committed locally while new commits landed on the remote branch you track.

Pro tips

  • During rebase, run `git status` to see which files still need conflict resolution.
  • If the rebase goes sideways, use `git rebase --abort` to restore the state before you started.

Common pitfalls

  • Do not force-push until you are certain the rewritten history is correct.
  • Switching between rebase and merge strategies mid-flow can create duplicate commits—pick one approach per branch sync.
Related

Inspect History Quickly

Use a compact log format to understand recent commits and where they came from.

History & InspectionBeginner

Graph view with one-line commits

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

Shows branches, tags, and commit messages in a single concise view.

Use this when

  • You want to visualize branching history or find where a change came from.
  • You are checking what commits exist before merging or rebasing.

Pro tips

  • Add an alias: `git config --global alias.lg "log --oneline --graph --decorate --all"`.
Related

Find Who Last Touched a Line

Identify the commit and author responsible for a specific line in a file.

History & InspectionIntermediate

Blame a file

Path to inspect
git blame app/models/user.rb

Outputs the commit, author, and timestamp for each line in app/models/user.rb.

Use this when

  • You need context for why code looks the way it does.
  • You are preparing to revert or modify a specific line and want to review the original change.

Common pitfalls

  • Whitespace-only changes add noise—use `git blame -w` to ignore whitespace.
Related

Search History for Introduced Changes

Trace when a line or string changed by combining blame, log, and regex searches.

History & InspectionIntermediate

Blame a specific line range

Path to inspect
git blame -L 42,+1 -- src/app.ts

Shows the commit and author responsible for the given line range in src/app.ts.

Trace history forward in time

Path to trace
git blame --reverse -- src/app.ts

Highlights commits that introduced or removed lines in src/app.ts—useful during large refactors.

Search history for a string change

Path to search
git log -S"deprecatedFunction" -- src/app.ts

Lists commits where the exact string was added or removed in src/app.ts, narrowing down regressions.

Use this when

  • You need to identify who introduced a regression or requirement.
  • You are preparing a large refactor and want to understand historical context.

Pro tips

  • Use `git log -G"regex"` for regex-based history searches when strings vary.
  • Add `--follow` to `git log` and `git blame` when files were renamed.

Common pitfalls

  • History across renames can be fragmented without `--follow`; remember to include it for moved files.
Related

Create and Share Tags

Use lightweight or annotated tags to mark releases and important commits.

History & InspectionBeginner

Create an annotated tag

git tag -a v1.2.0 -m "Release v1.2.0"

Annotated tags store metadata (author, date, message) and are best for releases.

List local tags

git tag --list

Displays all tags in the repository so you can confirm versions.

Tag a specific commit (not HEAD)

git tag -a v1.2.0 <commit-sha>

Creates an annotated tag pointing to the given commit—useful when you are tagging a release retroactively.

Push a tag to the remote

git push origin v1.2.0

Publishes the tag to collaborators. Use `git push --tags` to send all local tags.

Alternatives

Create a lightweight tag

git tag v1.2.0

Creates a simple pointer without metadata—useful for local bookmarks.

Move a tag to a new commit

git tag -f v1.2.0 <new-commit>

Retargets the tag locally; follow with `git push --force origin v1.2.0` to update the remote copy.

Use this when

  • You are preparing a release build and want to mark the exact commit.
  • You need human-friendly references when debugging customer environments.

Pro tips

  • Use annotated tags for anything shared, and reserve lightweight tags for temporary local markers.
  • Push tags explicitly—`git push` without arguments does not send newly created tags.

Common pitfalls

  • Force-updating public tags can confuse consumers; prefer creating a new tag when the release changes.
Related

Release Tagging Pipeline

Cut a release by syncing main, recording an annotated tag, and pushing code plus notes in one flow.

History & InspectionIntermediate

Ensure main is up to date

git checkout main
git pull --ff-only origin main

Start from the latest main branch to avoid releasing stale code.

Create an annotated, signed tag

git tag -a v2.3.0 -m "Release v2.3.0" && git tag -v v2.3.0 # optional verification

Annotated (and optionally signed) tags capture release metadata and can be verified later.

Push code and the tag

git push origin main
git push origin v2.3.0

Publishes the release commit and tag. Use `git push --tags` if pushing multiple tags.

Generate release notes from history

git log v2.2.0..v2.3.0 --oneline --no-merges

Summarize the changes since the prior tag for changelog or release notes.

Use this when

  • You need a reliable, repeatable process for publishing production releases.
  • You want traceability between deployed artifacts and Git history.

Pro tips

  • Automate the push + changelog steps in scripts so cutovers are consistent.
  • Include build IDs or CI artifact links in the tag message for faster triage.

Common pitfalls

  • Never retag a release—create a new tag (e.g., v2.3.1) if you must re-issue a build.
Related

Generate Human-Friendly Versions with git describe

Produce semantic-looking identifiers based on the nearest tag and commit distance.

History & InspectionIntermediate

Describe current commit

git describe --tags

Prints the nearest tag plus the number of commits and abbreviated SHA (e.g., v1.2.0-5-gabc1234).

Include lightweight tags as fallback

git describe --tags --match "v*"

Restricts matches to tags starting with v (or any glob) when multiple tagging schemes exist.

Describe other commits (e.g., HEAD^)

git describe --tags HEAD^

Generates an identifier for a specific commit, useful in CI pipelines.

Use this when

  • You want deterministic build numbers derived from Git history.
  • You are diagnosing which commit a deployed binary was built from.

Pro tips

  • Add `--dirty` to append a marker when the working tree has uncommitted changes.
  • Combine with `git rev-parse` in scripts to fall back to raw SHAs if no tags exist.

Common pitfalls

  • `git describe` relies on reachable tags—ensure release tags are pushed to the remote.
Related

Export Snapshots Without Sharing History

Create tarballs or single-file bundles when you need to distribute code without the full repository.

History & InspectionIntermediate

Create a tar archive of HEAD

git archive --format=tar --output=release.tar HEAD

Generates a tarball of the current tree—great for handing off to build systems or clients.

Archive a specific path only

git archive --format=zip --output=frontend.zip HEAD apps/web

Exports just the given directory from the repo, leaving the rest out of the package.

Bundle commits for offline transfer

git bundle create hotfix.bundle main feature/hotfix-123

Packages the necessary commits so another machine can fetch them without network access.

Use this when

  • You need to provide source code to a third party without exposing full history.
  • You are moving commits between environments with restricted network access.

Pro tips

  • Consumers can extract bundles with `git clone hotfix.bundle` or `git fetch hotfix.bundle main`.
  • Pair archives with version identifiers from `git describe` or tags for traceability.

Common pitfalls

  • Archives omit submodules by default; export them separately if required.
  • Bundles only include the referenced refs—remember to include all dependent branches when creating one.
Related

Choose the Right History Rewrite Strategy

Decide between revert, reset, or rebase based on whether commits are public and what you need to undo.

Fix MistakesIntermediate

Public history: create a revert

git revert <commit>

Adds a new commit that undoes the target without rewriting history—safe for shared branches.

Private history: rewrite with reset

Commits to move1
git reset --mixed HEAD~1

Moves HEAD back and keeps changes in the working tree so you can restage or split commits before pushing.

Polish feature branch with rebase

git rebase -i origin/main

Interactive rebase cleans up local commits before you share them. Use only when collaborators are not using the branch.

Use this when

  • You need to decide whether to use revert, reset, or rebase when undoing a mistake.
  • You want a quick reference that maps public vs private history to the safe command.

Pro tips

  • Use revert on main/prod branches so collaborators never lose history.
  • If multiple commits are bad, prefer `git revert <old>^..<new>` to revert a range in one command.

Common pitfalls

  • Reset and rebase rewrite commit IDs—coordinate with teammates or expect to force push.
  • Revert cannot operate on uncommitted changes; stash or commit before running it.
Related

Cleanup History with git filter-repo

Remove secrets or large files from history using the modern filter-repo tool.

History & InspectionAdvanced

Remove a file from entire history

git filter-repo --path secrets.txt --invert-paths

Strips `secrets.txt` from every commit. Run in a fresh clone and force push when finished.

Purge files over a certain size

git filter-repo --strip-blobs-bigger-than 10M

Deletes blobs larger than 10 MB anywhere in history—helpful when repos grow unexpectedly.

Rewrite email/author information

git filter-repo --mailmap my-mailmap.txt

Applies a mailmap to fix historical author/committer details.

Use this when

  • Credentials or large binaries were committed and must be removed from history.
  • You need to rewrite author information en masse.

Pro tips

  • Run filter-repo in a clean clone; treat results as a new repository history and communicate force pushes clearly.
  • After rewriting, archive the old repo or protect it from garbage collection until everyone updates.

Common pitfalls

  • Rewrites require force pushes and break existing clones—ensure everyone reclones or runs `git fetch --all` carefully.
  • Filter-repo is not installed by default; provide installation steps for teammates (pipx or homebrew).
Related

Pack and Prune Repositories Safely

Run garbage collection and repack objects to reduce repo size after large history rewrites or deletions.

Scaling & PerformanceIntermediate

Run garbage collection with aggressive pruning

git gc --prune=now --aggressive

Cleans up unreachable objects immediately—run after filter-repo or massive branch deletions.

Repack objects into a single packfile

git repack -Ad

Rewrites packfiles, removing duplicates and shrinking repo size on disk.

Expire reflogs to free space first

git reflog expire --expire=now --all

Drops reflog entries so gc can reclaim objects that would otherwise be retained.

Use this when

  • After running git filter-repo or removing large blobs you want to reclaim disk space.
  • Automating maintenance for monorepos that grow quickly.

Pro tips

  • Run maintenance in off-hours—aggressive gc can be CPU intensive on large repos.
  • Coordinate with teammates before pruning shared repos so no one relies on recently removed references.

Common pitfalls

  • Never run `git gc` inside a repository currently in use by another Git process.
  • Pruned objects cannot be recovered; ensure backups exist if you might need the old history.
Related

Post-Incident Checklist After Secret Removal

Rotate credentials and notify stakeholders after removing secrets from Git history.

Fix MistakesIntermediate

Rotate credentials immediately

# Example: rotate via cloud CLI
aws iam update-access-key --access-key-id <old> --status Inactive

Replace exposed tokens/keys in upstream systems to prevent unauthorized use.

Invalidate build caches or artifacts

gh workflow run purge-cache.yml --ref main # example

Ensure CI/CD caches or images that contained the secret are purged or rebuilt.

Force collaborators to resync history

git push --force origin main
# Communicate: everyone must run
git fetch --all && git reset --hard origin/main

After rewriting history, make sure every clone updates to the new canonical history.

Use this when

  • Immediately after running filter-repo or other secret removal steps.
  • As part of an incident response process when credentials leak.

Pro tips

  • Document which systems received rotated keys and confirm downstream applications were updated.
  • Attach a retro note via `git notes` summarizing the incident for future audits.

Common pitfalls

  • Skipping token rotation can leave services vulnerable even if the secret no longer exists in Git history.
  • Force pushes without communication can strand teammates—coordinate across channels.
Related

Sign Commits and Attach Post-Hoc Notes

Add cryptographic signatures to commits and append explanatory notes without rewriting history.

History & InspectionAdvanced

Create a signed commit

git commit -S -m "Secure commit"

Uses your configured GPG or SSH signing key to add a signature to the commit.

Verify commit signatures

git log --show-signature -1

Displays signature status so reviewers can confirm authenticity.

Add or edit a commit note

git notes add -m "Deployment checklist" <commit>

Attaches additional metadata to a commit without modifying the commit itself.

Use this when

  • You are in a compliance-conscious environment requiring signed commits.
  • You need to annotate a commit after the fact with deployment details or review notes.

Pro tips

  • Configure `user.signingkey` and `gpg.format` once, then set `commit.gpgSign true` to sign by default.
  • Share notes by pushing the `refs/notes/*` namespace (`git push origin refs/notes/*`).

Common pitfalls

  • Ensure all collaborators import and trust your signing key; otherwise signatures appear as “unverified”.
  • Notes are not fetched by default—document how to retrieve them (`git fetch origin refs/notes/*:refs/notes/*`).
Related

Bisect to Find a Bug

Binary search the commit history to isolate the change that introduced a regression.

History & InspectionAdvanced

Start the bisect session

git bisect start

Begins a binary search session.

Mark the current commit as bad

git bisect bad

Tells Git the current revision contains the bug.

Mark a known good commit

git bisect good <commit-sha>

Provide a commit where the bug did not exist. Git will then checkout the midpoint.

Automate the test at each step

git bisect run ./scripts/test-regression.sh

Runs the script at every step; bisect marks commits good/bad depending on the exit code (0 = good).

Use this when

  • A regression appeared and you need to identify the offending commit quickly.

Pro tips

  • Use lightweight scripts that exit 0/1 to keep automated bisect runs fast.
  • After finishing, run `git bisect reset` to return to your starting branch.

Common pitfalls

  • Forgetting to reset after the search leaves your repo checked out at the last tested commit.
Related

Stash Your Changes

Park uncommitted work on a stack so you can switch contexts without committing.

Workspace & StashBeginner

Stash tracked changes

git stash push -m "WIP: refactor dashboard"

Saves staged and unstaged tracked files. The message helps recall the stash later.

Alternatives

Include untracked files

git stash push -u -m "WIP: spike new UI"

Adds untracked files to the stash—helpful when you created new files.

Use this when

  • You need to change branches quickly but are not ready to commit.
  • You want to pause work before pulling in remote changes.

Common pitfalls

  • Stashes live locally only—do not rely on them for long-term storage.
Related

Work with Multiple Checkouts Using Worktrees

Maintain additional working directories that share the same repository data so you can work on several branches simultaneously.

Workspace & StashIntermediate

List existing worktrees

git worktree list

Shows every attached worktree, their paths, and which commit/branch each path checks out.

Create a new worktree for a branch

git worktree add ../feature-login feature/login

Creates a sibling directory at `../feature-login` and checks out the `feature/login` branch there. Use `-b new-branch` to create a branch at the same time.

Remove a worktree when finished

git worktree remove ../feature-login

Detaches the worktree and deletes that working directory once it is clean. Run `git worktree prune` to clean up stale metadata.

Alternatives

Create and checkout in one command

git worktree add -b hotfix/payment ../hotfix-payment origin/main

Creates `hotfix/payment` from `origin/main` in a dedicated directory while keeping your current working tree untouched.

Use this when

  • You need to hotfix or review another branch without stashing or committing ongoing work.
  • Running tests or builds in parallel across different branches demands separate working directories.

Pro tips

  • Keep worktrees outside your main repository folder (for example `../worktrees/branch`) to avoid nested Git repos.
  • Run `git worktree prune` periodically to remove entries for directories that no longer exist.

Common pitfalls

  • Each worktree has its own working directory; remember to install dependencies or virtualenvs per worktree as needed.
  • A branch can only be checked out by one worktree at a time—detach it before trying to checkout elsewhere.
Related

Manage Git Submodules

Track external repositories inside your project and keep them in sync without breaking downstream clones.

Workspace & StashAdvanced

Add a submodule

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

Registers the external repo and records its commit pointer in `.gitmodules` and the index. Commit those changes after verifying the checkout.

Initialize and update all submodules

git submodule update --init --recursive

Clones missing submodules and checks out the recorded commit for each module, including nested modules.

Pull upstream changes in submodules

git submodule update --remote --merge

Fetches latest changes for each submodule, checks out the configured branch, and merges the remote updates so you can review them.

Alternatives

Check submodule status

git submodule status

Shows the currently checked out commit for each submodule and flags when the working tree is dirty or out of sync.

Remove a submodule safely

git submodule deinit libs/lib && git rm libs/lib && rm -rf .git/modules/libs/lib

Detaches the module, removes the tracked entry, and deletes its metadata directory. Commit the resulting changes.

Use this when

  • You need to vendor another repository while keeping its history intact.
  • Your build depends on specific commits from upstream projects that update at a different cadence.

Pro tips

  • Always commit the updated submodule SHA after running `git submodule update --remote` so collaborators get the same revision.
  • Lock submodules to stable branches in `.gitmodules` (`branch = main`) to control update behaviour.

Common pitfalls

  • Forgetting to run `git submodule update --init` after cloning leaves modules empty—document this step in your project README or setup scripts.
  • Submodules add complexity to CI/CD pipelines; ensure your build scripts include `--recursive` clones or explicit submodule updates.
  • Submodules cannot share the same branch across multiple worktrees—detach them before using `git worktree`.
Related

Keep Submodules Happy with Worktrees

Detach submodule branches before creating worktrees and reattach them when finished to avoid checkout errors.

Workspace & StashAdvanced

Detach submodule branches

git submodule foreach --recursive "git checkout --detach"

Ensures each submodule is in a detached state so the branch can be checked out in only one worktree.

Create a new worktree for the feature branch

git worktree add ../feature-worktree feature/payment-refactor

Adds another working directory for the branch while submodules remain detached.

Reattach submodule branches after removing worktrees

git submodule foreach --recursive "git checkout main"

Once extra worktrees are removed, return submodules to their tracking branches.

Use this when

  • You run into “already checked out” errors when combining submodules and worktrees.
  • Multiple worktrees need to use the same submodule branch without conflicts.

Pro tips

  • Automate the detach/reattach cycle with scripts so no one forgets the steps.
  • Run `git submodule update --init --recursive` inside each worktree before working on submodules.

Common pitfalls

  • Forgetting to reattach branches leaves submodules detached, which can confuse teammates.
  • Do not edit submodules simultaneously in multiple worktrees unless you coordinate updates.
Related

Restore Stashed Work

Re-apply stashed changes when you are ready to continue the work.

Workspace & StashBeginner

List stashes with details

git stash list

Shows stash entries with their index and messages.

Apply a stash and keep it on the stack

git stash apply stash@{0}

Applies the newest stash (index 0) or any other by number.

Alternatives

Apply and drop in one step

git stash pop

Applies the latest stash and removes it. Use only if you are confident you no longer need the stash.

Use this when

  • You paused work with `git stash` and are ready to resume.

Common pitfalls

  • Conflicts can happen when applying a stash after the base branch has moved—resolve them and stage the fixes.
Related

Soft Reset to Combine Commits

Move HEAD backwards but keep all changes staged so you can recommit them.

Fix MistakesAdvanced

Move HEAD back two commits

Commits to move2
git reset --soft HEAD~2

Leaves all changes staged so you can create a new commit immediately.

Use this when

  • You want to recombine recent commits without losing work.
  • You need to change the order or content of the last few commits before sharing.

Common pitfalls

  • Only safe if the affected commits have not been pushed or if collaborators expect a rewrite.
Related

Mixed Reset to Rework Commits

Move HEAD back while keeping changes in the working tree so you can restage exactly what belongs.

Fix MistakesIntermediate

Reset the last commit but keep files edited

Commits to move1
git reset HEAD~1

Default (mixed) mode: moves HEAD back one commit and unstages those changes, leaving them as modifications.

Reset a specific file from staging

Path to unstage
git reset HEAD src/app.ts

Removes src/app.ts from the index but preserves working tree edits so you can recommit selectively.

Use this when

  • You need to rewrite the previous commit but want to restage just part of the changes.
  • You want to split a large commit into smaller ones without losing work.

Pro tips

  • Follow a mixed reset with `git status` to review exactly what changed states.
  • Pair with `git add -p` to build clean commits from the unstaged changes.

Common pitfalls

  • Resetting multiple commits (`HEAD~3`) can create a large pile of unstaged changes—work in smaller batches when possible.
Related

Hard Reset to Drop Work

Reset both HEAD and your working tree to a previous commit, discarding current changes entirely.

Fix MistakesAdvanced

Danger: reset everything to origin/main

git fetch origin && git reset --hard origin/main

Aligns your branch with the remote exactly. Any local changes are lost.

Use this when

  • You want to throw away local work and start fresh from a known good commit.

Common pitfalls

  • This is destructive. Ensure nothing important is uncommitted before running it.
Related

Clean Untracked Files Safely

Inspect and remove build artifacts or temporary files that Git is not tracking.

Workspace & StashIntermediate

Preview what would be removed

git clean -nd

Lists untracked files and directories that `git clean` would delete, without removing them.

Remove untracked files

git clean -f

Deletes untracked files (not directories). Always preview first so you know what will disappear.

Remove untracked directories too

git clean -fd

Deletes untracked files and directories—useful for wiping build artifacts or vendor folders.

Alternatives

Interactive cleaning

git clean -i

Step through each untracked path and decide interactively whether to remove it.

Use this when

  • Your working tree is cluttered with build outputs or generated files that are not tracked.
  • A previous branch left behind temporary directories that interfere with new work.

Pro tips

  • Combine with `.gitignore` updates so future builds do not recreate the same clutter inside version control.
  • Keep `git clean` out of aliases or scripts that run automatically; always preview before deleting.

Common pitfalls

  • `git clean` is irreversible—files are deleted rather than moved to the trash. Preview with `-n` before `-f`.
  • It never touches tracked files; if you need to revert tracked content use `git restore` instead.
Related

Recover Lost Work with Reflog

Use Git’s local reference log to undo destructive commands or resurrect commits from detached HEAD sessions.

Recovery & SafetyIntermediate

List recent HEAD movements

git reflog

Shows every commit your HEAD pointed to recently, including before resets, rebases, or checkouts.

Restore the repo to a prior state

git reset --hard HEAD@{2}

Moves HEAD, the index, and the working tree back to a known-good entry from the reflog. Adjust the index number as needed.

Rescue orphaned commits safely

git checkout -b rescue HEAD@{1}

Creates a new branch pointing at a reflog commit so you can merge or cherry-pick the recovered work.

Use this when

  • You ran `git reset --hard`, `git rebase`, or `git commit --amend` and lost changes you still need.
  • A detached HEAD session produced commits that disappeared when you switched branches.

Pro tips

  • Reflog entries expire (default 90 days); recover important work promptly.
  • Pair `git fsck --lost-found` with reflog for deeper recovery in corrupted repositories.

Common pitfalls

  • Reflog is local only—other collaborators cannot restore your lost commits if you never pushed them.
Related

Escape Detached HEAD Safely

Reattach HEAD to a branch so commits are not lost when checking out raw SHAs or tags.

Recovery & SafetyBeginner

Check the current commit identity

git status --short --branch

Shows whether HEAD is attached to a branch (`## main`) or detached at a specific commit.

Create a branch from the detached state

git checkout -b experiment-fix

Attaches HEAD to a new branch at the current commit so further commits are preserved.

Return to a tracked branch

git switch main

Moves HEAD back to a named branch once you are done reviewing or experimenting.

Alternatives

Abandon detached work

git switch -

Quickly jump back to the previous branch, leaving detached commits behind (they remain recoverable via reflog).

Use this when

  • You checked out a commit hash or tag to inspect a previous build and now need to resume normal work.
  • You accidentally committed while detached and want to keep the work.

Pro tips

  • Use `git switch --detach <sha>` intentionally for read-only exploration so you remember you are detached.
  • Name rescue branches descriptively so teammates understand their purpose when you push them.

Common pitfalls

  • Committing while detached and then switching branches without creating a new branch makes the commits unreachable (recover with reflog).
Related

Resolve Merge Conflicts Confidently

Identify conflicted files, edit markers, and finish the merge or rebase without losing context.

Recovery & SafetyIntermediate

See which files are conflicted

git status

Lists files with conflict markers (`both modified`) so you know exactly what needs attention.

Abort the merge or rebase if necessary

git merge --abort

Restores the pre-merge state. Use `git rebase --abort` during rebases when conflicts are too complex to resolve immediately.

Continue after resolving files

Resolved file path
git add src/app.ts && git commit

Stage src/app.ts after resolving conflicts, then complete the merge or rebase to record the reconciled result.

Alternatives

Inspect conflict hunks in a file

git diff --staged

Shows conflict markers before you edit so you understand the competing changes.

Use rerere to remember resolutions

git config --global rerere.enabled true

Makes Git remember how you resolved conflicts so recurring conflicts apply fixes automatically.

Use this when

  • A merge, rebase, or cherry-pick stops with conflict markers and you need a repeatable resolution process.
  • You want an escape hatch when the conflict was entered accidentally.

Pro tips

  • Resolve conflicts in small logical chunks; test after each resolution if the change is risky.
  • Editors and IDEs can highlight conflict sections, but always remove `<<<<<<<`, `=======`, and `>>>>>>>` markers before staging.

Common pitfalls

  • Forgetting to stage a resolved file causes `git status` to continue showing conflicts.
  • Running `git reset --hard` mid-merge discards both sides of work and may require reflog recovery.
Related

Cherry-pick a Commit

Copy a specific commit from one branch onto another without merging the whole branch.

Branching & MergingIntermediate

Cherry-pick onto current branch

git cherry-pick <commit-sha>

Applies the given commit on top of your current branch.

Continue after resolving conflicts

git cherry-pick --continue

Creates the cherry-picked commit once you have resolved conflicts and staged the fixes.

Abort the cherry-pick

git cherry-pick --abort

Stops the cherry-pick and restores the working tree to the state before it began.

Use this when

  • You need a hotfix from another branch but not the rest of its commits.
  • You want to backport a single change.

Pro tips

  • Cherry-pick ranges with `git cherry-pick <start>^..<end>` to pull several commits at once.
  • Enable rerere (`git config --global rerere.enabled true`) so Git remembers how you resolved recurring cherry-pick conflicts.

Common pitfalls

  • Cherry-picking duplicates commits and can create conflicts, especially if the same change is merged later.
  • Avoid cherry-picking merge commits unless you provide `-m` to specify which parent to keep.
Related

Track Large Files with Git LFS

Store heavy binary assets outside of normal Git history to keep clones fast while versioning the content.

Scaling & PerformanceIntermediate

Install Git LFS support

git lfs install

Configures your repository (and global Git) to use the LFS smudge/clean filters.

Track specific file types with LFS

git lfs track "*.psd"

Adds patterns to `.gitattributes` so matching files are stored as lightweight pointers in Git history.

Commit the tracking metadata

git add .gitattributes && git commit -m "Track design assets with LFS"

Ensures teammates automatically use LFS when they clone the repository.

Use this when

  • Binary assets (design files, media, datasets) make your repository clones slow or huge.
  • You need to version large artifacts but do not require diffable history.

Pro tips

  • Store LFS objects on a shared server (e.g., GitHub, GitLab) so collaborators can fetch them easily.
  • Combine with `.gitignore` to avoid accidentally committing large files that should never be tracked.

Common pitfalls

  • LFS bandwidth may incur hosting costs; monitor usage for large teams.
  • Cloning without LFS installed leaves placeholder pointers instead of real files—document the setup steps for new contributors.
Related

Use Shallow Clones for CI Speedups

Minimize download size by limiting history depth when you only need the latest snapshot.

Scaling & PerformanceIntermediate

Clone only the latest commit

git clone --depth 1 https://example.com/org/project.git

Downloads just the newest snapshot—ideal for disposable CI environments.

Combine shallow and partial clone

git clone --depth 1 --filter=blob:none https://example.com/org/project.git

Skips large blobs while still fetching recent history—great for enormous repositories in CI.

Extend history later if needed

git fetch --depth 10 origin main

Fetches additional history without recloning when you need a bit more context.

Convert to a full clone

git fetch --unshallow

Downloads the rest of the history so advanced commands like `git log` or `git blame` behave normally again.

Use this when

  • Continuous integration jobs that only build and test the latest commit.
  • Local experiments where full history is unnecessary and bandwidth is limited.

Pro tips

  • Combine with `--filter=blob:none` on newer Git versions for even smaller clones (partial clone).
  • Document that some commands fail on shallow clones so developers know when to unshallow.

Common pitfalls

  • Shallow clones cannot push new branches without first fetching additional history in some workflows.
  • History rewriting tools (rebase, bisect) behave unexpectedly without full commit ancestry.
Related

Limit Working Tree Size with Sparse Checkout

Materialize only the directories you need from a large monorepo to reduce checkout time and disk usage.

Scaling & PerformanceAdvanced

Enable sparse checkout mode

git sparse-checkout init --cone

Initializes sparse checkout using cone mode, which is simpler for directory-based selections.

Populate only the directories you need

git sparse-checkout set apps/web services/api

Syncs the working tree so only the specified paths appear, speeding up builds and tooling.

Return to a full checkout

git sparse-checkout disable

Restores the entire repository contents if you need full context again.

Alternatives

Inspect sparse checkout patterns

cat .git/info/sparse-checkout

Shows the patterns currently being matched so you can review or edit them manually.

Use this when

  • Working inside a massive monorepo where only a few services or packages concern you.
  • Your machine or container struggles with the full repository size during local development.

Pro tips

  • Combine with `git worktree` to keep multiple sparse views checked out for different services.
  • Automate sparse-checkout setup in onboarding scripts so newcomers do not need to memorize commands.

Common pitfalls

  • Tools that assume the full repository exists may fail—ensure build scripts respect sparse mode.
  • Sparse checkout affects only the working tree; Git still downloads full history unless you also use partial clone.
Related

Need Professional IT Services?

Our IT professionals can help optimize your infrastructure and improve your operations.

ℹ️ Disclaimer

This tool is provided for informational and educational purposes only. All processing happens entirely in your browser - no data is sent to or stored on our servers. While we strive for accuracy, we make no warranties about the completeness or reliability of results. Use at your own discretion.