<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>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # 傳輸協議 Git 可以通過兩種主要的方式在版本庫之間傳輸數據:“啞(dumb)”協議和“智能(smart)”協議。 本節將會帶你快速瀏覽這兩種協議的運作方式。 ## 啞協議 如果你正在架設一個基于 HTTP 協議的只讀版本庫,一般而言這種情況下使用的就是啞協議。 這個協議之所以被稱為“啞”協議,是因為在傳輸過程中,服務端不需要有針對 Git 特有的代碼;抓取過程是一系列 HTTP 的?`GET`?請求,這種情況下,客戶端可以推斷出服務端 Git 倉庫的布局。 > #### NOTE > 現在已經很少使用啞協議了。 使用啞協議的版本庫很難保證安全性和私有化,所以大多數 Git 服務器宿主(包括云端和本地)都會拒絕使用它。 一般情況下都建議使用智能協議,我們會在后面進行介紹。 讓我們通過 simplegit 版本庫來看看?`http-fetch`?的過程: ~~~ $ git clone http://server/simplegit-progit.git ~~~ 它做的第一件事就是拉取?`info/refs`?文件。 這個文件是通過?`update-server-info`?命令生成的,這也解釋了在使用HTTP傳輸時,必須把它設置為?`post-receive`?鉤子的原因: ~~~ => GET info/refs ca82a6dff817ec66f44342007202690a93763949 refs/heads/master ~~~ 現在,你得到了一個遠程引用和 SHA-1 值的列表。 接下來,你要確定 HEAD 引用是什么,這樣你就知道在完成后應該被檢出到工作目錄的內容: ~~~ => GET HEAD ref: refs/heads/master ~~~ 這說明在完成抓取后,你需要檢出?`master`?分支。 這時,你就可以開始遍歷處理了。 因為你是從`info/refs`?文件中所提到的?`ca82a6`?提交對象開始的,所以你的首要操作是獲取它: ~~~ => GET objects/ca/82a6dff817ec66f44342007202690a93763949 (179 bytes of binary data) ~~~ 你取回了一個對象——這是一個在服務端以松散格式保存的對象,是你通過使用靜態 HTTP GET 請求獲取的。 你可以使用 zlib 解壓縮它,去除其頭部,查看提交記錄的內容: ~~~ $ git cat-file -p ca82a6dff817ec66f44342007202690a93763949 tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf parent 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 author Scott Chacon <schacon@gmail.com> 1205815931 -0700 committer Scott Chacon <schacon@gmail.com> 1240030591 -0700 changed the version number ~~~ 接下來,你還要再獲取兩個對象,一個是樹對象?`cfda3b`,它包含有我們剛剛獲取的提交對象所指向的內容,另一個是它的父提交?`085bb3`: ~~~ => GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 (179 bytes of data) ~~~ 這樣就取得了你的下一個提交對象。 再抓取樹對象: ~~~ => GET objects/cf/da3bf379e4f8dba8717dee55aab78aef7f4daf (404 - Not Found) ~~~ 噢——看起來這個樹對象在服務端并不以松散格式對象存在,所以你得到了一個 404 響應,代表在 HTTP 服務端沒有找到該對象。 這有好幾個可能的原因——這個對象可能在替代版本庫里面,或者在包文件里面。 Git 會首先檢查所有列出的替代版本庫: ~~~ => GET objects/info/http-alternates (empty file) ~~~ 如果這返回了一個包含替代版本庫 URL 的列表,那么 Git 就會去那些地址檢查松散格式對象和文件——這是一種能讓派生項目共享對象以節省磁盤的好方法。 然而,在這個例子中,沒有列出可用的替代版本庫。所以你所需要的對象肯定在某個包文件中。 要檢查服務端有哪些可用的包文件,你需要獲取?`objects/info/packs`?文件,這里面有一個包文件列表(它也是通過執行?`update-server-info`?所生成的): ~~~ => GET objects/info/packs P pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack ~~~ 服務端只有一個包文件,所以你要的對象顯然就在里面。但是你要先檢查它的索引文件以確認。 即使服務端有多個包文件,這也是很有用的,因為這樣你就可以知道你所需要的對象是在哪一個包文件里面: ~~~ => GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.idx (4k of binary data) ~~~ 現在你有這個包文件的索引,你可以查看你要的對象是否在里面——因為索引文件列出了這個包文件所包含的所有對象的 SHA-1 值,和該對象存在于包文件中的偏移量。 你的對象就在這里,接下來就是獲取整個包文件: ~~~ => GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack (13k of binary data) ~~~ 現在你也有了你的樹對象,你可以繼續在提交記錄上漫游。 它們全部都在這個你剛下載的包文件里面,所以你不用繼續向服務端請求更多下載了。 Git 會將開始時下載的 HEAD 引用所指向的`master`?分支檢出到工作目錄。 ## 智能協議 啞協議雖然很簡單但效率略低,且它不能從客戶端向服務端發送數據。 智能協議是更常用的傳送數據的方法,但它需要在服務端運行一個進程,而這也是 Git 的智能之處——它可以讀取本地數據,理解客戶端有什么和需要什么,并為它生成合適的包文件。 總共有兩組進程用于傳輸數據,它們分別負責上傳和下載數據。 #### 上傳數據 為了上傳數據至遠端,Git 使用?`send-pack`?和?`receive-pack`?進程。 運行在客戶端上的`send-pack`?進程連接到遠端運行的?`receive-pack`?進程。 #### SSH 舉例來說,在項目中使用命令?`git push origin master`?時,?`origin`?是由基于 SSH 協議的 URL 所定義的。 Git 會運行?`send-pack`?進程,它會通過 SSH 連接你的服務器。 它會嘗試通過 SSH 在服務端執行命令,就像這樣: ~~~ $ ssh -x git@server "git-receive-pack 'simplegit-progit.git'" 00a5ca82a6dff817ec66f4437202690a93763949 refs/heads/master report-status \ delete-refs side-band-64k quiet ofs-delta \ agent=git/2:2.1.1+github-607-gfba4028 delete-refs 0000 ~~~ `git-receive-pack`?命令會立即為它所擁有的每一個引用發送一行響應——在這個例子中,就只有`master`?分支和它的 SHA-1 值。 第一行響應中也包含了一個服務端能力的列表(這里是?`report-status`、`delete-refs`?和一些其它的,包括客戶端的識別碼)。 每一行以一個四位的十六進制值開始,用于指明本行的長度。 你看到第一行以 005b 開始,這在十六進制中表示 91,意味著第一行有 91 字節。 下一行以 003e 起始,也就是 62,所以下面需要讀取 62 字節。 再下一行是 0000,表示服務端已完成了發送引用列表過程。 現在它知道了服務端的狀態,你的?`send-pack`?進程會判斷哪些提交記錄是它所擁有但服務端沒有的。?`send-pack`?會告知?`receive-pack`?這次推送將會更新的各個引用。 舉個例子,如果你正在更新?`master`?分支,并且增加?`experiment`?分支,這個?`send-pack`?的響應將會是像這樣: ~~~ 0076ca82a6dff817ec66f44342007202690a93763949 15027957951b64cf874c3557a0f3547bd83b3ff6 \ refs/heads/master report-status 006c0000000000000000000000000000000000000000 cdfdb42577e2506715f8cfeacdbabc092bf63e8d \ refs/heads/experiment 0000 ~~~ Git 會為每一個將要更新的引用發送一行數據,包括該行長度,舊 SHA-1 值,新 SHA-1 值和將要更新的引用。 第一行也包括了客戶端的能力。 這里的全為?*0*?的 SHA-1 值表示之前沒有過這個引用——因為你正要添加新的 experiment 引用。 刪除引用時,將會看到相反的情況:右邊的 SHA-1 值全為?*0*。 接下來,客戶端會發送一個包文件,它包含了所有服務端還沒有的對象。 最后,服務端會以成功(或失敗)響應: ~~~ 000eunpack ok ~~~ #### HTTP(S) HTTPS 與 HTTP 相比較,除了在“握手”過程略有不同外,其他基本相似。 連接是從下面這個請求開始的: ~~~ => GET http://server/simplegit-progit.git/info/refs?service=git-receive-pack 001f# service=git-receive-pack 00ab6c5f0e45abd7832bf23074a333f739977c9e8188 refs/heads/master report-status \ delete-refs side-band-64k quiet ofs-delta \ agent=git/2:2.1.1~vmg-bitmaps-bugaloo-608-g116744e 0000 ~~~ 這完成了客戶端和服務端的第一次數據交換。 接下來客戶端發起另一個請求,這次是一個?`POST`?請求,這個請求中包含了?`git-upload-pack`?提供的數據。 ~~~ => POST http://server/simplegit-progit.git/git-receive-pack ~~~ 這個?`POST`?請求的內容是?`send-pack`?的輸出和相應的包文件。 服務端在收到請求后相應地作出成功或失敗的 HTTP 響應。 #### 下載數據 當你在下載數據時,?`fetch-pack`?和?`upload-pack`?進程就起作用了。 客戶端啟動?`fetch-pack`?進程,連接至遠端的?`upload-pack`?進程,以協商后續傳輸的數據。 #### SSH 如果你通過 SSH 使用抓取功能,`fetch-pack`?會像這樣運行: ~~~ $ ssh -x git@server "git-upload-pack 'simplegit-progit.git'" ~~~ 在?`fetch-pack`?連接后,`upload-pack`?會返回類似下面的內容: ~~~ 00dfca82a6dff817ec66f44342007202690a93763949 HEAD multi_ack thin-pack \ side-band side-band-64k ofs-delta shallow no-progress include-tag \ multi_ack_detailed symref=HEAD:refs/heads/master \ agent=git/2:2.1.1+github-607-gfba4028 003fe2409a098dc3e53539a9028a94b6224db9d6a6b6 refs/heads/master 0000 ~~~ 這與?`receive-pack`?的響應很相似,但是這里所包含的能力是不同的。 而且它還包含 HEAD 引用所指向內容(`symref=HEAD:refs/heads/master`),這樣如果客戶端執行的是克隆,它就會知道要檢出什么。 這時候,`fetch-pack`?進程查看它自己所擁有的對象,并響應 “want” 和它需要的對象的 SHA-1 值。 它還會發送“have”和所有它已擁有的對象的 SHA-1 值。 在列表的最后,它還會發送“done”以通知?`upload-pack`?進程可以開始發送它所需對象的包文件: ~~~ 003cwant ca82a6dff817ec66f44342007202690a93763949 ofs-delta 0032have 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7 0009done 0000 ~~~ #### HTTP(S) 抓取操作的握手需要兩個 HTTP 請求。 第一個是向和啞協議中相同的端點發送?`GET`?請求: ~~~ => GET $GIT_URL/info/refs?service=git-upload-pack 001e# service=git-upload-pack 00e7ca82a6dff817ec66f44342007202690a93763949 HEAD multi_ack thin-pack \ side-band side-band-64k ofs-delta shallow no-progress include-tag \ multi_ack_detailed no-done symref=HEAD:refs/heads/master \ agent=git/2:2.1.1+github-607-gfba4028 003fca82a6dff817ec66f44342007202690a93763949 refs/heads/master 0000 ~~~ 這和通過 SSH 使用?`git-upload-pack`?是非常相似的,但是第二個數據交換則是一個單獨的請求: ~~~ => POST $GIT_URL/git-upload-pack HTTP/1.0 0032want 0a53e9ddeaddad63ad106860237bbf53411d11a7 0032have 441b40d833fdfa93eb2908e52742248faf0ee993 0000 ~~~ 這個輸出格式還是和前面一樣的。 這個請求的響應包含了所需要的包文件,并指明成功或失敗。 ## 協議總結 這一章節是傳輸協議的一個概貌。 傳輸協議還有很多其它的特性,像是?`multi_ack`?或?`side-band`,但是這些內容已經超出了本書的范圍。 我們希望能給你展示客戶端和服務端之間的基本交互過程;如果你需要更多的相關知識,你可以參閱 Git 的源代碼。
                  <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>

                              哎呀哎呀视频在线观看