Git
Daily workflow, branching, remotes, undo, stash, tags, advanced.
Initial setup
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main
git config --global core.editor vim
git config --global color.ui auto
git config --global pull.rebase true
Useful aliases:
git config --global alias.st status git config --global alias.co checkout git config --global alias.br branch git config --global alias.ci commit git config --global alias.lg "log --oneline --graph --decorate -20"Show config + origin:
git config --listgit config --list --show-origin
Daily workflow
Status:
git status/git status -sStage file / dir:
git add file.txtgit add src/Interactive (per-hunk):
git add -pModified + deleted (not new untracked):
git add -uCommit:
git commit -m "message"git commitgit commit -am "message"
Diff
Unstaged:
git diffStaged:
git diff --stagedSince last commit:
git diff HEADBranch vs branch:
git diff main..featureSummary:
git diff --stat
Log
Full:
git logCompact:
git log --onelineGraph + all branches:
git log --oneline --graph --allLast 20:
git log --oneline -20By author / date / message:
git log --author="jo"git log --since="2025-01-01"git log --grep="fix"File history with renames:
git log -p --follow file.txt
Show / blame
Show commit:
git show abc1234git show HEAD~3Blame:
git blame file.txtgit blame -L 10,20 file.txt
Branching
List local / remote / all:
git branchgit branch -rgit branch -agit branch -vCreate:
git branch feature-xCreate + switch (modern):
git switch -c feature-xSwitch:
git switch mainRename:
git branch -m old newgit branch -m new# currentDelete (safe):
git branch -d feature-xForce delete:
git branch -D feature-x
Merge
Merge:
git checkout main && git merge feature-xForce merge commit (preserve branch history):
git merge --no-ff feature-xAbort:
git merge --abort
Rebase
Onto main:
git checkout feature-x && git rebase mainAbort / continue:
git rebase --abort/git rebase --continue
Remotes
List:
git remote -vAdd:
git remote add origin https://github.com/user/repo.gitgit remote add upstream https://github.com/original/repo.gitRemove / rename:
git remote remove origingit remote rename origin old-origin
Fetch / pull / push
Fetch:
git fetch origingit fetch --allPull:
git pullgit pull --rebasePush:
git pushgit push origin mainPush + set upstream:
git push -u origin feature-xDelete remote branch:
git push origin --delete feature-xPush all branches / tags:
git push --all origingit push --tags
Track / prune
Track remote branch:
git checkout --track origin/feature-xSet upstream:
git branch --set-upstream-to=origin/main mainSync fork with upstream:
git fetch upstream git checkout main git merge upstream/main git push origin mainPrune stale refs:
git fetch --prunegit remote prune origin
Undo
Unstage / discard
Unstage file:
git restore --staged file.txtDiscard local changes:
git restore file.txtDiscard all:
git restore .
Amend
Change message:
git commit --amend -m "new message"Add forgotten file:
git add forgotten.txt && git commit --amend --no-edit
Revert (safe on shared branches)
- New commit undoing old commit:
git revert abc1234
Reset
Soft (keep changes staged):
git reset --soft HEAD~1Mixed (keep changes unstaged, default):
git reset --mixed HEAD~1Hard (destructive!):
git reset --hard HEAD~1
Recover lost commits
Show reflog:
git reflogCheck out lost commit:
git checkout abc1234Save it:
git branch recovery abc1234
Remove files
Untrack, keep on disk:
git rm --cached file.txtUntrack + delete:
git rm file.txt
Stash
Save (staged + unstaged):
git stashgit stash push -m "description"Include untracked / ignored:
git stash -ugit stash -aApply (keep in list):
git stash applyPop (apply + remove):
git stash popSpecific stash:
git stash apply stash@{2}List / show:
git stash listgit stash show -p stash@{0}Drop / clear:
git stash drop stash@{1}git stash clearBranch from stash:
git stash branch new-branch stash@{0}
Tags
List:
git taggit tag -l "v1.*"Annotated (recommended):
git tag -a v1.0 -m "Release v1.0"Lightweight:
git tag v1.0Tag specific commit:
git tag -a v0.9 abc1234 -m "Retroactive"Show:
git show v1.0Delete:
git tag -d v1.0git push origin --delete v1.0Push:
git push origin v1.0git push --tags
Cherry-pick
Apply one commit:
git cherry-pick abc1234Stage only (no commit):
git cherry-pick --no-commit abc1234Range:
git cherry-pick abc1234..def5678Abort:
git cherry-pick --abort
Worktrees
Add existing branch:
git worktree add ../feature-x feature-xNew branch + worktree:
git worktree add -b hotfix ../hotfix mainList:
git worktree listRemove / prune:
git worktree remove ../feature-xgit worktree prune
Bisect
Start + mark current bad + known good:
git bisect start git bisect bad git bisect good v1.0Then iterate:
git bisect goodorgit bisect badReset when done:
git bisect resetAutomated:
git bisect start HEAD v1.0 git bisect run ./test-script.sh
Interactive rebase
- Last 5 commits:
git rebase -i HEAD~5
Commands in the editor:
pick— keepreword— change messageedit— stop to amendsquash— merge into previous (keep both messages)fixup— merge into previous (discard message)drop— remove
Submodules
Add:
git submodule add https://github.com/user/repo.git path/to/subClone with submodules:
git clone --recurse-submodules URLInitialize after clone:
git submodule update --init --recursiveUpdate to latest on tracked branch:
git submodule update --remoteRemove (3-step):
git submodule deinit path/to/submodule git rm path/to/submodule rm -rf .git/modules/path/to/submodule
Useful patterns
File history with diffs:
git log -p --follow file.txtWhen was string added/removed:
git log -S "searchString" --onelineWhen did regex appear:
git log -G "regex" --onelineAll tracked files:
git ls-filesFile at specific revision:
git show HEAD~3:path/to/file.txtTar archive of HEAD:
git archive --format=tar.gz --prefix=project/ HEAD > project.tar.gzClean untracked:
git clean -nd# dry rungit clean -fd# for realShallow clone:
git clone --depth 1 URLSparse checkout:
git sparse-checkout init git sparse-checkout set src/ docs/
.gitignore
# Compiled
*.o
*.pyc
__pycache__/
build/
dist/
# Dependencies
node_modules/
vendor/
# Secrets
.env
.env.local
*.pem
# IDE
.vscode/
.idea/
*.swp
# OS
.DS_Store
Thumbs.db
# Logs
*.log
# Un-ignore
!important.log
Check why a file is ignored:
git check-ignore -v file.txtGlobal ignore:
git config --global core.excludesFile ~/.config/git/ignore