Git push與pull的預設行為

2021-08-10 07:26:56 字數 3777 閱讀 3331

一直以來對git pushgit pull命令的預設行為感覺混亂,今天抽空總結下。

通常對於乙個本地的新建分支,例如git checkout -b develop, 在develop分支commit了**之後,如果直接執行git push命令,develop分支將不會被push到遠端倉庫(但此時git push操作有可能會推送一些**到遠端倉庫,這取決於我們本地git config配置中的push.default預設行為,下文將會逐一詳解)。

因此我們至少需要顯式指定將要推送的分支名,例如git push origin develop,才能將本地新分支推送到遠端倉庫。

當我們通過顯式指定分支名進行初次push操作後,本地有了新的commit,此時執行git push命令會有什麼效果呢?

如果你未曾改動過git config中的push.default屬性,根據我們使用的git不同版本(git 2.0之前或之後),git push通常會有兩種截然不同的行為:

develop分支中本地新增的commit被push到遠端倉庫

push失敗,並收到git如下的警告

fatal: the current branch new

hasno upstream branch.

to push the current branch and

set the remote as upstream, use

git push --set-upstream origin develop

為什麼git版本不同會有兩種不同的push行為?

因為在git的全域性配置中,有乙個push.default屬性,其決定了git push操作的預設行為。在git 2.0之前,這個屬性的預設被設為'matching',2.0之後則被更改為了'******'。

我們可以通過git version確定當前的git版本(如果小於2.0,更新是個更好的選擇),通過git config --global push.default 'option'改變push.default的預設行為(或者也可直接編輯~/.gitconfig檔案)。

push.default 有以下幾個可選值:

nothing, current, upstream, ******, matching

其用途分別為:

因此如果我們使用了git2.0之前的版本,push.default = matching,git push後則會推送當前分支**到遠端分支,而2.0之後,push.default = ******,如果沒有指定當前分支的upstream分支,就會收到上文的fatal提示。

說到這裡,需要解釋一下git中的upstream到底是什麼:

git中存在upstream和downstream,簡言之,當我們把倉庫a中某分支x的**push到倉庫b分支y,此時倉庫b的這個分支y就叫做a中x分支的upstream,而x則被稱作y的downstream,這是乙個相對關係,每乙個本地分支都相對地可以有乙個遠端的upstream分支(注意這個upstream分支可以不同名,但通常我們都會使用同名分支作為upstream)。

初次提交本地分支,例如git push origin develop操作,並不會定義當前本地分支的upstream分支,我們可以通過git push --set-upstream origin develop,關聯本地develop分支的upstream分支,另乙個更為簡潔的方式是初次push時,加入-u引數,例如git push -u origin develop,這個操作在push的同時會指定當前分支的upstream。

注意push.default = current可以在遠端同名分支不存在的情況下自動建立同名分支,有些時候這也是個極其方便的模式,比如初次push你可以直接輸入 git push 而不必顯示指定遠端分支。

弄清楚git push的預設行為後,再來看看git pull

there is

no tracking information for the current branch.

please specify which branch you want to merge with.

see git-pull(1) for details

git pull

if you wish to

set tracking information for this branch you can do

so with:

git branch --set-upstream-to=origin/

new1

git pull的預設行為和git push完全不同。當我們執行git pull的時候,實際上是做了git fetch + git merge操作,fetch操作將會更新本地倉庫的remote tracking,也就是refs/remotes中的**,並不會對refs/heads中本地當前的**造成影響。

當我們進行pull的第二個行為merge時,對git來說,如果我們沒有設定當前分支的upstream,它並不知道我們要合併哪個分支到當前分支,所以我們需要通過下面的**指定當前分支的upstream:

git branch --set-upstream-to=origin/

develop

// 或者git push --set-upstream origin develop

實際上,如果我們沒有指定upstream,git在merge時會訪問git config中當前分支(develop)merge的預設配置,我們可以通過配置下面的內容指定某個分支的預設merge操作

[branch "develop"]

remote = origin

merge = refs/heads/develop // [1]為什麼不是refs/remotes/develop?

或者通過command-line直接設定:

git config branch.develop

.merge refs/heads/develop

這樣當我們在develop分支git pull時,如果沒有指定upstream分支,git將根據我們的config檔案去merge origin/develop;如果指定了upstream分支,則會忽略config中的merge預設配置。

以上就是git push和git pull操作的全部預設行為,如有錯誤,歡迎斧正

[1] 為什麼merge = refs/heads/develop 而不是refs/remotes/develop?

因為這裡merge指代的是我們想要merge的遠端分支,是remote上的refs/heads/develop,文中即是origin上的refs/heads/develop,這和我們在本地直接執行git merge是不同的(本地執行git merge origin/develop則是直接merge refs/remotes/develop)。

refs:

by abruzzi's blog

git push和pull如何解決衝突!!!精品

多人合作完成專案時,git push 和 pull經常會發生衝突,根本原因就是遠端的東西和本地的東西長的不一樣,以下步驟能完美解決所有衝突!先檢視一下分支 git branch 確認沒錯再進行下面的操作 1.找到乙個最新可用的版本,並回退到那 先用 git log 找到乙個可行版本,如 abc.再用...

Git 遠端分支的pull與push

git branch r 檢視遠端分支 git branch a 檢視所有分支,本地和遠端 git remote show remote name 檢視遠端倉庫資訊其中git remote show remote name 展示的資訊包括 git checkout b local origin da...

activemq接收訊息pull與push模式

1。同步和非同步的方式 public static void main string args else 非同步的方式接收訊息 consumer.setmessagelistener new messagelistener catch exception e 非同步接收 catch exceptio...