今天使用git pull拉取远程分支报错了:

1
2
3
4
5
6
7
8
9
10
11
12
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.

问题是这样的出现的:

  1. 开发分支远程有新的提交
  2. 我在相同分支commit了改动
  3. git pull

报错解释:
当你在仓库里执行 git pull 时,Git 发现 本地分支 和 远程分支 已经各自向前走了不同的提交轨迹——也就是说,这两条分支“分叉”(diverge)了。此时它不知道你更想采用哪种方式把两条轨迹合并到一起,于是给出提示,要求你明确告诉 Git 该怎么“调和”

如果验证分支出现分叉了呢?
可以跑一条命令即可印证是否分叉:

1
2
git fetch origin
git log --oneline --left-right --graph origin/develop...HEAD

只要左边(←)和右边(→)同时出现提交,即代表两端各自拥有独有提交——必然触发该提示。

Git提供了三种方式调和:

方案 作用机制 典型命令 结果在提交历史中的表现 适用场景
Merge 在本地留下一个新的 merge commit,把远程分支的头指针和当前分支指针共同作为父节点 git pull --no-rebasegit config pull.rebase false 出现一个“Y”字形合并结点,能完整保留两条原始轨迹 团队协作时需要保留真实历史、分支少且对线形历史不敏感
Rebase 先把远程分支的最新提交放到本地,再把你自己的提交“挪”到它们后面,仿佛你的工作是接在远程之后做的一样 git pull --rebasegit config pull.rebase true 历史保持单线;你的那几条提交会换一个新的 SHA 个人分支、希望历史更整洁,或多人协作但大家习惯 rebase
Fast-forward only 只允许“快进”——即要求本地没有任何额外提交,远程分支指针直接向前移动到本地 git pull --ff-onlygit config pull.ff only 绝对线性,没有合并结点 仓库策略强制线性历史;持续集成流水线经常使用

最常见的解决步骤:

  1. 选择策略——先和团队达成共识:

    • 想保留所有分叉历史:用 merge。
    • 想把历史整理成一条直线:用 rebase。
    • 强制无冲突、无分叉:用 ff-only(通常需要先 git pull --rebasegit merge 把分叉解决完再推送)。
  2. 一次性指定(推荐逐仓库设置,避免全局冲突):

    1
    2
    3
    4
    5
    6
    # 选 merge
    git config pull.rebase false
    # 选 rebase
    git config pull.rebase true
    # 选 fast-forward only
    git config pull.ff only
  3. 临时覆盖:在偶尔需要用另一种策略时,直接在命令行追加 --rebase / --no-rebase / --ff-only 即可。

  4. 解决冲突(如有):无论 merge 还是 rebase,如碰到冲突都要手动改文件、git add,然后

    • 如果是 merge:git commit 完成合并。
    • 如果是 rebase:git rebase --continue 继续挪动剩余提交。

小贴士:如果你正在 rebase 过程中后悔了,可以随时 git rebase --abort 回到操作前的状态。

😎