Photo by chansu shin on Unsplash

On this page

This chapter follows Merging versus rebasing.

Most days you commit, push, and merge. These tools matter when history is large, when a regression landed weeks ago, or when automation must enforce checks before commits leave your machine.

Revision syntax

HEAD is the current commit. HEAD^ or HEAD~1 is the first parent; HEAD~5 walks five first-parent steps. Merge commits have multiple parents—HEAD^2 is the second parent:

Terminal window
git show HEAD
git show HEAD^
git show HEAD~5
git show HEAD~5^2
git show HEAD@{"1 month ago"}

@{...} reflog-based dates resolve “where was this branch last month?”

Terminal window
git log --oneline
git log feature --oneline
git log --graph --decorate --oneline
git log --grep "fix menu" --oneline
git log -G"function login" --oneline
git log -G"login" -p
git log -5 --oneline
git log HEAD~5..HEAD --oneline
git log feature..main --oneline
git log feature...main --oneline

--grep matches commit messages. -G matches diffs (content changes). A..B shows commits reachable from B but not A. A...B shows symmetric difference (either side since merge-base)—useful for “what changed on both branches since they diverged.”

Blame

Terminal window
git blame src/app.ts
git blame -L 40,60 src/app.ts

Shows author and commit per line—helpful for understanding why a line exists, not for assigning blame in a team culture sense.

Reflog

Git logs where HEAD and branch tips were, even after reset or rebase:

Terminal window
git reflog
git reflog show feature/login

Recover a “lost” commit by creating a branch at an old reflog entry:

Terminal window
git branch recovered abc1234

Reflog entries expire (default ~90 days); unpushed work still needs remotes as backup.

Filter history with git filter-repo

Remove secrets or huge files from all commits:

Terminal window
pip install git-filter-repo
git filter-repo --path secrets.env --invert-paths

Requires force-push and team coordination. Prefer git filter-repo over legacy filter-branch.

Bisect

Find which commit introduced a bug with binary search:

Terminal window
git bisect start
git bisect bad
git bisect good v1.0.0
# test each checkout; mark good or bad
git bisect good # or git bisect bad
git bisect reset

Automate with git bisect run ./test.sh.

Worktrees

Check out multiple branches in separate directories from one repository:

Terminal window
git worktree add ../project-hotfix hotfix/123
git worktree list
git worktree remove ../project-hotfix

Avoids stashing when you need parallel checkouts without a second clone.

Hooks

Scripts in .git/hooks/ (or shared via core.hooksPath) run on events:

Hook Typical use
pre-commit Lint staged files
commit-msg Enforce message format
pre-push Run tests before push

Sample pre-commit installs via tools like husky on Node projects. Hooks are local unless the team ships a setup script— they are not cloned from GitHub automatically.

Rerere

Reuse recorded resolution of merge conflicts:

Terminal window
git config rerere.enabled true

When you resolve the same conflict again (e.g. after rebase), Git can reapply your prior resolution. Valuable on long-lived branches that merge main often.

Next: Pull requests with and without GitHub.

Search articles

Type a word to search published articles.

Open the search page