Git rebase (Git 2.45+): reapplies commits from one branch onto another, creating linear history by replaying commits. Command: git rebase main (rebase current branch onto main). Process: (1) Find common ancestor. (2) Save commits from current branch. (3) Reset current branch to target. (4) Replay saved commits one by one with new SHAs. Git merge: creates merge commit, preserves both histories, non-linear graph. Key differences: Rebase creates clean linear history (better for feature branches before PR), rewrites commit SHAs (dangerous if pushed to shared branches). Merge preserves complete history (safe for shared branches like main/develop), shows when/where branches merged. Best practices (2025): Use git rebase -i main to clean up feature branch commits before merging. Always git pull --rebase for local commits on tracked branches. Never rebase commits already pushed to shared repositories. Enable git config --global pull.rebase true for cleaner history.
Git Advanced FAQ & Answers
25 expert Git Advanced answers researched from official documentation. Every answer cites authoritative sources you can verify.
unknown
25 questionsInteractive rebase (Git 2.44+): powerful tool to edit commit history, squash commits, reorder, edit messages. Commands: git rebase -i HEAD~3 (last 3 commits), git rebase -i main (all commits since main). Editor opens with commits and actions: pick (use commit), reword (change message), edit (amend commit), squash (combine with previous, keep both messages), fixup (like squash but discard message), drop (remove commit), exec (run shell command). Modern workflow (2025): Use git commit --fixup=
Git cherry-pick: applies changes from specific commit to current branch, creating new commit with same changes but different SHA. Commands: git cherry-pick 3..main1 (range, excludes main~3). Common use cases (2025): (1) Backport bug fix to release branches: git checkout release-2.0 && git cherry-pick
Git reset: moves HEAD and current branch pointer to specified commit, modifies staging area and working directory differently. (1) git reset --soft
Git reset: moves branch pointer backwards, rewrites history by removing commits from branch. Commands: git reset --soft HEAD~1 (undo commit, keep staged), git reset --hard origin/main (match remote). Use for: local unpushed commits, private feature branches. Destructive: commits become unreachable but recoverable via git reflog for 90 days. Git revert: creates new commit that applies exact opposite of changes (inverse cherry-pick). Commands: git revert
Git reflog: records every HEAD movement in local repository (commits, checkouts, resets, rebases, cherry-picks). Commands: git reflog (show all HEAD movements), git reflog show branch-name (specific branch), git reflog show --all (all refs). Output: HEAD@{0} (current), HEAD@{1} (previous), etc. with commit SHA, action, and timestamp. Example output: abc123 HEAD@{0}: commit: Add feature / def456 HEAD@{1}: reset: moving to HEAD~1. Recovery scenarios (2025): (1) Undo accidental reset: git reflog → find commit before reset → git reset --hard
Git bisect: 'binary search through commit history to find commit that introduced bug.' Process: (1) git bisect start. (2) git bisect bad (mark current commit as bad). (3) git bisect good
Git worktree (Git 2.15+): allows multiple working directories for single repository, each checked out to different branch. Share single .git directory, avoiding multiple clones. Commands: git worktree add ../hotfix-dir hotfix (create worktree for existing branch), git worktree add -b feature-x ../feature-x-dir main (create new branch), git worktree list (show all worktrees with branches), git worktree remove ../hotfix-dir (delete worktree), git worktree prune (clean stale metadata). Use cases (2025): (1) Urgent hotfix while working on feature (no stashing needed). (2) Review PR without losing current work. (3) Parallel CI/testing in different worktrees. (4) Stacked diffs workflow (multiple dependent features). Benefits: Faster than git clone (shares objects), no stashing/switching overhead, independent working states. Limitations: Can't checkout same branch in multiple worktrees, refs in refs/bisect and refs/worktree not shared. Best practices: Use descriptive directory names, run git worktree prune monthly, commit before removing worktree.
Git submodule: repository embedded inside another repository (superproject), maintains separate history and .git directory. Use for: third-party libraries, shared code across projects, monorepo components. Commands: git submodule add
Git hooks: scripts Git executes before/after events (commit, push, merge) to automate workflow. Stored in .git/hooks/, must be executable (chmod +x). Client-side hooks: pre-commit (lint/test before commit, exits non-zero to abort), prepare-commit-msg (edit default message), commit-msg (validate format, enforce conventional commits), post-commit (notifications), pre-push (run full test suite, prevent bad pushes), post-checkout (install dependencies), post-merge (npm install after pulling package.json changes). Server-side hooks: pre-receive (validate push before accepting), update (per-branch validation), post-receive (trigger CI/CD deployment). Modern tooling (2025): Husky v9 (Node.js, 2 kB, ~1ms execution, auto-installs hooks via npm), pre-commit framework (Python ecosystem), lefthook (fast Go-based tool). Example with Husky: npx husky init creates .husky/ directory, npx husky add .husky/pre-commit "npm test" adds hook. Combine with lint-staged to only check staged files. Best practices: Keep hooks fast (<2s for pre-commit), use lint-staged for performance, version control hooks via Husky/pre-commit, document setup in README.
Git stash advanced commands beyond basic git stash/git stash pop. Named stashes: git stash push -m "WIP: refactoring auth" (descriptive message). Partial stashing: git stash push -- src/auth.js src/utils.js (specific files only), git stash push -p (interactive, select hunks). Include untracked/ignored: git stash -u (include untracked files), git stash -a (include ignored files like build artifacts). Managing multiple stashes: git stash list (shows stash@{0}, stash@{1}, etc. with messages), git stash show stash@{1} -p (view diff of specific stash), git stash apply stash@{1} (apply without removing from list), git stash pop stash@{1} (apply and remove), git stash drop stash@{1} (delete specific stash), git stash clear (delete all stashes). Advanced workflows: git stash branch feature-from-stash stash@{0} (create branch from stash, auto-applies and drops stash). Best practices (2025): Name all stashes with -m, clean stashes monthly with git stash list, prefer git worktree for long-term parallel work, use git stash -u by default to avoid losing untracked files.
Git clean: removes untracked files from working directory. Permanently deletes files (not recoverable). ALWAYS preview first: git clean -n (dry-run, shows what would be deleted), git clean -nd (dry-run including directories). Deletion commands (require -f force flag): git clean -f (delete untracked files only), git clean -fd (delete untracked files and directories), git clean -fX (delete only ignored files from .gitignore, preserves build artifacts logic), git clean -fx (delete ALL untracked and ignored files, nuclear option). Interactive mode: git clean -i (choose what to delete interactively, safest). Common workflows (2025): Clean build artifacts: git clean -fX (removes node_modules, dist/, .cache). Fresh clone state: git clean -fdx (WARNING: removes everything not tracked). Safe exploration: git clean -fdn → review → git clean -fd. Best practices: ALWAYS run git clean -n first, add permanent ignores to .gitignore instead of cleaning repeatedly, use git stash -u instead if might need files later, configure git config --global clean.requireForce true (default safety).
Git blame: shows which commit and author last modified each line of file. Basic: git blame file.js (shows SHA, author, timestamp, line number, content). Output format: abc123 (John Doe 2025-01-15 14:23:45 -0500 42) const x = 1;. Advanced options: git blame -L 10,20 file.js (specific line range), git blame -L :functionName: file.js (blame specific function), git blame -w (ignore whitespace changes), git blame -C (detect lines copied from other files in same commit), git blame -C -C (detect copies from any commit), git blame -M (detect moved/cut-pasted lines within file), git blame abc123 file.js (blame at specific commit in history), git blame --since="3.weeks" file.js (only show changes from last 3 weeks). Effective workflow (2025): git blame file.js → find SHA → git show
Advanced git log filtering for code archeology. Author/date filters: git log --author="John" --committer="Jane" (regex supported), git log --since="2.weeks" --until="2025-01-01", git log --after="2025-01-01 09:00" --before="2025-01-15 17:00" (precise timestamps). Content filters: git log --grep="fix" --grep="bug" --all-match (multiple patterns, AND logic), git log -S"TODO" (pickaxe: commits adding/removing string), git log -G"function.*{" (regex pattern in diff), git log -L:functionName:file.js (track function history). File/path filters: git log -- path/to/file (commits affecting file), git log --follow -- file.js (track through renames). Branch comparison: git log main..feature (commits in feature not in main), git log main...feature (symmetric difference, commits in either but not both). Format options: git log --oneline --graph --decorate (visual branch history), git log --pretty=format:"%h %an %ar: %s" (custom format), git log --stat (file change stats), git log -p (full diff). Advanced: git log --merges (only merge commits), git log --no-merges --first-parent (linear history on main), git log --all --source (all branches with branch names). Combined: git log --author="John" --since="1.month" --grep="fix" --no-merges -S"API" (powerful multi-filter).
git filter-branch: deprecated tool for rewriting Git history (slow, complex, error-prone). Modern alternative: git-filter-repo (10-100x faster, safer, not built-in). Install: brew install git-filter-repo or pip install git-filter-repo. Common use cases (2025): (1) Remove sensitive data: git filter-repo --invert-paths --path secrets.env (removes file from all history). (2) Extract subdirectory: git filter-repo --path subdir/ --path-rename subdir/: (make subdir new root). (3) Change author info: git filter-repo --mailmap mailmap.txt (fix names/emails). (4) Remove large files: git filter-repo --strip-blobs-bigger-than 10M. Critical workflow: (1) REVOKE compromised credentials first (if removing secrets). (2) Fresh clone: git clone --mirror repo.git. (3) Run filter-repo on clone. (4) Force push: git push --force --all. (5) All team members must re-clone (history rewritten). BFG Repo-Cleaner: simpler alternative for removing files/passwords. Best practices (2025): Use filter-repo not filter-branch, close all PRs before rewriting, coordinate team re-clone, backup before running, verify with git log after.
Git rerere (Reuse Recorded Resolution): 'records how merge conflicts resolved, automatically reuses solutions.' Enable: git config --global rerere.enabled true && git config --global rerere.autoupdate true. autoupdate automatically stages resolved conflicts (default: false, requires manual git add). Storage: resolutions in .git/rr-cache/ directory. How it works: (1) Conflict occurs during merge/rebase. (2) You resolve conflict + commit. (3) Git records resolution (conflict markers + resolution). (4) Same conflict later → Git auto-applies recorded resolution. Enable when: rebasing >3 times/week, long-lived feature branches (>2 weeks), frequent integration with main branch. Cache expiration: unresolved conflicts pruned after 15 days (gc.rerereUnresolved), resolved after 60 days (gc.rerereResolved). Commands: git rerere status (conflicts), git rerere diff (resolutions), git rerere forget
Git history rewriting best practices (2025): Golden rule: NEVER rewrite pushed commits on shared branches (main, master, develop, release). Breaks collaborators' repos. Safe scenarios: (1) Private feature branches before merging. (2) Local unpushed commits. (3) Team-coordinated rewrites with all members re-cloning. Pre-rewrite safety: git branch backup-feature (create backup branch), git reflog (verify recoverable for 90 days). Rewriting tools: git rebase -i main (clean up feature branch commits), git commit --amend (fix last commit message/files), git reset --soft HEAD~3 (undo commits, keep changes staged). Safe force-pushing: Use git push --force-with-lease (Git 2.30+: add --force-if-includes for extra safety). Checks if remote changed since last fetch, prevents overwriting teammates' work. Fails if remote updated by others. Alternative: git push --force is dangerous (blindly overwrites). Team coordination: Announce before force-pushing shared branches, document reason in PR/Slack, ensure all members fetch before/after, prefer git revert for public commits (preserves history, no force-push needed). Verification: git log --oneline --graph after rewriting, git push --dry-run --force-with-lease before pushing.
Git patches: text files containing diffs, used for sharing changes without Git remote access. Create patches: git diff > unstaged.patch (uncommitted changes), git diff --cached > staged.patch (staged changes), git format-patch -1 HEAD (last commit as 0001-.patch with metadata), git format-patch -3 HEAD (last 3 commits, creates 3 files), git format-patch main..feature (all commits in feature since main), git format-patch --stdout main > feature.patch (single file for all commits). Apply patches: git apply changes.patch (apply diff without committing, like git diff output), git apply --check changes.patch (dry-run test), git apply --3way changes.patch (three-way merge if conflicts), git am 0001-.patch (apply format-patch files, preserves commits/author/date), git am --signoff *.patch (add Signed-off-by line). Use cases (2025): Linux kernel mailing list workflow, contributing to projects without push access, sharing changes via forums/email, archiving experimental changes. Difference: git format-patch includes full commit metadata (author, date, message, committer), git am recreates original commits exactly. Best practices: Prefer PRs/MRs for team collaboration, use patches for open-source mailing lists, test with --check before applying.
Git tags mark specific points in history for releases/versions. Lightweight tag: simple pointer to commit (like immovable branch). Create: git tag v1.0.0. Stores: commit SHA only (41 bytes). Use for: temporary markers, local bookmarks, private milestones. Annotated tag: full Git object with metadata. Create: git tag -a v1.0.0 -m "Release 1.0.0" or git tag -a v2.0.0
git gc (garbage collection): optimizes repository by packing loose objects, removing unreachable objects, cleaning caches. Operations: (1) Packs loose objects into compressed packfiles (saves disk space, faster operations). (2) Removes objects unreachable from any ref after grace period (default 14 days for objects, 90 days for reflog commits). (3) Packs refs into packed-refs file. (4) Cleans rerere cache and worktree metadata. (5) Prunes old reflog entries (90 days for reachable, 30 days for unreachable). Commands: git gc (standard cleanup, runs in ~seconds for small repos), git gc --aggressive (thorough repack, slow, rarely needed), git gc --prune=now (immediate pruning, use after filter-repo), git gc --auto (runs only if needed based on heuristics). Automatic triggering (Git 2.30+): Git auto-runs gc when: >6700 loose objects exist, >50 packfiles exist, or after operations like fetch/rebase. Modern alternative (Git 2.30+): git maintenance start (schedules background tasks: hourly commit-graph/prefetch, daily incremental-repack/loose-objects, weekly gc). Best practices (2025): Let automatic gc handle routine maintenance, run git gc after major history rewrites (filter-repo), use git maintenance for repos >1GB, avoid --aggressive (minimal benefit, high cost).
Git bundle: single file containing Git objects and refs for offline transfer. Create full: git bundle create repo.bundle --all (entire repo with all branches/tags). Create specific: git bundle create feature.bundle main (single branch). Incremental: git bundle create updates.bundle main10..main (last 10 commits, requires main10 exists in destination). Verify: git bundle verify repo.bundle (checks integrity and prerequisites). Clone: git clone repo.bundle new-repo (creates repository from bundle). Fetch: git fetch /path/to/repo.bundle refs/heads/main:refs/heads/main (imports branch). Track incremental: git tag -f last-bundle main (mark last bundled commit), then git bundle create next.bundle last-bundle..main. Use cases: air-gapped deployments (no network access), secure environments (financial/lab systems), offline transfer (USB/email), CI/CD artifacts. Bundle is read-only (cannot push to it). Best practice: verify before use, tag bundle points, err on overlap side (safe).
Advanced git config for productivity (2025). Conflict resolution: git config --global rerere.enabled true (reuse recorded resolutions, essential for frequent rebasing), git config --global merge.conflictstyle zdiff3 (Git 2.35+, best conflict markers with common ancestor). Branch management: git config --global fetch.prune true (auto-delete gone remote branches), git config --global pull.rebase true (rebase not merge on pull, cleaner history), git config --global push.default current (push current branch to same name), git config --global push.autoSetupRemote true (Git 2.37+, auto-create remote branch). Rebase workflow: git config --global rebase.autosquash true (auto-handle fixup!/squash! commits), git config --global rebase.updateRefs true (Git 2.38+, auto-update dependent branches). Security: git config --global commit.gpgsign true (sign all commits), git config --global gpg.format ssh (use SSH keys for signing, Git 2.34+), git config --global user.signingkey ~/.ssh/id_ed25519.pub. Performance: git config --global core.fsmonitor true (Git 2.37+, faster git status on large repos), git config --global feature.manyFiles true (optimize for repos with many files). UX improvements: git config --global core.excludesfile ~/.gitignore_global (global .gitignore), git config --global help.autocorrect 10 (auto-run misspelled commands after 1s), git config --global alias.st "status -sb" (shortcuts). Credential management: git config --global credential.helper osxkeychain (macOS) or git config --global credential.helper 'cache --timeout=3600' (Linux, 1 hour cache).
Common Git mistakes and recovery (2025). (1) Committed to wrong branch: git reset --soft HEAD~1 (uncommit, keep changes staged), git switch correct-branch, git commit (or git cherry-pick
Sparse-checkout (Git 2.25+): check out only subset of files from repository, skip rest. Setup: git clone --no-checkout
git maintenance (Git 2.30+): 'scheduled optimization tasks for large repos.' Enable: git maintenance start (runs hourly: commit-graph/prefetch, daily: loose-objects/incremental-repack, weekly: pack-refs). incremental-repack consolidates small pack-files without full repack (repos with thousands of packs dropped to dozens, 200GB→30-50GB). commit-graph accelerates log/blame/traversal operations. multi-pack-index prevents performance degradation from many packfiles. Large repo optimization: (1) scalar clone