git-advanced

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Git 高级操作

Git 高级操作

概述

概述

分支策略、rebase、cherry-pick、hooks 等高级 Git 技能。
分支策略、rebase、cherry-pick、hooks 等高级 Git 技能。

分支管理

分支管理

分支操作

分支操作

bash
undefined
bash
undefined

创建分支

创建分支

git branch feature/new-feature git checkout -b feature/new-feature git switch -c feature/new-feature
git branch feature/new-feature git checkout -b feature/new-feature git switch -c feature/new-feature

切换分支

切换分支

git checkout main git switch main
git checkout main git switch main

删除分支

删除分支

git branch -d feature/merged git branch -D feature/unmerged # 强制删除
git branch -d feature/merged git branch -D feature/unmerged # 强制删除

删除远程分支

删除远程分支

git push origin --delete feature/old
git push origin --delete feature/old

重命名分支

重命名分支

git branch -m old-name new-name
git branch -m old-name new-name

查看分支

查看分支

git branch -a # 所有分支 git branch -v # 带最后提交 git branch --merged # 已合并分支 git branch --no-merged # 未合并分支
undefined
git branch -a # 所有分支 git branch -v # 带最后提交 git branch --merged # 已合并分支 git branch --no-merged # 未合并分支
undefined

分支追踪

分支追踪

bash
undefined
bash
undefined

设置上游分支

设置上游分支

git branch --set-upstream-to=origin/main main git push -u origin feature/new
git branch --set-upstream-to=origin/main main git push -u origin feature/new

查看追踪关系

查看追踪关系

git branch -vv
undefined
git branch -vv
undefined

Rebase 操作

Rebase 操作

基础 rebase

基础 rebase

bash
undefined
bash
undefined

变基到 main

变基到 main

git checkout feature git rebase main
git checkout feature git rebase main

交互式 rebase

交互式 rebase

git rebase -i HEAD~5 git rebase -i main
git rebase -i HEAD~5 git rebase -i main

交互式命令

交互式命令

pick - 保留提交

pick - 保留提交

reword - 修改提交信息

reword - 修改提交信息

edit - 修改提交内容

edit - 修改提交内容

squash - 合并到上一个提交

squash - 合并到上一个提交

fixup - 合并但丢弃提交信息

fixup - 合并但丢弃提交信息

drop - 删除提交

drop - 删除提交

继续/中止 rebase

继续/中止 rebase

git rebase --continue git rebase --abort git rebase --skip
undefined
git rebase --continue git rebase --abort git rebase --skip
undefined

合并提交

合并提交

bash
undefined
bash
undefined

合并最近 3 个提交

合并最近 3 个提交

git rebase -i HEAD~3
git rebase -i HEAD~3

将后两个 pick 改为 squash 或 fixup

将后两个 pick 改为 squash 或 fixup

修改历史提交信息

修改历史提交信息

git rebase -i HEAD~3
git rebase -i HEAD~3

将 pick 改为 reword

将 pick 改为 reword

undefined
undefined

Cherry-pick

Cherry-pick

bash
undefined
bash
undefined

选择单个提交

选择单个提交

git cherry-pick commit-hash
git cherry-pick commit-hash

选择多个提交

选择多个提交

git cherry-pick commit1 commit2 commit3
git cherry-pick commit1 commit2 commit3

选择范围(不包含起始)

选择范围(不包含起始)

git cherry-pick start-commit..end-commit
git cherry-pick start-commit..end-commit

不自动提交

不自动提交

git cherry-pick -n commit-hash
git cherry-pick -n commit-hash

解决冲突后继续

解决冲突后继续

git cherry-pick --continue git cherry-pick --abort
undefined
git cherry-pick --continue git cherry-pick --abort
undefined

Stash 暂存

Stash 暂存

bash
undefined
bash
undefined

暂存修改

暂存修改

git stash git stash push -m "work in progress"
git stash git stash push -m "work in progress"

暂存包括未跟踪文件

暂存包括未跟踪文件

git stash -u git stash --include-untracked
git stash -u git stash --include-untracked

查看暂存列表

查看暂存列表

git stash list
git stash list

恢复暂存

恢复暂存

git stash pop # 恢复并删除 git stash apply # 恢复但保留 git stash apply stash@{2} # 指定暂存
git stash pop # 恢复并删除 git stash apply # 恢复但保留 git stash apply stash@{2} # 指定暂存

查看暂存内容

查看暂存内容

git stash show -p stash@{0}
git stash show -p stash@{0}

删除暂存

删除暂存

git stash drop stash@{0} git stash clear # 清空所有
undefined
git stash drop stash@{0} git stash clear # 清空所有
undefined

撤销操作

撤销操作

撤销工作区修改

撤销工作区修改

bash
undefined
bash
undefined

撤销单个文件

撤销单个文件

git checkout -- file.txt git restore file.txt
git checkout -- file.txt git restore file.txt

撤销所有修改

撤销所有修改

git checkout -- . git restore .
undefined
git checkout -- . git restore .
undefined

撤销暂存区

撤销暂存区

bash
undefined
bash
undefined

取消暂存

取消暂存

git reset HEAD file.txt git restore --staged file.txt
git reset HEAD file.txt git restore --staged file.txt

取消所有暂存

取消所有暂存

git reset HEAD
undefined
git reset HEAD
undefined

撤销提交

撤销提交

bash
undefined
bash
undefined

撤销最后一次提交(保留修改)

撤销最后一次提交(保留修改)

git reset --soft HEAD~1
git reset --soft HEAD~1

撤销最后一次提交(丢弃修改)

撤销最后一次提交(丢弃修改)

git reset --hard HEAD~1
git reset --hard HEAD~1

创建撤销提交

创建撤销提交

git revert commit-hash git revert HEAD
git revert commit-hash git revert HEAD

撤销多个提交

撤销多个提交

git revert HEAD~3..HEAD
undefined
git revert HEAD~3..HEAD
undefined

修改提交

修改提交

bash
undefined
bash
undefined

修改最后一次提交

修改最后一次提交

git commit --amend git commit --amend -m "new message" git commit --amend --no-edit # 不修改信息
git commit --amend git commit --amend -m "new message" git commit --amend --no-edit # 不修改信息

添加遗漏文件

添加遗漏文件

git add forgotten-file git commit --amend --no-edit
undefined
git add forgotten-file git commit --amend --no-edit
undefined

远程操作

远程操作

bash
undefined
bash
undefined

查看远程

查看远程

git remote -v
git remote -v

添加远程

添加远程

git remote add upstream https://github.com/original/repo.git
git remote add upstream https://github.com/original/repo.git

获取远程更新

获取远程更新

git fetch origin git fetch --all
git fetch origin git fetch --all

拉取并变基

拉取并变基

git pull --rebase origin main
git pull --rebase origin main

强制推送(谨慎使用)

强制推送(谨慎使用)

git push --force-with-lease origin feature
undefined
git push --force-with-lease origin feature
undefined

Git Hooks

Git Hooks

常用 hooks

常用 hooks

bash
undefined
bash
undefined

hooks 位置

hooks 位置

.git/hooks/
.git/hooks/

常用 hooks

常用 hooks

pre-commit # 提交前 prepare-commit-msg # 准备提交信息 commit-msg # 提交信息验证 post-commit # 提交后 pre-push # 推送前
undefined
pre-commit # 提交前 prepare-commit-msg # 准备提交信息 commit-msg # 提交信息验证 post-commit # 提交后 pre-push # 推送前
undefined

pre-commit 示例

pre-commit 示例

bash
#!/bin/bash
bash
#!/bin/bash

.git/hooks/pre-commit

.git/hooks/pre-commit

运行 lint

运行 lint

npm run lint if [ $? -ne 0 ]; then echo "Lint failed. Commit aborted." exit 1 fi
npm run lint if [ $? -ne 0 ]; then echo "Lint failed. Commit aborted." exit 1 fi

运行测试

运行测试

npm test if [ $? -ne 0 ]; then echo "Tests failed. Commit aborted." exit 1 fi
exit 0
undefined
npm test if [ $? -ne 0 ]; then echo "Tests failed. Commit aborted." exit 1 fi
exit 0
undefined

commit-msg 示例

commit-msg 示例

bash
#!/bin/bash
bash
#!/bin/bash

.git/hooks/commit-msg

.git/hooks/commit-msg

commit_msg=$(cat "$1")
commit_msg=$(cat "$1")

检查提交信息格式

检查提交信息格式

if ! echo "$commit_msg" | grep -qE "^(feat|fix|docs|style|refactor|test|chore)((.+))?: .{1,50}"; then echo "Invalid commit message format." echo "Format: type(scope): message" exit 1 fi
exit 0
undefined
if ! echo "$commit_msg" | grep -qE "^(feat|fix|docs|style|refactor|test|chore)((.+))?: .{1,50}"; then echo "Invalid commit message format." echo "Format: type(scope): message" exit 1 fi
exit 0
undefined

常见场景

常见场景

场景 1:同步 fork 仓库

场景 1:同步 fork 仓库

bash
undefined
bash
undefined

添加上游仓库

添加上游仓库

git remote add upstream https://github.com/original/repo.git
git remote add upstream https://github.com/original/repo.git

获取上游更新

获取上游更新

git fetch upstream
git fetch upstream

合并到本地

合并到本地

git checkout main git merge upstream/main
git checkout main git merge upstream/main

推送到 fork

推送到 fork

git push origin main
undefined
git push origin main
undefined

场景 2:清理历史中的大文件

场景 2:清理历史中的大文件

bash
undefined
bash
undefined

使用 git-filter-repo(推荐)

使用 git-filter-repo(推荐)

git filter-repo --path large-file.zip --invert-paths
git filter-repo --path large-file.zip --invert-paths

或使用 BFG

或使用 BFG

bfg --delete-files large-file.zip git reflog expire --expire=now --all git gc --prune=now --aggressive
undefined
bfg --delete-files large-file.zip git reflog expire --expire=now --all git gc --prune=now --aggressive
undefined

场景 3:二分查找 bug

场景 3:二分查找 bug

bash
undefined
bash
undefined

开始二分

开始二分

git bisect start
git bisect start

标记当前为坏

标记当前为坏

git bisect bad
git bisect bad

标记已知好的提交

标记已知好的提交

git bisect good v1.0.0
git bisect good v1.0.0

Git 会自动切换到中间提交

Git 会自动切换到中间提交

测试后标记

测试后标记

git bisect good # 或 git bisect bad
git bisect good # 或 git bisect bad

找到后重置

找到后重置

git bisect reset
undefined
git bisect reset
undefined

场景 4:子模块管理

场景 4:子模块管理

bash
undefined
bash
undefined

添加子模块

添加子模块

git submodule add https://github.com/user/repo.git path/to/submodule
git submodule add https://github.com/user/repo.git path/to/submodule

初始化子模块

初始化子模块

git submodule init git submodule update
git submodule init git submodule update

克隆时包含子模块

克隆时包含子模块

git clone --recursive https://github.com/user/repo.git
git clone --recursive https://github.com/user/repo.git

更新子模块

更新子模块

git submodule update --remote
undefined
git submodule update --remote
undefined

故障排查

故障排查

问题解决方法
合并冲突手动解决后
git add
+
git commit
rebase 冲突解决后
git rebase --continue
误删分支
git reflog
找回
推送被拒绝
git pull --rebase
后重试
bash
undefined
问题解决方法
合并冲突手动解决后
git add
+
git commit
rebase 冲突解决后
git rebase --continue
误删分支
git reflog
找回
推送被拒绝
git pull --rebase
后重试
bash
undefined

查看操作历史

查看操作历史

git reflog
git reflog

恢复误删的提交

恢复误删的提交

git checkout -b recovery commit-hash
undefined
git checkout -b recovery commit-hash
undefined