Git basics
Repo & config
| Goal | Command |
|---|---|
| New repo | git init |
| Clone | git clone <url> |
| Clone shallow | git clone --depth 1 <url> |
| Identity | git config --global user.name "...", git config --global user.email "..." |
| Show setting | git config --get user.email |
Status & diff
| Goal | Command |
|---|---|
| Overview | git status |
| Short | git status -sb |
| Unstaged changes | git diff |
| Staged vs last commit | git diff --staged (same as --cached) |
| File history | git log --follow -p -- <path> |
| One commit | git show <commit> |
Stage & commit
| Goal | Command |
|---|---|
| Stage paths | git add <path> |
| Stage all (tracked + new) | git add -A |
| Stage interactively | git add -p |
| Commit | git commit -m "message" |
| Stage tracked + commit | git commit -am "message" |
| Amend last commit (keep msg) | git commit --amend --no-edit |
| Amend with new message | git commit --amend -m "message" |
| Change last commit’s dates | GIT_AUTHOR_DATE="2024-01-15T10:00:00" GIT_COMMITTER_DATE="2024-01-15T10:00:00" git commit --amend --no-edit — or author only: git commit --amend --no-edit --date="2024-01-15T10:00:00" (committer stays current time) |
| Change an older commit’s date | git rebase -i <commit>^ → edit / e on that line → set GIT_AUTHOR_DATE / GIT_COMMITTER_DATE as above → git commit --amend --no-edit → git rebase --continue |
Log & inspect
| Goal | Command |
|---|---|
| Log compact | git log --oneline --graph --decorate -20 |
| Log with stats | git log --stat |
| Who changed a line | git blame <path> |
| Branches containing commit | git branch -a --contains <commit> |
Branch, switch & checkout
| Goal | Command |
|---|---|
| List local | git branch |
| List all | git branch -a |
| Create (stay on current) | git branch <name> |
| Switch branch | git switch <name> or git checkout <name> |
| Create branch + switch to it | git switch -c <name> or git checkout -b <name> |
| Detached HEAD at a commit | git checkout <commit> or git switch --detach <commit> |
| Checkout tracks remote branch | git checkout <name> (if origin/<name> exists and name is unique) — or git switch -c <name> --track origin/<name> |
| Delete merged | git branch -d <name> |
| Delete force | git branch -D <name> |
| Rename current | git branch -m <new-name> |
git checkout can also take paths after --: it does not switch branches then; it copies those files into your working tree from somewhere else—usually the index (git checkout -- <path>) or a specific revision (git checkout HEAD -- <path>, git checkout <branch> -- <path>). That is how people used to discard edits or pull one file from another branch. Prefer git restore for that today (git restore <path>, git restore --source=HEAD <path>). For moving HEAD to a branch, git switch (Git 2.23+) is the dedicated command. Older docs and scripts still use checkout for everything.
Remote & sync
| Goal | Command |
|---|---|
| List remotes | git remote -v |
| Add remote | git remote add origin <url> |
| Fetch | git fetch |
| Fetch prune deleted branches | git fetch --prune |
| Pull | git pull |
| Pull rebase | git pull --rebase |
| Push branch | git push -u origin <branch> |
| Push current | git push |
| Force push (overwrite remote) | git push --force / git push -f — rewrites remote history; avoid on shared branches unless your team expects it |
| Safer force push | git push --force-with-lease — refuses if the remote tip changed since your last fetch (still history rewrite; use with care) |
| Delete remote branch | git push origin --delete <branch> |
Merge & rebase
| Goal | Command |
|---|---|
| Merge branch into current | git merge <branch> |
| Abort merge | git merge --abort |
| Rebase onto | git rebase <upstream-branch> |
| Interactive rebase last N commits | git rebase -i HEAD~N |
| Interactive rebase from a specific commit (and after) | git rebase -i <commit>^ — same as git rebase -i <commit>~1 on linear history: both mean “rebase onto the parent of <commit>”, so the todo lists <commit> and all commits after it; use git rebase -i --root if <commit> is the first commit |
| Reword that commit’s message | In the todo file: reword / r instead of pick on that line → save → edit message in the next editor step |
| Edit that commit’s snapshot | In the todo file: edit / e instead of pick on that line → save → change files → git add … → git commit --amend → git rebase --continue |
| Abort rebase | git rebase --abort |
| Continue after conflict or amend | git rebase --continue |
| Cherry-pick | git cherry-pick <commit> |
Undo & clean up
| Goal | Command |
|---|---|
| Unstage file | git restore --staged <path> |
| Discard working-tree file | git restore <path> |
| Soft reset (keep changes staged) | git reset --soft HEAD~1 |
| Mixed reset (default, unstage) | git reset HEAD~1 |
| Hard reset (destructive) | git reset --hard <commit> |
| Revert a commit (new commit) | git revert <commit> |
| Remove untracked files/dirs | git clean -fd (dry-run: git clean -fdn) |
Stash
| Goal | Command |
|---|---|
| Stash | git stash push -m "note" |
| List | git stash list |
| Apply latest | git stash apply |
| Apply + drop | git stash pop |
| Drop latest | git stash drop |
Tags
| Goal | Command |
|---|---|
| List | git tag |
| Annotated tag | git tag -a v1.0 -m "release" |
| Push tags | git push --tags |
Misc
| Goal | Command |
|---|---|
| Recover moved HEAD / lost commits | git reflog |
| Ignore patterns file | .gitignore in repo root |
See also docker.