<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                這里我們要看一下: Git的客戶端和服務器如何交互傳輸數據. ## 通過HTTP協議抓取 通過http協議的url進行的git數據抓取, 使用了一個比較傻瓜化(dumber)的協議. 使用http協議, 所有的邏輯計算(logic)都是在客戶端進行. 服務器不需要特別的設置, 你只要把git目錄放到一個可以訪問的web目錄即可. 為了能通過http訪問, 當你的倉庫有任何更新時, 需要運行一個命令:?[git update-server-info](http://www.kernel.org/pub/software/scm/git/docs/git-update-server-info.html). 因為web服務器一般不允許執行列出目錄中文件的操作, 所以[git update-server-info](http://www.kernel.org/pub/software/scm/git/docs/git-update-server-info.html)命令把可用的打包文件(packfile)和引用(refs)列表更新到“objects/info/packs","info/refs"這個兩個文件中. 當?[git update-server-info](http://www.kernel.org/pub/software/scm/git/docs/git-update-server-info.html)?執行后,"objects/info/packs"文件看起來就會像下面一樣: ~~~ P pack-ce2bd34abc3d8ebc5922dc81b2e1f30bf17c10cc.pack P pack-7ad5f5d05f5e20025898c95296fe4b9c861246d8.pack ~~~ 如果在通過http協議拉取數據的過程中找不到松散文件(loose file), git就會去嘗試查找打包文件(packfiles). "info/refs" 文件的內容看起來就下面這樣: ~~~ 184063c9b594f8968d61a686b2f6052779551613 refs/heads/development 32aae7aef7a412d62192f710f2130302997ec883 refs/heads/master ~~~ 當你從這個倉庫開始抓取(fetch)數據時, git就會從這些引用(refs)開始遍歷查找所有的提交對象(commit objects), 直到客戶端得到了它所有需要的所有對象為止. 例如, 你要抓取到(fetch)服務器上的"master"分支; git看到服務器上的"master"分支指向`32aae7ae`, 而你當前的"master"分支是指向`ab04d88`. 那么很明顯, 你需要得到`32aae7ae`這個對象. 下面就是抓取時的交互過程(http協議層): ~~~ CONNECT http://myserver.com GET /git/myproject.git/objects/32/aae7aef7a412d62192f710f2130302997ec883 - 200 ~~~ 然后返回信息看起來就像下面這樣: ~~~ tree aa176fb83a47d00386be237b450fb9dfb5be251a parent bd71cad2d597d0f1827d4a3f67bb96a646f02889 author Scott Chacon <schacon@gmail.com> 1220463037 -0700 committer Scott Chacon <schacon@gmail.com> 1220463037 -0700 added chapters on private repo setup, scm migration, raw git ~~~ 好的那么現在它就是開始抓取樹對象(tree)?`aa176fb8`: 譯者注:`32aae7ae`提交對象(commit object)指向的樹對象(tree)是:`aa176fb8`. ~~~ GET /git/myproject.git/objects/aa/176fb83a47d00386be237b450fb9dfb5be251a - 200 ~~~ 下面這些是返回的樹對象(tree)信息: ~~~ 100644 blob 6ff87c4664981e4397625791c8ea3bbb5f2279a3 COPYING 100644 blob 97b51a6d3685b093cfb345c9e79516e5099a13fb README 100644 blob 9d1b23b8660817e4a74006f15fae86e2a508c573 Rakefile ~~~ 很明顯, 樹對象(tree)里有3個文件(blob). 好的, 我們就把它們抓下來吧: ~~~ GET /git/myproject.git/objects/6f/f87c4664981e4397625791c8ea3bbb5f2279a3 - 200 GET /git/myproject.git/objects/97/b51a6d3685b093cfb345c9e79516e5099a13fb - 200 GET /git/myproject.git/objects/9d/1b23b8660817e4a74006f15fae86e2a508c573 - 200 ~~~ 這些http下載操作實際上是由curl來完成的, 我們可以開多個并行的線程來加快下載速度. Git遍歷完提交對象(commit)所指向的樹對象(tree)后, 就會開始抓取提交對象(commit)的父對象(next parent). ~~~ GET /git/myproject.git/objects/bd/71cad2d597d0f1827d4a3f67bb96a646f02889 - 200 ~~~ 返回的父對象(parent commit object)信息就如下面所示: ~~~ tree b4cc00cf8546edd4fcf29defc3aec14de53e6cf8 parent ab04d884140f7b0cf8bbf86d6883869f16a46f65 author Scott Chacon <schacon@gmail.com> 1220421161 -0700 committer Scott Chacon <schacon@gmail.com> 1220421161 -0700 added chapters on the packfile and how git stores objects ~~~ 我們現在可以看到`ab04d88`是返回的對象(commit)的父對象, 而`ab04d88`(commit)就是我們當前的"master"分支. 那么我們只需要得到樹對象(tree):`b4cc00c`就可以了, 因為之前的所以的提交(commit)我們都有了. 為了保險起見, 你也可以加上'--recover'參數, 強制git反復檢查我們是否擁有所有的對象. 你可以點這里:?[git http-fetch](http://www.kernel.org/pub/software/scm/git/docs/git-http-fetch.html)?查看更多信息: 如果有一個松散對象(loose object)下載失敗了, git會下載打包文件索引(packfile indexes), 通過它來查找對應的sha串值,然后再下載對應的打包文件(packfile). 你一定要在git服務器的倉庫里添一個"post-receive"鉤子(hook), 這個鉤子(hook)會在倉庫更新后執行'git update-server-info; 否則倉庫的相關信息就得不到更新. ## 通過 Upload Pack 抓取數據 對于一個聰明的協議, 抓取對象的過程(fetching objects)應當更加高效. 不管是用通過ssh協議還是git協議(git:// 協議,在9418端口上運行), 當客戶端和服務器建立了一個socket連接后,客戶端開始運行:[git fetch-pack命令, 和服務器創建(fork)的 linkgit:git update-pack](http://www.kernel.org/pub/software/scm/git/docs/git-fetch-pack%E5%91%BD%E4%BB%A4,%20%E5%92%8C%E6%9C%8D%E5%8A%A1%E5%99%A8%E5%88%9B%E5%BB%BA(fork)%E7%9A%84%20linkgit:git-update-pack.html)進行通訊. 服務器會告訴客戶端它每個引用(ref)所有擁有的SHA串值, 而客戶端會以它所需要的和所擁有SHA串值作為回應. 這里, 服務器會把客戶端需要的所有對象打一個包(packfile), 然后再傳送給客戶端. 讓我們來看一個例子. 客戶端連接并且發送請求頭(request header). 例如,克隆命令: ~~~ $ git clone git://myserver.com/project.git ~~~ 上面的命令會產生下面的請求: ~~~ 0032git-upload-pack /project.git\000host=myserver.com\000 ~~~ 每行的最前面的4個字節表示此行的16進行制長度(hex length) (包括這個4個字節,但不包括換行符). 下面接著的是命令和參數, 這之后是一個null字節(#body00)和主機信息. 請求的結尾是以null字節(\000)結束的. 這個請求被服務器接收并且轉換成對"git-upload-pack"的命令調用. ~~~ $ git-upload-pack /path/to/repos/project.git ~~~ 這條命令會馬上返回倉庫的信息: ~~~ 007c74730d410fcb6603ace96f1dc55ea6196122532d HEAD\000multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress 003e7d1665144a3a975c05f1f43902ddaf084e784dbe refs/heads/debug 003d5a3f6be755bbb7deae50065988cbfa1ffa9ab68a refs/heads/dist 003e7e47fe2bd8d01d481f44d7af0531bd93d3b21c01 refs/heads/local 003f74730d410fcb6603ace96f1dc55ea6196122532d refs/heads/master 0000 ~~~ 每一行開始的頭4個字節表示此行的長度(以16進制表示). 這塊(section)信息以一行“0000”為結束標識符. 上面這些服務器產生的數據被發送回客戶端. 然后客戶端用另外一個請求做為響應: ~~~ 0054want 74730d410fcb6603ace96f1dc55ea6196122532d multi_ack side-band-64k ofs-delta ~~~ p 0032want 7d1665144a3a975c05f1f43902ddaf084e784dbe ~~~ 0032want 5a3f6be755bbb7deae50065988cbfa1ffa9ab68a 0032want 7e47fe2bd8d01d481f44d7af0531bd93d3b21c01 0032want 74730d410fcb6603ace96f1dc55ea6196122532d 00000009done ~~~ 上面這些客戶端的請求會被發送到的"git-upload-pack"進程, 這個進程會返回(streams out)最終的結果(final response): ~~~ "0008NAK\n" "0023\002Counting objects: 2797, done.\n" "002b\002Compressing objects: 0% (1/1177) \r" "002c\002Compressing objects: 1% (12/1177) \r" "002c\002Compressing objects: 2% (24/1177) \r" "002c\002Compressing objects: 3% (36/1177) \r" "002c\002Compressing objects: 4% (48/1177) \r" "002c\002Compressing objects: 5% (59/1177) \r" "002c\002Compressing objects: 6% (71/1177) \r" "0053\002Compressing objects: 7% (83/1177) \rCompressing objects: 8% (95/1177) \r" ... "005b\002Compressing objects: 100% (1177/1177) \rCompressing objects: 100% (1177/1177), done.\n" "2004\001PACK\000\000\000\002\000\000\n\355\225\017x\234\235\216K\n\302"... "2005\001\360\204{\225\376\330\345]z2673"... ... "0037\002Total 2797 (delta 1799), reused 2360 (delta 1529)\n" ... "<\276\255L\273s\005\001w0006\001[0000" ~~~ 你可以查看"打包文件"(packfile)這一章, 了解響應內容中的打包文件(packfile)的格式. ## 推送數據 通過git和ssh協議推送數據(pushing data)是相似的, 但是更簡單. 基本上是, 客戶端發出一個"receive-pack"的請求, 如果客戶端有訪問權限, 那么服務器就返回所有引用"頭"的SHA串值(all ref head shas). 客戶端收到響應后, 計算出服務器需要的所有數據或對象, 再做成一個打包文件(packfile)傳送給服務器. 服務器收到后要么就把它們存儲到硬盤上再建立索引, 要么只把它解壓(如果里面的對象不多的話). 在這整個推送數據的過程中, 客戶端通過?[git push](http://www.kernel.org/pub/software/scm/git/docs/git-push.html)?命令調用:[git sendpack](http://www.kernel.org/pub/software/scm/git/docs/git-sendpack.html)命令, 服務器端通過"ssh連接進程"或是"git服務器"來調用:linkgit:git-receive-pack 命令來完成整個操作.
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看