Git遠程分支和refs文件具體解釋


推送遠程分支到同一個server

比方首先建立gitserver,順便clone出兩個副本

mkdir server
cd server git init --bare cd .. git clone server git1 git clone server git2

眼下git branch是空的。

我們提交一點東西建立master分支。

cd git1
touch a.txt git add . git commit -m "init" git push origin master

如今git branch -a 顯示:

* master remotes/origin/master

當前系統處於master分支,遠程origin的repository上也有一個master分支。兩個是tracking的。

我們切到git2以下

cd ../git2 git pull origin

這時候git2跟git1全然同步了。

如今我們開始嘗試建立還有一個分支並推送到server。

習慣的,我們還是切回git1

cd ../git1 git checkout -b source

這時候我們已經有了一個本地分支了,假設這個分支不須要共享,那么你能夠一直在這個分支上commit可是不push到server。直到這個分支被合並回主分支或者丟棄。

git branch 顯演示樣例如以下:

  master
* source

我們終於決定把這個分支push到server上與其它人共享。例如以下:

git push origin source:source

這時候git branch -a 能看到當前repository里面全部的分支,包含兩個本地的,兩個遠程的,本地和遠程的都處於tracking狀態。

  master
* source remotes/origin/master remotes/origin/source

切到還有一個副本。

cd ../git2 git pull origin

顯演示樣例如以下:

 * [新分支] source -> origin/source

git branch -a顯示本地已經有了一個遠程分支的指針,可是沒有tracking這個分支的本地分支:

* master remotes/origin/master remotes/origin/source

相同我們能夠在.git/refs/remotes/origin下看到分支的名字,可是refs/heads以下並沒有。我們來檢出這個遠程分支:

git checkout -b source origin/source

這時候git branch -a 顯示就跟git1一致了。git2下也能夠編輯source分支並同步。這些都是比較常見的操作,我們須要注意的是。多分支下默認的參數。比方,在兩個分支都改動一點東西:

cd ../git1 git checkout master //modify  git add . git commit -m "master modify" git checkout source //modify git add . git commit -m "source modify"

這時候git push origin 是針對當前分支的,所以兩個分支同一時候push更新僅僅能

git push origin git checkout master git push origin

pull更新的時候

cd ../git2 git checkout master git pull origin

這會同一時候更新兩個分支的指針。可是不會merge還有一個分支,我們去還有一個分支下

git checkout source git pull origin

可是出錯例如以下:

You asked to pull from the remote 'origin', but did not specify a branch. Because this is not the default configured remote for your current branch, you must specify a branch on the command line.

問題在於沒有給當前分支配置merge的路徑,git不知道去merge哪個分支。(盡管我認為既然是tracking的不應該不知道啊)。

假設你有 1.6.2 以上版本號的 Git。—track 選項能夠同一時候配置merge的路徑:

git checkout --track origin/serverfix

這里我們改動配置文件增加branch “source”:

[core] repositoryformatversion = 0 filemode = false bare = false logallrefupdates = true [remote "origin"] url = /media/cxh/backup/work/ceshi/git/server fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master"這里指server上的refs/heads/master [branch "source"] remote = origin merge = refs/heads/source

這意味着每次fetch origin的時候更新全部remotes/origin的頭指針到refs/heads/以下,詳細能夠去.git下查閱這個文件夾,可是頭指針都是僅僅讀的。

merge是由所在branch定義的。

我們加了branch “source”的配置指定當前source的merge策略是使用server端的refs/heads/source來合並到當前分支。

這樣就能夠順利的git pull origin了。

推送遠程分支到不同server

我們先建立新的repo:

cd .. mkdir server2 cd server2 git init --bare

增加git1副本,並提交

git remote add server xxx/server2 git push server

上面過程的本質是提交當前分支頭指針到server。相當於拷貝refs/head/xxx到refs/remotes/server/下並提交。

git push server會被展開成

git push server 當前分支名:當前分支名

我們能夠在git2副本相同增加該repository並更新引用

git remote add server xxx/server2 git fetch server

能夠看到refs下文件夾結構例如以下:

├── heads    ├── master    └── source ├── remotes    ├── origin       ├── master       └── source    └── server    └── source └── tags

總結一下

  • update

    • fetch操作的本質是更新repo所指定遠程分支的頭指針(server->refs/remotes/xxx/)

    • merge操作的本質是合並當前分支和指定的頭指針(refs/remotes/xxx->refs/heads)

    • pull操作的本質是fetch + merge

  • commit

    • commit的本質是改動了當前分支的頭指針(refs/heads)

    • push操作本質是提交當前分支頭指針到server,順便也改動了本地存儲的server頭指針(refs/remotes/xxx)

  • checkout

    • 復制本地分支的本質是拷貝了refs/heads/下的一個頭指針

    • push本地分支到server的本質是把這個頭指針上傳服務器,順便拷貝了本地存儲的server頭指針(refs/remotes/xxx)

    • tracking遠程分支的本質是把refs/remotes/下的指針復制到了refs/heads下

注:以上過程都沒有涉及數據流。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM