关于 Git 2.27 版本中 git pull 时的警告

简述

最近发现,在升级了Git版本后,每次执行git pull时都会出现以下警告。

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.

早晚要好好处理这件事情,可时间已经过去了,所以现在我会认真对待。

根据搜索结果显示,这条消息似乎是在 Git 2.27.0 版本中引入的。
正如消息所述,只要实施以下三个设定之一,警告就会消失。

    • git config pull.rebase false

 

    • git config pull.rebase true

 

    git config pull.ff only

特别是,如果您对以前的操作没有任何不满,您可以运行git config –global pull.rebase false,这样以前的行为将保持不变,并且只会消除警告。

嗯,反正呢,既然有这个机会,就借此回顾一下,进一步加深理解吧。

理解 git merge 的选择

git pull 在基本上是将远程分支合并到本地分支的操作。

Git合并的策略有以下两种。

merge commit を作成 (3-way merge が行われる)
(必要なら merge 対象のブランチを rebase した上での) fast-forward (merge commit を作成しない)

比如说,假设在提交 a 之后,主分支(main branch)和开发分支(develop)产生了分叉。

git_merge_base.png

在进行合并提交时,每个分支的历史记录将保持不变,同时会创建一个新的合并提交m。

git_merge_merge_commit.png

如果要执行快速合并,那么就意味着不需创建合并提交,因此main分支在develop分岐之后不能有任何提交。(也就是说,如果main分支仍然停留在提交a的状态,那么可以直接使用快速合并将develop合并进去。)

git_merge_base_simple.png

如果不是这样的情况,首先要将develop重新基于main的HEAD提交d进行变更(rebase),使develop的分支源头成为commit d。
develop分支中的所有提交都将变为与原始提交不同的e’、f’、g’。
由于这样会修改历史记录,请注意可能出现的冲突。
此外,在Git上即使没有冲突,从代码的意义和实际操作上也可能出现冲突,因此一定要进行测试。(这一点在创建合并提交时也是一样的。)

git_merge_fast_forward_1.png

然后进行快进操作。这只是将主分支的HEAD移动到提交g’。这样在历史上就成了一条直线。

git_merge_fast_forward_2.png

对于 git pull 操作的选择理解

好的,那么在此之前,我想先考虑一下解决刚才的警告的三个选择。但在此之前,让我们确认一下 git pull 的 –rebase 选项。
如果不指定任何参数,与 –rebase false 相同,这是默认操作。如果指定了 –rebase,则与 –rebase true 相同。
还有其他用于精细控制 rebase 行为的选项,例如 –rebase merges、 –rebase preserve、 –rebase interactive,但这里就不提了。

git_pull_base.png

一般情况下,执行git pull(不加–rebase参数)会先执行git fetch,然后再执行git merge。
在默认设置下,如果可以进行快速合并(fast-forward),则会进行快速合并;如果不能进行快速合并,就会像之前的示意图那样生成合并提交(merge commit)。

git_pull_merge.png

对此,执行 git pull –rebase 命令时,先执行 git fetch 命令,然后在本地分支(此示例中为主分支)执行 git rebase 命令。
在上述 fast-forward 合并的说明中,我们执行了 develop 分支的 rebase 操作,然后执行了 fast-forward 操作,但请注意,此处执行的是主分支的 rebase 操作。(尽管 main – develop 的关系变成了 origin/main – main 的关系,但本质上还是相同的事情。)

通过这样做,不会对远程分支产生任何影响。

git_pull_rebase_1.png
git_pull_rebase_2.png

关于git pull命令的–rebase选项的使用场景有主要以下两种。

    • 同一ブランチに対して、複数人が同時並行で開発を行う場合

ローカルブランチを rebase した上で push することで、 merge commit が乱立することを防ぐことができます

Pull Request マージ前に、マージ先のデフォルトブランチを取り込んで、テストなどを行う場合

例えば、 Pull Request の feature ブランチにマージ先である main ブランチをあらかじめマージしても、 feature ブランチには merge commit が作られずに済みます (結果的に履歴が綺麗になります)

我也会查看与 git pull 的 fast-forward 相关的以下三个选项。 (git merge 也有完全相同的选项)
我将在下表中总结如下。 (默认选项为 –ff)

optionfast-forward 可能な場合fast-forward できない場合--fffast-forward で merge するmerge commit を生成する--no-ffmerge commit を生成するmerge commit を生成する--ff-onlyfast-forward で merge するmerge せず、エラー終了する

如果分别选择前面的三个选项後的行为

当达到这一点时,在没有附加选项的情况下执行git pull,我们可以了解到Git要求以下其中一项。

请将git配置pull.rebase设置为false。

这是默认的行为。执行git pull而没有添加–rebase选项的效果与没有执行–rebase的git pull相同。在默认情况下,如果可以进行fast-forward操作,它将执行fast-forward操作,否则将尝试生成合并提交。

将git配置pull.rebase设置为true。

进行 git pull –rebase 的效果与进行 git fetch 后再对本地分支进行 rebase 是相同的,因此可以保证提交历史呈直线排列,而不会创建合并提交。

只需要git config pull.ff。

只有在使用了–ff-only选项时,并且可以进行快速前进时,才会进行快速前进。
否则,不进行合并/变基操作,并以错误的方式终止。

最后结果

基本上,我認為合併/拉入策略是由每個團隊的方針而定的。以我的觀點,最好是在團隊內部達成一致,這樣在查看 Git 歷史時較容易操作。然而,當人數增加時,這一點可能變得更加困難。

合并/拉取的策略是关于如何整合代码历史记录的讨论,对当前的快照没有特别影响。(在Git操作中可能会遇到问题,但影响可能不大)
由于没有特别严重的问题,所以总的来说,当遇到困惑时,最好保持默认设置?

参考资料

    • https://raw.githubusercontent.com/git/git/master/Documentation/RelNotes/2.27.0.txt

 

    • How to deal with this git warning? “Pulling without specifying how to reconcile divergent branches is discouraged” – Stack Overflow

 

    • Why You Should Use git pull –ff-only | sffc’s Tech Blog

 

    • オプションなし git pull でデフォルトの挙動が未設定だと警告が出る – Qiita

 

    • Git 2.27.0 から git pull をすると表示されるようになった “Pulling without specifying how to reconcile divergent branches is discouraged.” について – esm アジャイル事業部 開発者ブログ

 

    • git pull エラー “Pulling without specifying how to reconcile divergent branches is discouraged.” | ハックノート

 

    • ブランチの統合|サル先生のGit入門【プロジェクト管理ツールBacklog】

 

    • Git – git-merge Documentation

 

    • Git – git-pull Documentation

 

    • Git – git-config Documentation

 

    • Git – リベース

 

    • fast-forwardマージから理解するgit rebase – Qiita

 

    • Git のファストフォワードマージとは – yu8mada

 

    • Git fast-forward な状態にして update branch で master を取り込んだ commit を残さずに済むための git rebase – かもメモ

 

    • git pull と git pull –rebase の違いって?図を交えて説明します! – KRAY Inc.

 

    • 3-way mergeについて調べた – Qiita

 

    • GithubでのWeb上からのマージの仕方3種とその使いどころ – Qiita

 

    何故 git rebase は駄目で git pull –rebase はいいのか « LANCARD.LAB|ランカードコムのスタッフブログ
广告
将在 10 秒后关闭
bannerAds