# Git > Distributed version control — track, branch, merge, and collaborate. ## Config ```bash # Identity git config --global user.name "Your Name" git config --global user.email "you@example.com" # Editor git config --global core.editor vim # Default branch name git config --global init.defaultBranch main # Useful defaults git config --global pull.rebase true git config --global push.autoSetupRemote true git config --global rerere.enabled true git config --global diff.algorithm histogram git config --global merge.conflictstyle zdiff3 # Aliases git config --global alias.st status git config --global alias.co checkout git config --global alias.br branch git config --global alias.lg "log --oneline --graph --all" # Show current config git config --list --show-origin ``` ### Config Scope | Flag | File | Purpose | |------------|-------------------------|------------------| | `--system` | `/etc/gitconfig` | All users | | `--global` | `~/.gitconfig` | Current user | | `--local` | `.git/config` | Current repo | Local overrides global overrides system. ## Init and Clone ```bash git init git init --bare repo.git # server-side (no working tree) git clone https://github.com/user/repo.git git clone --depth 1 https://... # shallow (latest commit only) git clone --branch v2.0 https://... # specific branch/tag ``` ## Daily Workflow ```bash # Status git status git status -s # short format # Stage git add file.txt # specific file git add src/ # directory git add -p # interactive hunk staging git add -u # stage modified/deleted, not new # Unstage git restore --staged file.txt git reset HEAD file.txt # older syntax, same effect # Discard working tree changes git restore file.txt git checkout -- file.txt # older syntax # Commit git commit -m "feat: add login page" git commit -am "fix: typo" # stage tracked + commit git commit --amend # rewrite last commit git commit --amend --no-edit # amend without changing message git commit --allow-empty -m "trigger" # empty commit (CI triggers) ``` ## Diff ```bash # Working tree vs staging git diff # Staging vs last commit git diff --cached git diff --staged # same thing # Between commits git diff abc123..def456 git diff HEAD~3..HEAD # Between branches git diff main..feature # Specific file git diff -- path/to/file.txt # Stats only git diff --stat git diff --name-only git diff --name-status # with A/M/D markers # Word-level diff git diff --word-diff ``` ## Log ```bash # Compact git log --oneline git log --oneline -10 # last 10 # Graph git log --oneline --graph --all # Detailed git log -p # with diffs git log --stat # with file stats # Filter git log --author="alice" git log --since="2025-01-01" git log --after="2 weeks ago" git log --grep="fix:" # search commit messages git log -S "function_name" # search for string in diffs (pickaxe) git log -G "regex_pattern" # search diffs with regex git log -- path/to/file # commits touching file # Format git log --pretty=format:"%h %an %ar %s" git log --pretty=format:"%C(yellow)%h%Creset %s %C(dim)(%ar)%Creset" # Show single commit git show abc123 git show HEAD~2:path/to/file # file at specific commit ``` ## Stash ```bash # Save work in progress git stash git stash push -m "wip: api refactor" git stash push path/to/file # stash specific files # List stashes git stash list # Restore git stash pop # apply + remove from stash git stash apply # apply, keep in stash git stash apply stash@{2} # specific stash # Inspect git stash show # stat git stash show -p # full diff # Drop git stash drop stash@{0} git stash clear # drop all # Stash untracked files too git stash -u git stash --include-untracked ``` ## Remotes ```bash # List git remote -v # Add git remote add origin https://github.com/user/repo.git git remote add upstream https://github.com/original/repo.git # Change URL git remote set-url origin git@github.com:user/repo.git # Fetch git fetch # default remote git fetch --all # all remotes git fetch --prune # remove stale remote branches # Pull git pull # fetch + merge (or rebase if configured) git pull --rebase # fetch + rebase # Push git push git push -u origin main # set upstream git push origin --delete feature-branch # delete remote branch git push --tags # push all tags git push origin v1.0 # push specific tag ``` ## Tags ```bash # List git tag git tag -l "v1.*" # Create git tag v1.0 # lightweight git tag -a v1.0 -m "Release 1.0" # annotated (preferred) git tag -a v1.0 abc123 # tag specific commit # Delete git tag -d v1.0 git push origin --delete v1.0 # delete remote tag # Show git show v1.0 ``` ## .gitignore ```gitignore # Patterns *.log # all .log files build/ # directory !important.log # exception (don't ignore this one) **/temp # temp in any subdirectory doc/*.txt # doc/notes.txt but not doc/sub/notes.txt ``` ```bash # Ignore already-tracked file git rm --cached file.txt # untrack without deleting echo "file.txt" >> .gitignore # Debug ignore rules git check-ignore -v path/to/file ``` ## Gotchas - `git pull` without `--rebase` creates merge commits — set `pull.rebase true` globally - `git add .` stages everything including untracked — review with `git status` first - `--amend` rewrites history — never amend commits already pushed to shared branches - `git stash` does not stash untracked files unless `-u` is passed - `-S` (pickaxe) finds where a string was added/removed, not where it appears - `git log -- file` stops at renames — add `--follow` to track across renames - Tags aren't pushed by default — use `--tags` or push individually ## See Also - `git-branching` — branches, merge, rebase, cherry-pick, recovery - [Pro Git book](https://git-scm.com/book/en/v2) - `git help ` — built-in manual pages