1. 程式人生 > >git命令行(3)之遠程版本庫

git命令行(3)之遠程版本庫

git

一、遠程版本庫相關概念

1.裸版本庫和開發版本庫

裸版本庫就是不含有工作區的版本庫,而我們平常開發的代碼庫都是開發版本庫,修改工作區,然後進行提交、推送提交等操作。
可以使用git init --bare命令創建一個裸版本庫。裸版本庫一般作為服務器上的版本庫。

2.refspec

引用空間把遠程分支版本庫中的分支名映射到本地版本庫中的分支名。其語法為:
[+]source:dest如果有加號則表示不會在傳輸過程中進行正常的快進安全檢查。

操作 目標
fetch 抓取的遠程引用 更新的本地引用
push 推動的本地引用 更新的遠程引用

比如git fetch命令會使用refspec:+refs/heads/:refs/remotes/origin/

。其定義在.git/config文件中

3.遠程版本庫支持的協議

git使用URL來定位遠程版本庫,支持多種url協議,常見的有http、https、git、ssh、file。

二、clone和remote命令

1.clone

clone命令可以把遠程的代碼庫克隆到本地,並在.git/config目錄中記錄遠程版本庫的url。.git/config文件如下:

[core]
    repositoryformatversion = 0
    filemode = false
    bare = false
    logallrefupdates = true
    symlinks = false
    ignorecase = true
[remote "origin"]
    url = D:/source-code/temp/server
    fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
    remote = origin
    merge = refs/heads/master
[branch "develop"]
    remote = origin
    merge = refs/heads/develop

註意[remote "origin"] url = D:/source-code/temp/server,其中origin是對url的一個別名,因為一個git庫可能對應多個遠程代碼庫(例如使用git remote add命令添加其他遠程代碼庫,git協同模型的子樹合並),如果沒有這個別名,每次都填寫這個長長的url會很麻煩,所以這個別名是必須的,而且clone的時候,別名默認為“origin”。

2.remote命令

remote命令用於管理遠程版本庫

$git remote add daf_remote http://xxxx/*.git            --------添加daf_remote為別名的url,此時會看到.git/config文件變更
$git remote rename <old> <new>                      -----重命名別名
$git remote remove <name>         ------移除某個遠程代碼庫
$git remote -v show         ------移除某個遠程代碼庫

三、fetch和pull命令

pull=fetch+merge。當我們執行git pull命令實際上會首先執行fetch抓取命令,然後把當前分支和抓取的SHA1合並。
而當我們執行git pull命令的時候,git是如何知道拉取和合並的呢?

    • git pull命令的時候,git首先會查找遠程庫的url的別名,此時我們沒有輸入別名,那麽git默認使用"origin"別名,此時等價於git pull origin.
    • 執行fetch命令,fetch命令要求refspec來獲得抓取的範圍。因為我們沒有輸入,那麽git使用.git/config文件中的remote.<rep. alias>.fetch屬性的值,一般是+refs/heads/:refs/remotes/origin/。那麽這個ref表示抓取遠程庫上所有的以ref/heads/開頭的引用,映射到本地的refs/remotes/origin開頭的引用。以其中的master為例refs/heads/master:refs/remotes/origin/master,那麽抓取的時候會把遠程庫上的refs/heads/master(記住遠程庫上的.git庫同樣和本地都有refs/heads/master文件)對應的SHA1值同步到本地倉庫的refs/remotes/origin/master的文件中,並把其中差異的git對象(本地是a/b/c提交,而遠程是a/b/c/d/e提交,那麽差異的提交就是d/e和對應的git對象)從遠程庫下載到本地的對象庫(.git/objects目錄)。如果有多個分支(maste、develop、feature1)會循環執行同步SHA1和下載git對象內容。
    • 執行merge命令,把fetch到的遠程版本(即refs/remotes/origin/master文件的SHA1)合並到當前分支
      因此git pull=git fetch origin +refs/heads/:refs/remotes/origin/+git merge refs/remotes/origin/${當前分支}

當我們執行git pull origin develop(:develop)的時候,同樣和git pull相同,因為具體執行的時候,git fetch會補齊遠程倉庫和完整的refspac

四、git push

push命令是和fetch命令是一個相反的命令,其refspac一般為refs/heads/${branchNam}:refs/heads/${branchNam}。表示源為本地refs/heads/${branchNam}的引用,目標為遠程倉庫refs/heads/${branchNam}的引用。

  • 當我們執行git push的時候,其等價於git push origin refs/heads/${branchNam}:refs/heads/${branchNam}。也就是默認情況下只推 送本地分支,而不是所有的分支。
  • 可以使用git push origin refs/heads/:refs/heads/推送本地所有的分支變更。
  • git push origin :${branchNam}表示刪除某個分支

git命令行(3)之遠程版本庫