推送遠程分支到同一個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下
-
注:以上過程都沒有涉及數據流。