git-advanced
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGit Advanced
Git 高级用法
Worktrees
Worktrees
bash
undefinedbash
undefinedCreate a worktree for a feature branch (avoids stashing)
Create a worktree for a feature branch (avoids stashing)
git worktree add ../feature-auth feature/auth
git worktree add ../feature-auth feature/auth
Create a worktree with a new branch
Create a worktree with a new branch
git worktree add ../hotfix-123 -b hotfix/123 origin/main
git worktree add ../hotfix-123 -b hotfix/123 origin/main
List all worktrees
List all worktrees
git worktree list
git worktree list
Remove a worktree after merging
Remove a worktree after merging
git worktree remove ../feature-auth
Worktrees let you work on multiple branches simultaneously without stashing or committing WIP. Each worktree has its own working directory but shares the same `.git` repository.git worktree remove ../feature-auth
Worktrees 允许你同时处理多个分支,无需执行暂存(stash)或提交未完成工作(WIP)的操作。每个工作树都有独立的工作目录,但共享同一个 `.git` 仓库。Bisect
Bisect
bash
undefinedbash
undefinedStart bisect, mark current as bad and known good commit
Start bisect, mark current as bad and known good commit
git bisect start
git bisect bad HEAD
git bisect good v1.5.0
git bisect start
git bisect bad HEAD
git bisect good v1.5.0
Git checks out a midpoint commit. Test it, then mark:
Git checks out a midpoint commit. Test it, then mark:
git bisect good # if this commit works
git bisect bad # if this commit is broken
git bisect good # if this commit works
git bisect bad # if this commit is broken
Automate with a test script
Automate with a test script
git bisect start HEAD v1.5.0
git bisect run npm test
git bisect start HEAD v1.5.0
git bisect run npm test
When done, reset
When done, reset
git bisect reset
Bisect performs binary search across commits to find which commit introduced a bug. Automated bisect with `run` is the fastest approach.git bisect reset
Bisect 会在提交记录中执行二分查找,帮你定位是哪次提交引入了 Bug。搭配 `run` 参数实现自动化 Bisect 是最快的排查方式。Interactive Rebase
Interactive Rebase
bash
undefinedbash
undefinedRebase last 5 commits interactively
Rebase last 5 commits interactively
git rebase -i HEAD~5
git rebase -i HEAD~5
Common operations in the editor:
Common operations in the editor:
pick - keep commit as-is
pick - keep commit as-is
reword - change commit message
reword - change commit message
edit - stop to amend the commit
edit - stop to amend the commit
squash - merge into previous commit, keep both messages
squash - merge into previous commit, keep both messages
fixup - merge into previous commit, discard this message
fixup - merge into previous commit, discard this message
drop - remove the commit entirely
drop - remove the commit entirely
Rebase feature branch onto latest main
Rebase feature branch onto latest main
git fetch origin
git rebase origin/main
git fetch origin
git rebase origin/main
Continue after resolving conflicts
Continue after resolving conflicts
git rebase --continue
git rebase --continue
Abort if things go wrong
Abort if things go wrong
git rebase --abort
undefinedgit rebase --abort
undefinedGit Hooks
Git Hooks
bash
#!/bin/shbash
#!/bin/sh.git/hooks/pre-commit
.git/hooks/pre-commit
Run linter on staged files only
Run linter on staged files only
STAGED_FILES=$(git diff --cached --name-only --diff-filter=d | grep -E '.(ts|tsx|js|jsx)$')
if [ -n "$STAGED_FILES" ]; then
npx eslint $STAGED_FILES --fix
git add $STAGED_FILES
fi
```bash
#!/bin/shSTAGED_FILES=$(git diff --cached --name-only --diff-filter=d | grep -E '.(ts|tsx|js|jsx)$')
if [ -n "$STAGED_FILES" ]; then
npx eslint $STAGED_FILES --fix
git add $STAGED_FILES
fi
```bash
#!/bin/sh.git/hooks/commit-msg
.git/hooks/commit-msg
Enforce conventional commit format
Enforce conventional commit format
COMMIT_MSG=$(cat "$1")
PATTERN="^(feat|fix|docs|style|refactor|test|chore)((.+))?: .{1,72}$"
if ! echo "$COMMIT_MSG" | head -1 | grep -qE "$PATTERN"; then
echo "Error: Commit message must follow Conventional Commits format"
echo "Example: feat(auth): add OAuth2 login flow"
exit 1
fi
```bash
#!/bin/shCOMMIT_MSG=$(cat "$1")
PATTERN="^(feat|fix|docs|style|refactor|test|chore)((.+))?: .{1,72}$"
if ! echo "$COMMIT_MSG" | head -1 | grep -qE "$PATTERN"; then
echo "Error: Commit message must follow Conventional Commits format"
echo "Example: feat(auth): add OAuth2 login flow"
exit 1
fi
```bash
#!/bin/sh.git/hooks/pre-push
.git/hooks/pre-push
Run tests before pushing
Run tests before pushing
npm test
if [ $? -ne 0 ]; then
echo "Tests failed. Push aborted."
exit 1
fi
undefinednpm test
if [ $? -ne 0 ]; then
echo "Tests failed. Push aborted."
exit 1
fi
undefinedRecovery Techniques
恢复技巧
bash
undefinedbash
undefinedUndo last commit but keep changes staged
Undo last commit but keep changes staged
git reset --soft HEAD~1
git reset --soft HEAD~1
Recover a deleted branch using reflog
Recover a deleted branch using reflog
git reflog
git checkout -b recovered-branch HEAD@{3}
git reflog
git checkout -b recovered-branch HEAD@{3}
Recover a file from a specific commit
Recover a file from a specific commit
git checkout abc1234 -- path/to/file.ts
git checkout abc1234 -- path/to/file.ts
Find lost commits (dangling after reset or rebase)
Find lost commits (dangling after reset or rebase)
git fsck --lost-found
git show <dangling-commit-sha>
git fsck --lost-found
git show <dangling-commit-sha>
Undo a rebase
Undo a rebase
git reflog
git reset --hard HEAD@{5} # point before rebase started
undefinedgit reflog
git reset --hard HEAD@{5} # point before rebase started
undefinedUseful Aliases
实用别名
bash
undefinedbash
undefined~/.gitconfig
~/.gitconfig
[alias]
lg = log --graph --oneline --decorate --all
st = status -sb
co = checkout
unstage = reset HEAD --
last = log -1 HEAD --stat
branches = branch -a --sort=-committerdate
stash-all = stash push --include-untracked
conflicts = diff --name-only --diff-filter=U
undefined[alias]
lg = log --graph --oneline --decorate --all
st = status -sb
co = checkout
unstage = reset HEAD --
last = log -1 HEAD --stat
branches = branch -a --sort=-committerdate
stash-all = stash push --include-untracked
conflicts = diff --name-only --diff-filter=U
undefinedAnti-Patterns
反模式
- Force-pushing to shared branches without
--force-with-lease - Rebasing commits that have already been pushed and shared
- Committing large binary files without Git LFS
- Using without reviewing
git add .git diff --staged - Not using for build artifacts, dependencies, and secrets
.gitignore - Keeping long-lived feature branches instead of merging frequently
- 未添加 参数就向共享分支执行强制推送
--force-with-lease - 对已经推送并共享的提交执行变基操作
- 不使用 Git LFS 就提交大型二进制文件
- 未先检查 就直接使用
git diff --stagedgit add . - 未配置 忽略构建产物、依赖和敏感信息
.gitignore - 维护生命周期过长的功能分支,而非频繁合并
Checklist
检查清单
- Worktrees used for parallel branch work instead of stashing
- automates bug-finding with a test command
git bisect run - Interactive rebase cleans up commits before merging to main
- Pre-commit hooks run linting on staged files
- Commit message format enforced via commit-msg hook
- used instead of
--force-with-leasewhen force-pushing--force - Reflog consulted before any destructive operation
- covers build outputs, dependencies, and environment files
.gitignore
- 使用 Worktrees 处理并行分支工作,而非使用暂存
- 使用 搭配测试命令自动化查找引入 Bug 的提交
git bisect run - 合并到主分支前使用交互式变基清理提交记录
- 预提交钩子会对暂存文件执行代码检查
- 通过 commit-msg 钩子强制规范提交信息格式
- 强制推送时使用 替代
--force-with-lease--force - 执行任何破坏性操作前先查看 reflog 记录
- 覆盖了构建输出、依赖和环境变量文件
.gitignore