1 问题背景
如果你也在使用2.27.0及以上版本的Git时,使用git pull
命令出现以下的警告文案,可以通过阅读本篇文章来解决此问题。
博主最近在Android Studio上使用git pull
命令时,每次Android Studio都会弹出下述的警告文案:
warning: Pulling without specifying how to reconcile divergent branches is discouraged. You can squelch this message by running one of the following commands sometime before your next pull:
git config pull.rebase false # merge (the default strategy)
git config pull.rebase true # rebase
git config pull.ff only # fast-forward only
You can replace "git config" with "git config --global" to set a default preference for all repositories. You can also pass --rebase, --no-rebase, or --ff-only on the command line to override the configured default per invocation.
该警告的中文版本文案描述如下:
warning: 不建议在没有为偏离分支指定合并策略时执行pull操作。
您可以在执行下一次pull操作之前执行下面一条命令来抑制本消息:
git config pull.rebase false # 合并(缺省策略)
git config pull.rebase true # 变基
git config pull.ff only # 仅快进
您可以将 "git config" 替换为 "git config --global" 以便为所有仓库设置
缺省的配置项。您也可以在每次执行 pull 命令时添加 --rebase、--no-rebase,
或者 --ff-only 参数覆盖缺省设置。
当博主看到上述的警告信息后很懵,于是在百度和Google上都查询了相关的问题解释和解决方案,但都没有详细的论证证据和说服力,于是楼主自己前往了Git官方参考文档中查询了相关知识点,终于理清了这个问题,现在把问题产生的原因、解决方案分享给大家。
2 理解问题
2.1 理解问题的文案描述
我们在上述的警告文案描述中可以发现两个重要的Git配置信息pull.rebase
和pull.ff
。
先来了解一下pull.ff
。
在《Git官方文档-参考-pull.ff》文章中可以查看到它的定义:
当把
pull.ff
设置为false时,这个变量告诉Git在这种情况下,如果执行不带选项的git pull
命令时先尝试快进合并,如果不行再进行正常合并生成一个新的提交。
当把
pull.ff
设置为only时,只允许快进合并(相当于执行命令git pull --ff-only
),如果执行不带选项的git pull
命令时,如果不能进行快进合并则终止当前操作。
如果将
pull.ff
设置为only,而执行不带选项的git pull
命令被终止,其实可以使用带参数的git pull --no-ff
或者git pull --rebase
命令来执行pull操作。
接着在《Git官方文档-参考-pull.base》文章中可查看pull.rebase
的定义,但是官网的定义过于复杂,因此此处只解释当选项pull.rebase
的参数为true
或者false
时的定义:
当
pull.rebase
为true时,运行不带选项的命令git pull
相当于执行git pull --rebase
。
当
pull.rebase
为false时,运行不带选项的命令git pull
不会被改变含义,即不会变基。如果想变基,需要在执行命令时显式地加上选项--rebase
,即git pull --rebase
。
2.2 理解git pull
命令的原理及其各选项的含义
2.2.1 git pull
命令的原理
git fetch
会查询git remote
中所有的远程仓库所包含分支的最新提交,并将其记录到.git/FETCH_HEAD
文件中。
.git/FETCH_HEAD
是一个版本链接,指向着目前已经从远程仓库取下来的所有分支的最新提交。
git pull
命令等价于:先执行git fetch
,再执行git merge FETCH_HEAD
将远程仓库对应分支的最新提交合并到当前本地分支中。
2.2.2 git pull
命令中各选项的含义
其中git pull
有这几项常见的选项搭配:
- 不带任何选项的
git pull
命令:先尝试快进合并,如果不行再进行正常合并生成一个新的提交。 git pull --ff-only
命令:只尝试快进合并,如果不行则终止当前合并操作。git pull --no-ff
命令:禁止快进合并,即不管能不能快进合并,最后都会进行正常合并生成一个新的提交。git pull --rebase
命令:先尝试快进合并,如果不行再进行变基合并。
2.3 理解git pull
命令出现问题的原因
现在,看完上述的问题的文案描述、git pull
命令的原理及其各选项的含义后,现在我们清楚为什么git pull
命令出现该警告文案的原因了:
执行不带任何选项的
git pull
命令时,会产生三种歧义:git pull --ff-only
、git pull --no-ff
、git pull --rebase
,而这三种pull方式的合并策略差异很大,即对整个分布式项目的版本管理有很大的影响作用。
而我们执行不带任何选项的
git pull
命令时,Git就不知道我们到底想用哪种合并策略来执行git pull
,因此Git会给出上述的警告文案,建议我们通过git config
命令指定不带选项的git pull
命令应该按照这三种合并策略的哪种来执行。
3 解决问题
现在我们再次回顾一下上述执行不带选项的git pull
命令提示的警告文案:
warning: 不建议在没有为偏离分支指定合并策略时执行pull操作。
您可以在执行下一次pull操作之前执行下面一条命令来抑制本消息:
git config pull.rebase false # 合并(缺省策略)
git config pull.rebase true # 变基
git config pull.ff only # 仅快进
您可以将 "git config" 替换为 "git config --global" 以便为所有仓库设置
缺省的配置项。您也可以在每次执行 pull 命令时添加 --rebase、--no-rebase,
或者 --ff-only 参数覆盖缺省设置。
首先理解什么是偏离分支
:
当本地的分支落后于远程分支时,本地分支又自行修改项目文件生成了新的提交,这时本地分支再执行
git pull
命令就不能快进合并,并且还容易发生冲突。这时的本地分支便称为偏离分支,因为这时的本地分支的最新提交跟远程分支的最新提交不同,产生了偏离。
接着理解什么是合并策略
:
合并策略便是
git merge --ff-only
、git merge --no-ff
、git merge --rebase
这三种常见的合并策略,分别代表着快进合并、非快进普通合并、变基合并。
而我们执行不带任何选项的git pull
命令时,Git就不知道我们到底想用哪种合并策略来执行git pull
,因此Git会给出上述的警告文案,建议我们通过git config
命令应该按照这三种合并策略的哪种来执行。
通过上述的文章讲解,现在我们理解了为什么理解git pull
命令出现问题的原因,因此只要我们在Git中配置选项pull.rebase
或pull.ff
的参数即可。配置后,即便我们再执行不带任何选项的git pull
命令,也不会再出现上述的警告文案啦。
3.1 如何配置选项pull.rebase
或pull.ff
的参数
博主已经在本文的《2.1 理解问题的文案描述》章节中将选项pull.rebase
和pull.ff
的参数的所有情况进行了一一介绍,因此具体怎么配置按照你使用Git的个人喜好即可。
例如博主喜欢在git pull
时只接受快进合并和变基合并,那么博主可以执行git config pull.ff only
,保证每次执行不带选项的git pull
时要么快进合并成功,要么快进合并失败。如果快进合并失败,博主再显式执行git pull --rebase
进行变基合并即可。
3.1.1 选项pull.rebase
或pull.ff
各个参数的含义
《Git官方文档-参考-pull.ff》文章中对选项pull.ff
各个参数的定义:
当把
pull.ff
设置为false时,这个变量告诉Git在这种情况下,如果执行不带选项的git pull
命令时先尝试快进合并,不行再创建一个合并后新的提交。
当把
pull.ff
设置为only时,只允许快进合并(相当于执行命令git pull --ff-only
),如果执行不带选项的git pull
命令时,不能进行快进合并则终止当前操作。
如果将
pull.ff
设置为only,而执行不带选项的git pull
命令被终止,其实可以使用带参数的git pull --no-ff
或者git pull --rebase
命令来执行pull操作。
《Git官方文档-参考-pull.base》文章中pull.rebase
的各个参数的定义:
当
pull.rebase
为true时,运行不带选项的命令git pull
相当于执行git pull --rebase
。
当
pull.rebase
为false时,运行不带选项的命令git pull
不会被改变含义,即不会变基。如果想变基,需要在执行命令时显式地加上选项--rebase
,即git pull --rebase
。
3.2 如何保持当前的默认合并策略并阻止弹出警告文案
如果你是一个Git小白,看完我上述的文章还是没看懂什么意思,又希望你自己在执行git pull
命令时,既保持当前的默认合并策略,保证不再出现配置合并策略的警告文案,那么你只需要执行git config pull.ff false
即可,因为pull.ff
默认是没有指定的,而没有指定的pull.ff
的默认值与显式指定为false的效果一致。因此当你显式指定pull.ff
后,既保持当前的默认合并策略,又能保证不再出现配置合并策略的警告文案。
另外,上述提到的默认策略便是不带任何选项的git pull
命令:先尝试快进合并,如果不行再进行正常合并生成一个新的提交。
本文参考文献:
Git warning: Pulling without specifying how to reconcile divergent branches is discouraged
Git官方文档-参考-pull.ff
Git官方文档-参考-pull.base
Git官方文档-参考-git pull
CNBlogs文章《git fetch, git pull 以及 FETCH_HEAD》