git pull 是什么
git pull 是把远端更新取回本地并立即集成的组合命令,等价于先 git fetch 再执行 merge 或 rebase。它的便利在于一条命令完成同步,代价是集成方式被配置隐式决定,出问题时不容易分辨到底是「取回」还是「合并」哪一步造成的。
集成方式从哪来
pull 用合并还是变基,取决于配置与参数:pull.rebase 决定默认行为,命令行可用 --rebase 或 --no-rebase 覆盖,--ff-only 则要求只允许快进,无法快进就直接失败。团队里如果没人统一过这个配置,同一条 pull 在不同人机器上会产生不同的历史形态。
基本信息
| 适用平台 | Linux / macOS / Windows(Git 2.x) |
|---|---|
| 语法 | git pull [选项] [远端] [分支] |
| 等价动作 | git fetch 加上 merge 或 rebase |
| 关键参数 | --ff-only;--rebase;--no-rebase;--autostash |
| 相关配置 | pull.rebase 决定默认集成方式 |
| 前置要求 | 工作区改动不能与拉取内容冲突 |
典型使用场景
- 日常同步:在主干分支上拉取团队最新提交
- 谨慎推进:用 --ff-only 只接受快进,拒绝意外合并
- 保持线性:个人分支上用 --rebase 把本地提交叠到最新上游之上
- 带现场的同步:用 --autostash 临时收藏本地改动再拉取
- 排查前先看清:先 fetch 再看区间日志,确认要集成什么
- 脚本化:CI 中显式指定远端与分支,不依赖默认上游
常用示例
常用示例
git pull # 按配置决定是合并还是变基
git pull --ff-only # 只允许快进,否则直接失败
git pull --rebase # 把本地提交叠到最新远端之上
git pull --autostash # 先自动收藏本地改动再拉取
git fetch origin && git log --oneline HEAD..origin/main # 看清再决定
git pull origin main # 显式指定远端与分支几种集成方式
| 方式 | 历史形态 | 适用场景 |
|---|---|---|
| 默认 merge | 可能生成合并提交 | 主干分支、团队未统一约定时 |
| --rebase | 线性,没有多余合并提交 | 个人分支跟进上游 |
| --ff-only | 只能快进,否则失败 | 要求线性且不接受自动合并 |
| --no-rebase | 等价于临时改用 merge | 想覆盖全局配置的一次操作 |
| --autostash | 先收藏再恢复本地改动 | 改动零碎但不想先提交 |
| --allow-unrelated | 允许无共同祖先的合并 | 谨慎使用,先确认来源 |
工作区有未提交改动时,pull 可能被拒绝,也可能把改动卷进冲突现场。稳妥做法是先提交,或先 git stash 保存现场再拉取。
想看清上游到底多了什么,先 git fetch,再用 git log --oneline HEAD..origin/main 查看区间,确认之后才决定集成方式,比直接 pull 可控得多。
团队里 pull.rebase 设置不一致会产出不同的历史形态。要么在贡献指南里统一,要么在关键分支上改用 fetch 加显式集成。
--ff-only 失败说明本地已经分叉。这时不要反复拉取,应先判断本地那些提交是要保留、要变基还是可以丢弃,再决定集成方式。
和 fetch 的分工
fetch 只更新远端跟踪引用,是纯粹的网络取回,不碰你的分支;pull 在取回之后立刻集成,会改动当前分支。需要先判断「上游多了什么」再决定时用 fetch;已经明确要同步、且工作区干净时用 pull。养成先 fetch 再决定的习惯,能免去在隐式合并出来的历史里找原因。
fetch 与 pull 对照
| 命令 | 作用 | 影响范围 |
|---|---|---|
| git fetch | 只更新远端跟踪引用 | 不动本地分支与工作区 |
| git pull | 取回并立即集成 | 会生成合并提交或触发变基 |
拉取过程中发生冲突时,仓库会停在集成状态。解决完冲突按提示提交即可;想整体放弃,用 git merge --abort 或 git rebase --abort 回到拉取之前,不要手工删文件了事。中途卡住又拿不准,先 git status 看首行提示再决定。