第 2 卷
◦ git merge:提交历史是非线性的,会保留分支的分叉记录(可清晰看到何时创建分支、何
时合并分支);
◦ git rebase:提交历史是线性的,会“抹平”分支分叉,看起来当前分支是在目标分支最
新版本后直接开发的(重写了提交的父节点)。
- 使用场景差异
◦ git merge:适合**公共分支(如master/main、develop)**的合并,保留完整的分支历
史,便于追溯和回滚(不破坏公共提交历史);
◦ git rebase:适合**个人分支/功能分支(如feature/*)**整合公共分支更新,或在合并到
公共分支前整理提交历史(使公共分支历史更整洁);禁止在公共分支上使用rebase(会重写公共提交历史,导致其他开发者协作异常)。
- 示例对比
- 合并(merge):分支A → 合并分支B → 生成新合并提交C(A和B的历史均保留);
◦ 变基(rebase):分支A → 基于分支B最新版本变基 → 分支A的提交依次排在B最新提交之后
(无新合并提交)。
五、git pull 与 git fetch 的区别
git pull 和 git fetch 均用于获取远程仓库的最新版本,但核心差异在于是否自动合并,具体区别如下:
- 核心行为差异(关键区别)
◦ git fetch:仅拉取,不合并。将远程仓库的最新提交、分支信息拉取到本地的远程跟踪分
支(如 origin/main),本地当前工作分支(如 main)不会发生任何变化,开发者可先对比差异再手动合并;
◦ git pull:拉取 + 自动合并。 git pull 本质上是 git fetch + git merge(默
认)的组合操作:先拉取远程最新版本到本地远程跟踪分支,再自动将远程跟踪分支的更新合并到本地当前工作分支。
- 安全性与灵活性差异
◦ git fetch:更安全、更灵活。由于不自动合并,开发者可以通过 git diff <本地分支
> <远程跟踪分支>(如 git diff main origin/main)查看远程更新与本地分支的差异,自主决定是否合并、如何合并,避免自动合并导致的意外冲突;
◦ git pull:更便捷,但灵活性低、风险略高。适合本地分支无未提交修改、且确认远程更新
不会与本地冲突的场景;若本地有未提交修改,或远程更新与本地修改冲突,会直接触发合并冲突,增加解决成本。
- git fetch:适合谨慎的开发流程(如公共分支同步、先验证差异再合并);
◦ git pull:适合个人开发分支快速同步远程更新(如个人feature分支拉取远程develop分
支的最新代码)。
六、Git钩子(hook)的定义与用途
- Git钩子(hook)的定义
Git钩子是嵌入在Git工作流程中的自动化脚本(Shell、Python、Node.js等语言编写),存储在本地仓库的 .git/hooks 目录下(默认包含多个示例脚本,后缀为 .sample,移除后缀即可启用)。
Git钩子由特定的Git事件触发,无需手动执行,是Git提供的内置自动化扩展机制。
- Git钩子的核心用途
钩子按触发时机可分为“客户端钩子”(本地操作触发)和“服务器端钩子”(远程仓库操作触发),各自用途如下:
◦ 客户端钩子(常用)
- 提交前钩子( pre-commit):提交前触发,用于校验本地代码(如代码格式检查、语法
校验、是否存在调试代码、文件大小限制等),若脚本返回非0值,Git会阻止本次提交;
- 提交信息校验钩子( commit-msg):提交时触发,用于校验提交说明的格式(如是否符
合“类型: 描述”的规范,是否长度达标等),不符合规范则阻止提交;
- 合并前钩子( pre-merge-commit):合并操作前触发,用于校验合并的合法性,避免
无效合并。
◦ 服务器端钩子(常用)
- 推送前钩子( pre-receive):远程仓库接收推送时触发,用于校验推送的提交(如是
否包含敏感信息、提交者是否有权限、代码是否通过CI校验等),不符合规则则拒绝接收推送;
- 接收后钩子( post-receive):远程仓库成功接收推送后触发,用于执行后续自动化操
作(如自动部署项目、发送推送通知、同步到其他仓库、触发CI/CD流水线等)。
七、撤销Git最后一次提交的方法
根据“是否保留最后一次提交的修改”,有两种常用方案,适用于本地未推送远程的场景(若已推送远程,不建议直接撤销,避免破坏公共历史):
- 方案1:保留修改(仅撤销提交记录,修改保留在工作区/暂存区)
适用于提交说明写错、或遗漏部分文件需要补充提交的场景,有两种细分命令:
◦ 保留修改在暂存区(可直接重新commit):
◦ 保留修改在工作区(需重新add再commit):
Code block
1git reset --mixed HEAD~1# --mixed是默认参数,可省略,即 git reset HEAD~1
- 方案2:丢弃修改(彻底撤销最后一次提交,删除所有变更)
适用于最后一次提交存在严重错误,需要完全丢弃的场景(谨慎使用,不可恢复):
Code block
1git reset --hard HEAD~1
- 补充:已推送远程的最后一次提交撤销(不推荐,特殊场景使用)
若已将最后一次提交推送到远程公共分支,不可使用 git reset(会重写公共历史),可使用 git revert 创建一个“反向提交”,抵消最后一次提交的修改:
Code block
| 1 | git revert HEAD | #撤销最后一次提交,生成新的提交记录 |
|---|---|---|
| 2 | git push origin <分支名> | #将反向提交推送到远程 |
八、Git大型仓库的性能优化方法
大型仓库(文件数量多、历史提交久、体积大)容易出现 git clone、 git status、 git log 等操作缓慢的问题,优化方案如下:
- 克隆优化:减少本地仓库体积
◦ 浅克隆(Shallow Clone):仅克隆最近的N次提交,不下载完整历史,大幅减少克隆时间和磁
盘占用:
Code block
1git clone --depth <N> <远程仓库地址># N为提交次数,如 --depth 1 仅克隆最新一次提交
◦ 单分支克隆:仅克隆指定分支,不下载其他无关分支:
全站分卷索引 · 3 卷
- 1第 1 卷
- Git 中 Pull、Fetch、Merge 和 Rebase 的差异
- 解析
- 一、Git与SVN的本质区别
- ◦ Git:分布式版本控制系统(DVCS)。每个开发者本地都会完整克隆整个仓库的所有版本历
- ◦ SVN:集中式版本控制系统(CVCS)。所有版本历史、分支信息都存储在唯一的中央服务器
- ◦ 离线工作能力:Git支持完全离线工作(本地提交、版本对比等),SVN无网络无法进行版本相
- ◦ 分支/标签效率:Git的分支/标签是轻量级的(仅指向特定提交的指针),创建、切换、合并几
- ◦ 数据安全性:Git本地仓库完整备份,单个仓库损坏可通过其他开发者的本地仓库恢复;SVN中
- 二、开发中常用的Git命令
- ◦ git status:查看工作区、暂存区的文件状态(哪些文件未跟踪、已修改未暂存、已暂存
- ◦ git commit --amend:修改最近一次提交的说明(或补充暂存区的修改到最近一次提
- ◦ git checkout -- <文件名>:撤销工作区中该文件的未暂存修改(恢复到暂存区或最近
- 2第 2 卷
- ◦ git merge:提交历史是非线性的,会保留分支的分叉记录(可清晰看到何时创建分支、何
- ◦ git rebase:提交历史是线性的,会“抹平”分支分叉,看起来当前分支是在目标分支最
- ◦ git merge:适合**公共分支(如master/main、develop)**的合并,保留完整的分支历
- ◦ git rebase:适合**个人分支/功能分支(如feature/*)**整合公共分支更新,或在合并到
- ◦ 变基(rebase):分支A → 基于分支B最新版本变基 → 分支A的提交依次排在B最新提交之后
- 五、git pull 与 git fetch 的区别
- ◦ git fetch:仅拉取,不合并。将远程仓库的最新提交、分支信息拉取到本地的远程跟踪分
- ◦ git pull:拉取 + 自动合并。 git pull 本质上是 git fetch + git merge(默
- ◦ git fetch:更安全、更灵活。由于不自动合并,开发者可以通过 git diff <本地分支
- ◦ git pull:更便捷,但灵活性低、风险略高。适合本地分支无未提交修改、且确认远程更新
- ◦ git pull:适合个人开发分支快速同步远程更新(如个人feature分支拉取远程develop分
- 六、Git钩子(hook)的定义与用途
- 3第 3 卷
- ◦ 开启压缩:提升网络传输效率(默认开启,可确认配置):
- ◦ 关闭文件索引统计:对于海量文件仓库,关闭 git status 时的文件统计,提升速度:
- ◦ 增大缓存:调整Git的内存缓存大小,减少磁盘IO:
- ◦ 使用Git子模块(git submodule):将大型仓库拆分为多个独立子仓库,主仓库仅引用子仓库
- ◦ 使用Git LFS(Large File Storage):专门管理大文件(如图片、视频、二进制包等),不将大
- ◦ 清理无用数据:定期清理悬空提交、过期分支、大文件历史等,缩小仓库体积:
- ◦ 避免频繁操作全量历史:使用 git log --oneline --no-merges 等简洁命令查看历
- ◦ 使用稀疏检出(Sparse Checkout):仅检出工作区需要的目录,不下载所有文件,适用于仅
- 九、Git内部工作原理与文件变化跟踪机制
- ◦ Blob对象(二进制大对象):用于存储文件的内容数据,不包含文件名和目录结构,仅通过内
- ◦ Tree对象:用于描述目录结构,存储了目录下的文件名、对应Blob对象/子Tree对象的哈希值,
- ◦ Commit对象:用于记录一次提交的完整信息,包括:指向当前版本Tree对象的哈希值(对应