Git 进阶
当团队协作或长期维护分支时,只靠 add/commit/push 不够,需要更精细的历史改写与恢复手段。
rebase 与 merge
merge 把两个分支的最新提交以及它们的共同祖先进行三方合并,生成一个合并提交;rebase 把当前分支的提交「重放」到目标分支顶端,使历史呈线性。
git merge feature # 合并,保留分支拓扑
git rebase main # 将当前分支变基到 main
git rebase -i HEAD~3 # 交互式变基,改写、合并、删除提交
建议:未推送的本地提交用 rebase 整理,已推送的公共分支用 merge,避免对他人历史造成影响。
cherry-pick 与 stash
git cherry-pick <commit> # 挑选某个提交应用到当前分支
git cherry-pick <c1>..<c2> # 一次性应用一段提交
git stash 把当前未提交的修改暂存起来,工作区回到干净状态:
git stash push -m "wip"
git stash list
git stash pop # 恢复并删除
git stash apply stash@{0} # 恢复但保留
reset、revert 与 reflog
reset 改写 HEAD 指针,会改写历史;revert 创建一个新提交来撤销指定提交,不改写历史,适合公共分支。
git reset --soft HEAD~1 # 撤销提交,改动保留在暂存区
git reset --mixed HEAD~1 # 默认,撤销提交与暂存,改动留在工作区
git reset --hard HEAD~1 # 丢弃一切
git revert <commit> # 生成反向提交
reflog 记录 HEAD 的每次移动,几乎可以恢复任何「丢失」的提交:
git reflog
git reset --hard <reflog-id>
标签与子模块
git tag v1.0.0 # 轻量标签
git tag -a v1.0.0 -m "release" # 附注标签
git push origin --tags
子模块用于引入外部依赖仓库:
git submodule add <url> path/
git submodule update --init --recursive