Two reference files covering: - git.md — config, daily workflow, diff, log, stash, remotes, tags - git-branching.md — branches, merge, rebase, cherry-pick, bisect, reflog, reset, revert, worktrees
259 lines
6.5 KiB
Markdown
259 lines
6.5 KiB
Markdown
# 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 <command>` — built-in manual pages
|