# Git command-line essentials

Source: https://codewiki.com/cheatsheets/git-shell/

## Read repository state

- `git status --short --branch` — show the branch, upstream divergence, and compact working-tree and index status
- `git diff -- path/to/file` — compare unstaged content with the index for one path
- `git diff --cached -- path/to/file` — compare staged content with `HEAD` for one path
- `git diff HEAD -- path/to/file` — compare working-tree content with `HEAD`, including staged and unstaged changes
- `git log --oneline --decorate --graph --all` — draw the commit graph reachable from all local references
- `git show --stat --oneline COMMIT` — inspect one commit's header and file-level change summary

## Stage and commit

- `git add -- path/to/file` — copy the current path content into the index
- `git add -p -- path/to/file` — choose patch hunks interactively for the index
- `git restore --staged -- path/to/file` — reset the index path from `HEAD` while keeping the working-tree edit
- `git diff --cached --check` — report whitespace errors in the change prepared for commit
- `git commit -m 'Explain the change'` — commit the staged snapshot with a non-empty message
- `git commit --amend --no-edit` — replace the latest commit with the current index while retaining its message

## Branches and tags

- `git switch -c feature/name main` — create `feature/name` from `main` and switch to it
- `git switch main` — switch the working tree and index to the local `main` branch
- `git branch --show-current` — print the current branch name, or nothing in detached `HEAD` state
- `git branch -m feature/new-name` — rename the current branch without changing its commits
- `git branch -d feature/name` — delete a branch only when Git considers it fully merged
- `git tag -a v1.2.3 -m 'Release v1.2.3'` — create an annotated tag at `HEAD`
- `git show --no-patch v1.2.3` — inspect a tag and its target without printing the patch

## Compare revisions

- `git rev-parse --verify main^{commit}` — resolve `main` and require it to identify a commit
- `git merge-base main feature/name` — print a best common ancestor of two commit tips
- `git log main..feature/name --oneline` — list commits reachable from the feature but not from `main`
- `git log --left-right --oneline main...feature/name` — show commits unique to either side and mark which side contains each
- `git diff main...feature/name` — compare the feature tip with its merge base against `main`
- `git diff COMMIT^ COMMIT --` — show a non-root commit's change from its first parent

## Fetch and inspect remotes

- `git remote -v` — show each remote's configured fetch and push URLs
- `git config --get-all remote.origin.fetch` — inspect the refspecs used when fetching from `origin`
- `git fetch --prune origin` — download from `origin` and remove stale remote-tracking references
- `git branch --remotes --verbose` — list local remote-tracking references and their tip subjects
- `git log HEAD..origin/main --oneline` — list fetched commits on `origin/main` that `HEAD` lacks
- `git diff --stat HEAD...origin/main` — summarize the remote side's changes since the merge base

## Integrate and publish

- `git merge --ff-only origin/main` — advance the current branch only when no merge commit is required
- `git merge --no-ff feature/name` — merge the feature and create a merge commit even when fast-forwarding is possible
- `git pull --ff-only origin main` — fetch remote `main` and accept only a fast-forward update
- `git push --dry-run origin HEAD` — preview the remote reference update without changing it
- `git push -u origin feature/name` — publish the local branch and record its upstream
- `git push --force-with-lease origin feature/name` — force a rewritten branch only if the lease expectation still matches
- `git push --atomic origin main v1.2.3` — require the branch and tag updates to succeed or fail together

## Resolve merge conflicts

- `git ls-files --unmerged` — show the base, stage-2 side, and stage-3 side recorded for each conflict
- `git show :2:path/to/file` — read the current operation's stage-2 version
- `git show :3:path/to/file` — read the current operation's stage-3 version
- `git add -u -- path/to/file` — replace a tracked path's unmerged index entries with its resolved state
- `git diff --check` — find leftover conflict markers and whitespace errors before continuing
- `git merge --continue` — finish the merge after resolving and staging every conflict
- `git merge --abort` — restore the pre-merge state when the merge must be abandoned

## Rebase and cherry-pick

- `git rebase main` — replay the current branch's unique commits onto `main`
- `git rebase -i HEAD~5` — reorder, combine, edit, or drop the latest five commits
- `git rebase --onto main OLD_BASE feature/name` — replay `OLD_BASE..feature/name` onto `main` and check out the rewritten feature
- `git rebase --continue` — resume a stopped rebase after staging the resolution
- `git rebase --abort` — return the branch and working tree to the pre-rebase state
- `git cherry-pick -x COMMIT` — apply one commit's change and record its source identifier
- `git cherry-pick --abort` — restore the state from before the current cherry-pick sequence

## Undo by storage layer

- `git restore -- path/to/file` — discard unstaged tracked edits by copying the index version to the working tree
- `git restore --source=COMMIT -- path/to/file` — replace a working-tree path from a commit without changing the index
- `git restore --source=HEAD --staged --worktree -- path/to/file` — replace both index and working-tree versions of one path from `HEAD`
- `git reset --soft HEAD^` — move `HEAD` to its first parent without changing the index or working tree
- `git reset --mixed HEAD^` — move `HEAD`, reset the index to its parent, and leave the working tree unchanged
- `git reset --hard HEAD^` — move `HEAD` and reset tracked index and working-tree content to its parent
- `git revert COMMIT` — record the inverse of an ordinary commit; reverting a merge also requires `-m`

## Stash and worktrees

- `git stash push -u -m 'Context for later'` — stash tracked and untracked changes with a searchable message
- `git stash list` — list stash entries without applying them
- `git stash show --patch stash@{0}` — inspect the complete patch stored in one stash entry
- `git stash apply stash@{0}` — apply a stash while retaining the stash entry
- `git stash branch rescue/stashed stash@{0}` — create a branch at the stash base, apply it, and drop it only on success
- `git worktree add -b hotfix/name ../repo-hotfix main` — create a new branch and check it out in another working tree
- `git worktree list --porcelain` — list worktrees in a stable, script-friendly format

## Find regressions and recover

- `git bisect start BAD GOOD` — start a binary search between a known bad and known good commit
- `git bisect run ./test-regression.sh` — classify revisions by exit status: 0 good, 125 skip, and other 1–127 values bad
- `git bisect reset` — end bisection and return to the branch or commit checked out before it
- `git reflog --all --date=iso` — inspect dated local movements of `HEAD` and other references
- `git show --stat --oneline HEAD@{1}` — inspect a candidate reflog position before recovering it
- `git branch rescue/lost HEAD@{1}` — make the verified reflog position reachable from a new branch
- `git fsck --unreachable` — report currently unreachable objects that may contain lost commits

## Inspect objects and references

- `git cat-file -t OBJECT` — print an object's type
- `git cat-file -p OBJECT` — pretty-print an object's content according to its type
- `git ls-tree -r --name-only COMMIT` — list every path in a commit snapshot recursively
- `git show COMMIT:path/to/file` — read one file directly from a committed snapshot
- `git ls-files --stage` — show each index entry's mode, object identifier, stage, and path
- `git for-each-ref --format='%(refname) %(objectname)' refs/heads/` — list local branch references with their full target identifiers
- `git update-ref refs/heads/main NEW OLD` — update `main` atomically only if it still points to `OLD`
