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

推送遠程分支到同一個server

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

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

眼下git branch是空的。bash

咱們提交一點東西創建master分支。服務器

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

現在git branch -a 顯示:fetch

* master remotes/origin/master

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

咱們切到git2如下this

cd ../git2 git pull origin

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

現在咱們開始嘗試創建還有一個分支並推送到server。spa

習慣的,咱們仍是切回git1指針

cd ../git1 git checkout -b source

這時候咱們已經有了一個本地分支了,假設這個分支不需要共享,那麼你可以一直在這個分支上commit但是不push到server。直到這個分支被合併回主分支或者丟棄。regexp

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下

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

相關文章
相關標籤/搜索