Skip to content

Commit 724ab02

Browse files
committed
Merge branch 'zwpaper-10_git_internals_transfer_protocols'
2 parents 523b7aa + 62cbad4 commit 724ab02

File tree

2 files changed

+87
-87
lines changed

2 files changed

+87
-87
lines changed
Lines changed: 86 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,57 @@
1-
=== Transfer Protocols
1+
=== 传输协议
22

3-
Git can transfer data between two repositories in two major ways: the ``dumb'' protocol and the ``smart'' protocol.
4-
This section will quickly cover how these two main protocols operate.
3+
Git 可以通过两种主要的方式在版本库之间传输数据:“哑(dumb)”协议和“智能(smart)”协议。
4+
本节将会带你快速浏览这两种协议的运作方式。
55

6-
==== The Dumb Protocol
6+
==== 哑协议
77

8-
If you're setting up a repository to be served read-only over HTTP, the dumb protocol is likely what will be used.
9-
This protocol is called ``dumb'' because it requires no Git-specific code on the server side during the transport process; the fetch process is a series of HTTP `GET` requests, where the client can assume the layout of the Git repository on the server.
8+
如果你正在架设一个基于 HTTP 协议的只读版本库,一般而言这种情况下使用的就是哑协议。
9+
这个协议之所以被称为“哑”协议,是因为在传输过程中,服务端不需要有针对 Git 特有的代码;抓取过程是一系列 HTTP `GET` 请求,这种情况下,客户端可以推断出服务端 Git 仓库的布局。
1010

1111
[NOTE]
1212
====
13-
The dumb protocol is fairly rarely used these days.
14-
It's difficult to secure or make private, so most Git hosts (both cloud-based and on-premises) will refuse to use it.
15-
It's generally advised to use the smart protocol, which we describe a bit further on.
13+
现在已经很少使用哑协议了。
14+
使用哑协议的版本库很难保证安全性和私有化,所以大多数 Git 服务器宿主(包括云端和本地)都会拒绝使用它。
15+
一般情况下都建议使用智能协议,我们会在后面进行介绍。
1616
====
1717

18-
Let's follow the `http-fetch` process for the simplegit library:
18+
让我们通过 simplegit 版本库来看看 `http-fetch` 的过程:
1919

2020
[source,console]
2121
----
2222
$ git clone http://server/simplegit-progit.git
2323
----
2424

25-
The first thing this command does is pull down the `info/refs` file.
26-
This file is written by the `update-server-info` command, which is why you need to enable that as a `post-receive` hook in order for the HTTP transport to work properly:
25+
它做的第一件事就是拉取 `info/refs` 文件。
26+
这个文件是通过 `update-server-info` 命令生成的,这也解释了在使用HTTP传输时,必须把它设置为 `post-receive` 钩子的原因:
2727

2828
[source]
2929
----
3030
=> GET info/refs
3131
ca82a6dff817ec66f44342007202690a93763949 refs/heads/master
3232
----
3333

34-
Now you have a list of the remote references and SHAs.
35-
Next, you look for what the HEAD reference is so you know what to check out when you're finished:
34+
现在,你得到了一个远程引用和 SHA 值的列表。
35+
接下来,你要确定 HEAD 引用是什么,这样你就知道在完成后应该被检出到工作目录的内容:
3636

3737
[source]
3838
----
3939
=> GET HEAD
4040
ref: refs/heads/master
4141
----
4242

43-
You need to check out the `master` branch when you've completed the process.
44-
At this point, you're ready to start the walking process.
45-
Because your starting point is the `ca82a6` commit object you saw in the `info/refs` file, you start by fetching that:
43+
这说明在完成抓取后,你需要检出 `master` 分支。
44+
这时,你就可以开始感受一下这个过程了。
45+
因为你是从 `info/refs` 文件中所提到的 `ca82a6` 提交对象开始的,所以你的首要操作是获取它:
4646

4747
[source]
4848
----
4949
=> GET objects/ca/82a6dff817ec66f44342007202690a93763949
5050
(179 bytes of binary data)
5151
----
5252

53-
You get an object back – that object is in loose format on the server, and you fetched it over a static HTTP GET request.
54-
You can zlib-uncompress it, strip off the header, and look at the commit content:
53+
你取回了一个对象——这是一个在服务端以松散格式保存的对象,是你通过使用静态 HTTP GET 请求获取的。
54+
你可以使用 zlib 解压缩它,去除其头部,查看提交记录的内容:
5555

5656
[source,console]
5757
----
@@ -64,104 +64,104 @@ committer Scott Chacon <[email protected]> 1240030591 -0700
6464
changed the version number
6565
----
6666

67-
Next, you have two more objects to retrieve – `cfda3b`, which is the tree of content that the commit we just retrieved points to; and `085bb3`, which is the parent commit:
67+
接下来,你还要再获取两个对象,一个是树对象 `cfda3b`,它包含有我们刚刚获取的提交对象所指向的内容,另一个是它的父提交 `085bb3`
6868

6969
[source]
7070
----
7171
=> GET objects/08/5bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
7272
(179 bytes of data)
7373
----
7474

75-
That gives you your next commit object.
76-
Grab the tree object:
75+
这样就取得了你的下一个提交对象。
76+
再抓取树对象:
7777

7878
[source]
7979
----
8080
=> GET objects/cf/da3bf379e4f8dba8717dee55aab78aef7f4daf
8181
(404 - Not Found)
8282
----
8383

84-
Oops – it looks like that tree object isn't in loose format on the server, so you get a 404 response back.
85-
There are a couple of reasons for this – the object could be in an alternate repository, or it could be in a packfile in this repository.
86-
Git checks for any listed alternates first:
84+
噢——看起来这个树对象在服务端并不以松散格式对象存在,所以你得到了一个 404 响应,代表在 HTTP 服务端没有找到该对象。
85+
这有好几个可能的原因——这个对象可能在替代版本库里面,或者在包文件里面。
86+
Git 会首先检查所有列出的替代版本库:
8787

8888
[source]
8989
----
9090
=> GET objects/info/http-alternates
9191
(empty file)
9292
----
9393

94-
If this comes back with a list of alternate URLs, Git checks for loose files and packfiles there – this is a nice mechanism for projects that are forks of one another to share objects on disk.
95-
However, because no alternates are listed in this case, your object must be in a packfile.
96-
To see what packfiles are available on this server, you need to get the `objects/info/packs` file, which contains a listing of them (also generated by `update-server-info`):
94+
如果这返回了一个包含替代版本库 URL 的列表,那么 Git 就会去那些地址检查松散格式对象和文件——这是一种能让派生项目共享对象以节省磁盘的好方法。
95+
然而,在这个例子中,没有列出可用的替代版本库。所以你所需要的对象肯定在某个包文件中。
96+
要检查服务端有哪些可用的包文件,你需要获取 `objects/info/packs` 文件,这里面有一个包文件列表(它也是通过执行 `update-server-info` 所生成的):
9797

9898
[source]
9999
----
100100
=> GET objects/info/packs
101101
P pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
102102
----
103103

104-
There is only one packfile on the server, so your object is obviously in there, but you'll check the index file to make sure.
105-
This is also useful if you have multiple packfiles on the server, so you can see which packfile contains the object you need:
104+
服务端只有一个包文件,所以你要的对象显然就在里面。但是你要先检查它的索引文件以确认。
105+
即使服务端有多个包文件,这也是很有用的,因为这样你就可以知道你所需要的对象是在哪一个包文件里面:
106106

107107
[source]
108108
----
109109
=> GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.idx
110110
(4k of binary data)
111111
----
112112

113-
Now that you have the packfile index, you can see if your object is in it – because the index lists the SHAs of the objects contained in the packfile and the offsets to those objects.
114-
Your object is there, so go ahead and get the whole packfile:
113+
现在你有这个包文件的索引,你可以查看你要的对象是否在里面——因为索引文件列出了这个包文件所包含的所有对象的 SHA 值,和该对象存在于包文件中的偏移量。
114+
你的对象就在这里,接下来就是获取整个包文件:
115115

116116
[source]
117117
----
118118
=> GET objects/pack/pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack
119119
(13k of binary data)
120120
----
121121

122-
You have your tree object, so you continue walking your commits.
123-
They're all also within the packfile you just downloaded, so you don't have to do any more requests to your server.
124-
Git checks out a working copy of the `master` branch that was pointed to by the HEAD reference you downloaded at the beginning.
122+
现在你也有了你的树对象,你可以继续在提交记录上漫游。
123+
它们全部都在这个你刚下载的包文件里面,所以你不用继续向服务端请求更多下载了。
124+
Git 会将开始时下载的 HEAD 引用所指向的 `master` 分支检出到工作目录。
125125

126-
==== The Smart Protocol
126+
==== 智能协议
127127

128-
The dumb protocol is simple but a bit inefficient, and it can't handle writing of data from the client to the server.
129-
The smart protocol is a more common method of transferring data, but it requires a process on the remote end that is intelligent about Git – it can read local data, figure out what the client has and needs, and generate a custom packfile for it.
130-
There are two sets of processes for transferring data: a pair for uploading data and a pair for downloading data.
128+
哑协议虽然很简单但效率略低,且它不能从客户端向服务端发送数据。
129+
智能协议是更常用的传送数据的方法,但它需要在服务端运行一个进程,而这也是 Git 的智能之处——它可以读取本地数据,理解客户端有什么和需要什么,并为它生成合适的包文件。
130+
总共有两组进程用于传输数据,它们分别负责上传和下载数据。
131131

132-
===== Uploading Data
132+
===== 上传数据
133133

134134
(((git commands, send-pack)))(((git commands, receive-pack)))
135-
To upload data to a remote process, Git uses the `send-pack` and `receive-pack` processes.
136-
The `send-pack` process runs on the client and connects to a `receive-pack` process on the remote side.
135+
为了上传数据至远端,Git 使用 `send-pack` `receive-pack` 进程。
136+
运行在客户端上的 `send-pack` 进程连接到远端运行的 `receive-pack` 进程。
137137

138138
====== SSH
139139

140-
For example, say you run `git push origin master` in your project, and `origin` is defined as a URL that uses the SSH protocol.
141-
Git fires up the `send-pack` process, which initiates a connection over SSH to your server.
142-
It tries to run a command on the remote server via an SSH call that looks something like this:
140+
举例来说,在项目中使用命令 `git push origin master` 时, `origin` 是由基于 SSH 协议的 URL 所定义的。
141+
Git 会运行 `send-pack` 进程,它会通过 SSH 连接你的服务器。
142+
它会尝试通过 SSH 在服务端执行命令,就像这样:
143143

144144
[source,console]
145145
----
146146
$ ssh -x git@server "git-receive-pack 'simplegit-progit.git'"
147147
005bca82a6dff817ec66f4437202690a93763949 refs/heads/master report-status \
148148
delete-refs side-band-64k quiet ofs-delta \
149-
agent=git/2:2.1.1+github-607-gfba4028 delete-refs
149+
agent=git/2:2.1.1+github-607-gfba4028 delete-refs
150150
003e085bb3bcb608e1e84b2432f8ecbe6306e7e7 refs/heads/topic
151151
0000
152152
----
153153

154-
The `git-receive-pack` command immediately responds with one line for each reference it currently has – in this case, just the `master` branch and its SHA.
155-
The first line also has a list of the server's capabilities (here, `report-status`, `delete-refs`, and some others, including the client identifier).
154+
`git-receive-pack` 命令会立即为它所拥有的每一个引用发送一行响应——在这个例子中,就只有 `master` 分支和它的SHA值。
155+
第一行响应中也包含了一个服务端能力的列表(这里是 `report-status``delete-refs` 和一些其它的,包括客户端的识别码)。
156156

157-
Each line starts with a 4-character hex value specifying how long the rest of the line is.
158-
Your first line starts with 005b, which is 91 in hex, meaning that 91 bytes remain on that line.
159-
The next line starts with 003e, which is 62, so you read the remaining 62 bytes.
160-
The next line is 0000, meaning the server is done with its references listing.
157+
每一行以一个四位的十六进制值开始,用于指明本行的长度。
158+
你看到第一行以 005b 开始,这在十六进制中表示 91,意味着第一行有 91 字节。
159+
下一行以 003e 起始,也就是 62,所以下面需要读取 62 字节。
160+
再下一行是 0000,表示服务端已完成了发送引用列表过程。
161161

162-
Now that it knows the server's state, your `send-pack` process determines what commits it has that the server doesn't.
163-
For each reference that this push will update, the `send-pack` process tells the `receive-pack` process that information.
164-
For instance, if you're updating the `master` branch and adding an `experiment` branch, the `send-pack` response may look something like this:
162+
现在它知道了服务端的状态,你的 `send-pack` 进程会判断哪些提交记录是它所拥有但服务端没有的。
163+
`send-pack` 会告知 `receive-pack` 这次推送将会更新的各个引用。
164+
举个例子,如果你正在更新 `master` 分支,并且增加 `experiment` 分支,这个 `send-pack` 的响应将会是像这样:
165165

166166
[source]
167167
----
@@ -172,13 +172,13 @@ For instance, if you're updating the `master` branch and adding an `experiment`
172172
0000
173173
----
174174

175-
Git sends a line for each reference you're updating with the line's length, the old SHA, the new SHA, and the reference that is being updated.
176-
The first line also has the client's capabilities.
177-
The SHA-1 value of all '0's means that nothing was there before – because you're adding the experiment reference.
178-
If you were deleting a reference, you would see the opposite: all '0's on the right side.
175+
Git 会为每一个将要更新的引用发送一行数据,包括该行长度,旧 SHA 值,新 SHA 值和将要更新的引用。
176+
第一行也包括了客户端的能力。
177+
这里的全为 '0' 的 SHA-1 值表示之前没有过这个引用——因为你正要添加新的 experiment 引用。
178+
删除引用时,将会看到相反的情况:右边的 SHA-1 值全为 '0'
179179

180-
Next, the client sends a packfile of all the objects the server doesn't have yet.
181-
Finally, the server responds with a success (or failure) indication:
180+
接下来,客户端会发送一个包文件,它包含了所有服务端还没有的对象。
181+
最后,服务端会以成功(或失败)响应:
182182

183183
[source]
184184
----
@@ -187,8 +187,8 @@ Finally, the server responds with a success (or failure) indication:
187187

188188
====== HTTP(S)
189189

190-
This process is mostly the same over HTTP, though the handshaking is a bit different.
191-
The connection is initiated with this request:
190+
HTTPS 与 HTTP 相比较,除了在“握手”过程略有不同外,其他基本相似。
191+
连接是从下面这个请求开始的:
192192

193193
[source]
194194
----
@@ -200,33 +200,33 @@ The connection is initiated with this request:
200200
0000
201201
----
202202

203-
That's the end of the first client-server exchange.
204-
The client then makes another request, this time a `POST`, with the data that `git-upload-pack` provides.
203+
这完成了客户端和服务端的第一次数据交换。
204+
接下来客户端发起另一个请求,这次是一个 `POST` 请求,这个请求中包含了 `git-upload-pack` 提供的数据。
205205

206206
[source]
207207
----
208208
=> POST http://server/simplegit-progit.git/git-receive/pack
209209
----
210210

211-
The `POST` request includes the `send-pack` output and the packfile as its payload.
212-
The server then indicates success or failure with its HTTP response.
211+
这个 `POST` 请求的内容是 `send-pack` 的输出和相应的包文件。
212+
服务端在收到请求后相应地作出成功或失败的 HTTP 响应。
213213

214-
===== Downloading Data
214+
===== 下载数据
215215

216216
(((git commands, fetch-pack)))(((git commands, upload-pack)))
217-
When you download data, the `fetch-pack` and `upload-pack` processes are involved.
218-
The client initiates a `fetch-pack` process that connects to an `upload-pack` process on the remote side to negotiate what data will be transferred down.
217+
当你在下载数据时, `fetch-pack` `upload-pack` 进程就起作用了。
218+
客户端启动 `fetch-pack` 进程,连接至远端的 `upload-pack` 进程,以协商后续传输的数据。
219219

220220
====== SSH
221221

222-
If you're doing the fetch over SSH, `fetch-pack` instead runs something like this:
222+
如果你通过 SSH 使用抓取功能,`fetch-pack` 会像这样运行:
223223

224224
[source,console]
225225
----
226226
$ ssh -x git@server "git-upload-pack 'simplegit-progit.git'"
227227
----
228228

229-
After `fetch-pack` connects, `upload-pack` sends back something like this:
229+
`fetch-pack` 连接后,`upload-pack` 会返回类似下面的内容:
230230

231231
[source]
232232
----
@@ -238,12 +238,12 @@ After `fetch-pack` connects, `upload-pack` sends back something like this:
238238
0000
239239
----
240240

241-
This is very similar to what `receive-pack` responds with, but the capabilities are different.
242-
In addition, it sends back what HEAD points to (`symref=HEAD:refs/heads/master`) so the client knows what to check out if this is a clone.
241+
这与 `receive-pack` 的响应很相似,但是这里所包含的能力是不同的。
242+
而且它还包含 HEAD 引用所指向内容(`symref=HEAD:refs/heads/master`),这样如果客户端执行的是克隆,它就会知道要检出什么。
243243

244-
At this point, the `fetch-pack` process looks at what objects it has and responds with the objects that it needs by sending ``want'' and then the SHA it wants.
245-
It sends all the objects it already has with ``have'' and then the SHA.
246-
At the end of this list, it writes ``done'' to initiate the `upload-pack` process to begin sending the packfile of the data it needs:
244+
这时候,`fetch-pack` 进程查看它自己所拥有的对象,并响应“want”和它需要的对象的 SHA 值。
245+
它还会发送“have”和所有它已拥有的对象的 SHA 值。
246+
在列表的最后,它还会发送“done”以通知 `upload-pack` 进程可以开始发送它所需对象的包文件:
247247

248248
[source]
249249
----
@@ -255,8 +255,8 @@ At the end of this list, it writes ``done'' to initiate the `upload-pack` proces
255255

256256
====== HTTP(S)
257257

258-
The handshake for a fetch operation takes two HTTP requests.
259-
The first is a `GET` to the same endpoint used in the dumb protocol:
258+
抓取操作的握手需要两个 HTTP 请求。
259+
第一个是向和哑协议中相同的端点发送 `GET` 请求:
260260

261261
[source]
262262
----
@@ -270,7 +270,7 @@ The first is a `GET` to the same endpoint used in the dumb protocol:
270270
0000
271271
----
272272

273-
This is very similar to invoking `git-upload-pack` over an SSH connection, but the second exchange is performed as a separate request:
273+
这和通过 SSH 使用 `git-upload-pack` 是非常相似的,但是第二个数据交换则是一个单独的请求:
274274

275275
[source]
276276
----
@@ -280,11 +280,11 @@ This is very similar to invoking `git-upload-pack` over an SSH connection, but t
280280
0000
281281
----
282282

283-
Again, this is the same format as above.
284-
The response to this request indicates success or failure, and includes the packfile.
283+
这个输出格式还是和前面一样的。
284+
这个请求的响应包含了所需要的包文件,并指明成功或失败。
285285

286-
==== Protocols Summary
286+
==== 协议总结
287287

288-
This section contains a very basic overview of the transfer protocols.
289-
The protocol includes many other features, such as `multi_ack` or `side-band` capabilities, but covering them is outside the scope of this book.
290-
We've tried to give you a sense of the general back-and-forth between client and server; if you need more knowledge than this, you'll probably want to take a look at the Git source code.
288+
这一章节是传输协议的一个概貌。
289+
传输协议还有很多其它的特性,像是 `multi_ack` `side-band`,但是这些内容已经超出了本书的范围。
290+
我们希望能给你展示客户端和服务端之间的基本交互过程;如果你需要更多的相关知识,你可以参阅 Git 的源代码。

status.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@
105105
"sections/plumbing-porcelain.asc": 100,
106106
"sections/refs.asc": 100,
107107
"sections/refspec.asc": 100,
108-
"sections/transfer-protocols.asc": 0
108+
"sections/transfer-protocols.asc": 100
109109
},
110110
"A-git-in-other-environments": {
111111
"1-git-other-environments.asc": 50,

0 commit comments

Comments
 (0)