[英]Is git pull really git fetch + git merge?
我在以下沙箱中練習 git: https ://learngitbranching.js.org/?NODEMO
我在兩個單獨的會話中運行了兩組命令。 第一組命令按順序如下:
git clone
git checkout -b feature
git push
git fakeTeamwork main 1
git fakeTeamwork feature 1
git pull
按順序排列的第二組命令類似,但我最后使用git fetch
+ git merge
代替:
git clone
git checkout -b feature
git push
git fakeTeamwork main 1
git fakeTeamwork feature 1
git fetch
git merge o/feature
如果git pull
= git fetch
+ git merge
,為什么兩個結果不同? 似乎git pull
並沒有更新所有的遠程跟蹤分支。 這只是沙盒的一個缺陷還是這實際上是 git 中發生的事情?
注意:命令git clone
和git fakeTeamwork
只是為沙箱構建的命令
謝謝!
似乎 git pull 並沒有更新所有的遠程跟蹤分支。
這可能發生,是的。 它確實發生在:
git pull
運行git fetch origin master
,並且git fetch origin master
因此只更新origin/master
。 此外,在 1.8.4 之前的 Git 版本中,一些git fetch
操作根本不會更新任何遠程跟蹤名稱。 這里git fetch origin master
對origin/master
沒有影響。
除了這些,我們還有其他幾種特殊情況:
git pull
運行git rebase
,它使用的第二個命令是git rebase
,而不是git merge
。 因此,明顯的替代品是git fetch
后跟git rebase
。 但是,這里的一些細節甚至更多取決於 Git 版本:特別是git pull
在git rebase --fork-point
存在之前為 rebase 實現--fork-point
模式(實際的--fork-point
選項首先出現在 Git 1.9 ,但是git pull
從某個 1.6 版本開始就做了一些特殊的工作——我曾經查過准確的版本,但現在使用的最古老的 Git 似乎是用於 CentOS,其中包括一些發行版中的一些 Git 1.7 版本)。git pull
,則還沒有現有的分支。 (您可以稍后使用孤立分支再次觸發這種情況。)在這種情況下, git pull
運行一個專門的git checkout
,而不是合並或變基。 分支的上游設置在這里很重要,具體取決於您傳遞給git pull
或 fetch 和第二個命令的參數。 一般來說,這些最終以相同的方式工作,除了你注意到一些遠程跟蹤名稱有時沒有得到更新的警告。
git pull
真的是git fetch
+git merge
嗎?
簡而言之,是的。
但是,值得指出的是,哪些遠程跟蹤分支由git fetch
更新(當不帶任何參數調用時)由remote.<repository>.fetch
配置變量確定。
如果您在真實的 Git 存儲庫中運行git config remote.origin.fetch
,您應該會看到以下內容:
+refs/heads/*:refs/remotes/origin/*
這稱為refspec 。 *
告訴 Git 獲取遠程origin
中的所有分支( :
的右側)並將它們放入本地存儲庫( :
的左側)。 如果您不帶任何參數運行git pull
或git fetch
,則所有新的和現有的遠程跟蹤分支都將由於此設置而更新。
從文檔中:
當
git fetch
運行時沒有指定在命令行上獲取哪些分支和/或標簽,例如git fetch origin
或git fetch
,remote.<repository>.fetch
值用作 refspecs——它們指定要獲取的 refs 和要更新哪些本地參考。 上面的示例將獲取origin
中存在的所有分支(即與值左側匹配的任何 ref,refs/heads/*
)並更新refs/remotes/origin/*
中相應的遠程跟蹤分支等級制度。
正如@torek在他的回答中指出的那樣,一旦您開始將分支名稱傳遞給git pull
或git fetch
,此行為將不再適用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.