From b6fa9cf01b8ecc42db2b7bb25b37c51da6a04a7c Mon Sep 17 00:00:00 2001 From: Kyrylo Yatsenko Date: Wed, 9 Dec 2015 21:59:19 +0200 Subject: [PATCH 1/2] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BA=D0=BB=D0=B0?= =?UTF-8?q?=D0=B4=2010-git-internals=20transfer-protocols.asc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sections/transfer-protocols.asc | 170 +++++++++--------- status.json | 2 +- 2 files changed, 86 insertions(+), 86 deletions(-) diff --git a/book/10-git-internals/sections/transfer-protocols.asc b/book/10-git-internals/sections/transfer-protocols.asc index c3c0b9a8..939342cd 100644 --- a/book/10-git-internals/sections/transfer-protocols.asc +++ b/book/10-git-internals/sections/transfer-protocols.asc @@ -1,29 +1,29 @@ -=== Transfer Protocols +=== Протоколи передачі -Git can transfer data between two repositories in two major ways: the ``dumb'' protocol and the ``smart'' protocol. -This section will quickly cover how these two main protocols operate. +Git може передавати дані між двома репозиторіями двома головними способами: ``тупим'' протоколом та ``розумним''. +Ця секція швидке розгляне, як ці два головні протоколи працюють. -==== The Dumb Protocol +==== Тупий протокол -If you're setting up a repository to be served read-only over HTTP, the dumb protocol is likely what will be used. -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. +Якщо ви налаштовуєте репозиторій, щоб він був доступним лише для читання через HTTP, то, напевно, ви використаєте тупий протокол. +Цей протокол називається ``тупим'', оскільки він не вимагає жодного специфічного для Git коду з боку сервера впродовж процесу передачі; процес отримання даних -- це просто низка HTTP запитів `GET`, в яких клієнти можуть припустити, як розташовано репозиторій Git на сервері. [NOTE] ==== -The dumb protocol is fairly rarely used these days. -It's difficult to secure or make private, so most Git hosts (both cloud-based and on-premises) will refuse to use it. -It's generally advised to use the smart protocol, which we describe a bit further on. +Нині тупий протокол доволі зрідка використовується. +Його важко зробити безпечним чи приватним, отже більшість серверів розгортання Git (як хмарних, як і особистих) відмовляються ним користуватись. +Зазвичай варто використовувати розумний протокол, який буде описано трохи далі. ==== -Let's follow the `http-fetch` process for the simplegit library: +Прослідкуймо за процесом `http-fetch` для бібліотеки simplegit: [source,console] ---- $ git clone http://server/simplegit-progit.git ---- -The first thing this command does is pull down the `info/refs` file. -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: +Спершу ця команда отримає файл `info/refs`. +Цей файл записується командою `update-server-info`, тому вам треба ввімкнути її в гаку `post-receive`, щоб HTTP транспорт працював правильно: [source] ---- @@ -31,8 +31,8 @@ This file is written by the `update-server-info` command, which is why you need ca82a6dff817ec66f44342007202690a93763949 refs/heads/master ---- -Now you have a list of the remote references and SHA-1s. -Next, you look for what the HEAD reference is so you know what to check out when you're finished: +Тепер у вас є список віддалених посилань та SHA-1 сум. +Далі, вам потрібне посилання HEAD, щоб ви знали, на яку гілку переключитись після завершення: [source] ---- @@ -40,9 +40,9 @@ Next, you look for what the HEAD reference is so you know what to check out when ref: refs/heads/master ---- -You need to check out the `master` branch when you've completed the process. -At this point, you're ready to start the walking process. -Because your starting point is the `ca82a6` commit object you saw in the `info/refs` file, you start by fetching that: +Вам треба переключитись на гілку `master` після завершення процесу. +Наразі, ви готові починати обхід. +Через те, що ви починаєте з об’єкту коміту `ca82a6`, який ви бачили у файлі `info/refs`, треба спочатку отримати його: [source] ---- @@ -50,8 +50,8 @@ Because your starting point is the `ca82a6` commit object you saw in the `info/r (179 bytes of binary data) ---- -You get an object back – that object is in loose format on the server, and you fetched it over a static HTTP GET request. -You can zlib-uncompress it, strip off the header, and look at the commit content: +Ви отримуєте об’єкт – цей об’єкт знаходиться у вільному форматі на сервері, і ви отримали його статичним запитом HTTP GET. +Ви можете розтиснути його за допомогою zlib, відкинути заголовок, та подивитись на вміст коміту: [source,console] ---- @@ -64,7 +64,7 @@ committer Scott Chacon 1240030591 -0700 changed the version number ---- -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: +Далі, вам треба отримати ще два об’єкти – `cfda3b`, який є деревом вмісту, на який вказує щойно отриманий коміт; а також `085bb3`, який є батьківським комітом: [source] ---- @@ -72,8 +72,8 @@ Next, you have two more objects to retrieve – `cfda3b`, which is the tree of c (179 bytes of data) ---- -That gives you your next commit object. -Grab the tree object: +Це надає нам об’єкт наступного коміту. +Хапайте об’єкт дерева: [source] ---- @@ -81,9 +81,9 @@ Grab the tree object: (404 - Not Found) ---- -Oops – it looks like that tree object isn't in loose format on the server, so you get a 404 response back. -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. -Git checks for any listed alternates first: +Овва – здається, цього об’єкту дерева немає у вільному форматі на сервері, тому ви отримали відповідь 404. +Є декілька причин для цього – об’єкт може бути в альтернативному сховищі, або він може бути у файлі пакунку цього репозиторію. +Git перевіряє спочатку задані альтернативи: [source] ---- @@ -91,9 +91,9 @@ Git checks for any listed alternates first: (empty file) ---- -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. -However, because no alternates are listed in this case, your object must be in a packfile. -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`): +Якщо це поверне список альтернативних URL, Git перевірить вільні файли та пакунки там – це зручний засіб для проектів, які є форками інших, щоб спільно користуватись об’єктами на диску. +Втім, оскільки в даному випадку жодної альтернативи не зазначено, ваш об’єкт має бути у файлі пакунків. +Щоб побачити, чи існує файл пакунків на цьому сервері, вам треба отримати файл `objects/info/packs`, який містить їх список (також згенерований командою `update-server-info`): [source] ---- @@ -101,8 +101,8 @@ To see what packfiles are available on this server, you need to get the `objects P pack-816a9b2334da9953e530f27bcac22082a9f5b835.pack ---- -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. -This is also useful if you have multiple packfiles on the server, so you can see which packfile contains the object you need: +Існує лише один файл пакунок на сервері, отже, очевидно, ваш об’єкт знаходиться там, проте ви перевірите файл індексу, щоб переконатись. +Це також корисно, якщо у вас декілька файлів пакунків на сервері, щоб ви могли побачити, який з них містить потрібний об’єкт: [source] ---- @@ -110,8 +110,8 @@ This is also useful if you have multiple packfiles on the server, so you can see (4k of binary data) ---- -Now that you have the packfile index, you can see if your object is in it – because the index lists the SHA-1s of the objects contained in the packfile and the offsets to those objects. -Your object is there, so go ahead and get the whole packfile: +Тепер, коли у вас є індекс пакунку, ви можете перевірити, чи є там ваш об’єкт – адже індекс надає список SHA-1 сум об’єктів, які містяться в пакунку, та зсуви до них. +Ваш об’єкт там, отже уперед отримувати весь пакунок: [source] ---- @@ -119,27 +119,27 @@ Your object is there, so go ahead and get the whole packfile: (13k of binary data) ---- -You have your tree object, so you continue walking your commits. -They're all also within the packfile you just downloaded, so you don't have to do any more requests to your server. -Git checks out a working copy of the `master` branch that was pointed to by the HEAD reference you downloaded at the beginning. +У вас є об’єкт дерева, отже ви продовжуєте обходити ваші коміти. +Вони всі також у щойно завантаженому пакунку, отже вам не доводиться більше робити запитів до сервера. +Git створює робочу копію гілки `master`, на яку вказувало посилання HEAD, яке ви завантажили спочатку. -==== The Smart Protocol +==== Розумний протокол -The dumb protocol is simple but a bit inefficient, and it can't handle writing of data from the client to the server. -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. -There are two sets of processes for transferring data: a pair for uploading data and a pair for downloading data. +Тупий протокол простий, проте нефективний, та не може писати дані клієнта до сервера. +Розумний протокол є більш поширеним методом передачі даних, проте вимагає, щоб на віддаленому сервері був процес, який знає про Git – він може читати локальні дані, зрозуміти, що потрібно клієнту, та згенерувати окремий пакунок для нього. +Є два набори процесів для передачі даних: пара для відвантаження даних та пара для завантаження даних. -===== Uploading Data +===== Відвантаження даних (((git commands, send-pack)))(((git commands, receive-pack))) -To upload data to a remote process, Git uses the `send-pack` and `receive-pack` processes. -The `send-pack` process runs on the client and connects to a `receive-pack` process on the remote side. +Щоб відвантажити дані до віддаленого процесу, Git використовує процеси `send-pack` та `receive-pack`. +Процес `send-pack` працює на клієнті та під’єднується до процесу `receive-pack` на віддаленому боці. ====== SSH -For example, say you run `git push origin master` in your project, and `origin` is defined as a URL that uses the SSH protocol. -Git fires up the `send-pack` process, which initiates a connection over SSH to your server. -It tries to run a command on the remote server via an SSH call that looks something like this: +Наприклад, скажімо, що ви виконуєте `git push origin master` в своєму проекті, а `origin` визначено як URL, який використовує протокол SSH. +Git запускає процес `send-pack`, який починає взаємодію SSH з вашим сервером. +Він намагається виконати команду на віддаленому сервері через SSH виклик, який виглядає приблизно так: [source,console] ---- @@ -151,17 +151,17 @@ $ ssh -x git@server "git-receive-pack 'simplegit-progit.git'" 0000 ---- -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-1. -The first line also has a list of the server's capabilities (here, `report-status`, `delete-refs`, and some others, including the client identifier). +Команда `git-receive-pack` негайно відповідає одним рядком для кожного посилання, яке сервер наразі має – у даному випадку, лише гілка `master` та її SHA-1. +Перший рядок також має список можливостей сервера (тут, `report-status`, `delete-refs`, а також деякі інші, включно з ідентифікатором клієнта). -Each line starts with a 4-character hex value specifying how long the rest of the line is. -Your first line starts with 005b, which is hexadecimal for 91, meaning that 91 bytes remain on that line. -The next line starts with 003e, which is 62, so you read the remaining 62 bytes. -The next line is 0000, meaning the server is done with its references listing. +Кожен рядок починається з чотирьохсимвольного шістнадцяткове значення, яке задає, наскільки довгою є решта рядка. +Ваш перший рядок починається з 005b, що шістнадцятковою означає 91, тобто в цьому рядку ще 91 байт. +Наступний починається з 003e, тобто 62, отже вам треба зчитати решту 62 байти. +Наступний рядок 0000, що означає, що сервер закінчив перелічування посилань. -Now that it knows the server's state, your `send-pack` process determines what commits it has that the server doesn't. -For each reference that this push will update, the `send-pack` process tells the `receive-pack` process that information. -For instance, if you're updating the `master` branch and adding an `experiment` branch, the `send-pack` response may look something like this: +Тепер, коли `send-pack` знає стан сервера, він може визначити, які коміти в нього є, а у сервера немає. +Для кожного посилання, яки цей push буде оновлювати, процес `send-pack` надає процесу `receive-pack` цю інформацію. +Наприклад, якщо ви оновлюєте гілку `master` та додаєте гілку `experiment`, то відповідь `send-pack` може виглядати так: [source] ---- @@ -172,13 +172,13 @@ For instance, if you're updating the `master` branch and adding an `experiment` 0000 ---- -Git sends a line for each reference you're updating with the line's length, the old SHA-1, the new SHA-1, and the reference that is being updated. -The first line also has the client's capabilities. -The SHA-1 value of all '0's means that nothing was there before – because you're adding the experiment reference. -If you were deleting a reference, you would see the opposite: all '0's on the right side. +Git надсилає рядок для кожного посилання, яке ви оновлюєте, з довжиною рядка, старим SHA-1, новим SHA-1, та посиланням, яке оновлюється. +Перший рядок також містить можливості клієнта. +Значення SHA-1 зі всіма нулями означає, що раніше нічого не було – оскільки ви додаєте посилання experiment. +Якщо ви вилучаєте посилання, от буде навпаки: всі нулі з правого боку. -Next, the client sends a packfile of all the objects the server doesn't have yet. -Finally, the server responds with a success (or failure) indication: +Далі, клієнт надсилає пакунок, що містить усі об’єкти, яких ще немає на сервері. +Нарешті, сервер відповідає успіхом чи провалом. [source] ---- @@ -187,8 +187,8 @@ Finally, the server responds with a success (or failure) indication: ====== HTTP(S) -This process is mostly the same over HTTP, though the handshaking is a bit different. -The connection is initiated with this request: +Цей процес майже такий самий через HTTP, хоча квитування трохи інше. +Зв’язок починається з такого запиту: [source] ---- @@ -200,33 +200,33 @@ The connection is initiated with this request: 0000 ---- -That's the end of the first client-server exchange. -The client then makes another request, this time a `POST`, with the data that `git-upload-pack` provides. +Це кінець першого обміну клієнта сервера. +Клієнт потім робить ще один запит, цього разу `POST`, з даними, які надає `git-upload-pack`. [source] ---- => POST http://server/simplegit-progit.git/git-receive-pack ---- -The `POST` request includes the `send-pack` output and the packfile as its payload. -The server then indicates success or failure with its HTTP response. +Запит `POST` включає вивід `send-pack`, а також пакунок, як тіло запиту. +Сервер потім зазначає успіх чи провал за допомогою відповіді HTTP. -===== Downloading Data +===== Завантаження даних (((git commands, fetch-pack)))(((git commands, upload-pack))) -When you download data, the `fetch-pack` and `upload-pack` processes are involved. -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. +Коли ви завантажуєте дані, задіяно процеси `fetch-pack` та `upload-pack`. +Клієнт запускає процес `fetch-pack`, який зв’язується з процесом `upload-pack` на віддаленому сервері, щоб дізнатися, які дані буде передано. ====== SSH -If you're doing the fetch over SSH, `fetch-pack` runs something like this: +Якщо ви отримуєте дані через SSH, то `fetch-pack` виконує щось схоже на: [source,console] ---- $ ssh -x git@server "git-upload-pack 'simplegit-progit.git'" ---- -After `fetch-pack` connects, `upload-pack` sends back something like this: +Після того, як `fetch-pack` підключається, `upload-pack` надсилає щось таке: [source] ---- @@ -238,12 +238,12 @@ After `fetch-pack` connects, `upload-pack` sends back something like this: 0000 ---- -This is very similar to what `receive-pack` responds with, but the capabilities are different. -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. +Це дуже схоже на те, як відповідає `receive-pack`, проте можливості (capabilities) інші. +На додаток, він відправляє те, на що вказує HEAD (`symref=HEAD:refs/heads/master`), отже клієнт знає, на що переключитись, якщо йде клонування. -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-1 it wants. -It sends all the objects it already has with ``have'' and then the SHA-1. -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: +Тепер, процес `fetch-pack` дивиться, які об’єкти в нього є, та відповідає об’єктами, які йому потрібні, для чого надсилає ``want'' (хочу) та потім SHA-1, які бажає. +Він надсилає всі об’єкти, які в нього вже є з позначкою ``have'' (маю), а потім SHA-1. +Наприкінці цього списку, він пише ``done'' (готово), щоб процес `upload-pack` почав надсилати пакунок з необхідними даними: [source] ---- @@ -255,8 +255,8 @@ At the end of this list, it writes ``done'' to initiate the `upload-pack` proces ====== HTTP(S) -The handshake for a fetch operation takes two HTTP requests. -The first is a `GET` to the same endpoint used in the dumb protocol: +Квитування для операції отримання потребує двох HTTP запитів. +Перший -- це `GET` до тієї ж кінцевої точки, яку використовував тупий протокол: [source] ---- @@ -270,7 +270,7 @@ The first is a `GET` to the same endpoint used in the dumb protocol: 0000 ---- -This is very similar to invoking `git-upload-pack` over an SSH connection, but the second exchange is performed as a separate request: +Це дуже схоже на виклик `git-upload-pack` через SSH зв’язок, проте другий обмін здійснюється як окремий запит: [source] ---- @@ -280,11 +280,11 @@ This is very similar to invoking `git-upload-pack` over an SSH connection, but t 0000 ---- -Again, this is the same format as above. -The response to this request indicates success or failure, and includes the packfile. +Знову, це той самий формат, що й вище. +Відповідь на цей запит містить успіх або провал, та включає пакунок. -==== Protocols Summary +==== Підсумок щодо протоколів -This section contains a very basic overview of the transfer protocols. -The protocol includes many other features, such as `multi_ack` or `side-band` capabilities, but covering them is outside the scope of this book. -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. +Друга секція містить дуже базовий огляд протоколів передачі. +Протокол включає багато іншого функціоналу, такого як можливості `multi_ack` чи `sde-band`, проте їх розгляд виходить за межі цієї книги. +Ми намагались дати вам розуміння загальної взаємодії між клієнтом та сервером; якщо вам потрібно більше інформації, то ви напевно забажаєте подивитись у вихідний код Git. diff --git a/status.json b/status.json index 0bdb50a9..8d0bbb51 100644 --- a/status.json +++ b/status.json @@ -104,7 +104,7 @@ "sections/plumbing-porcelain.asc": 0, "sections/refs.asc": 0, "sections/refspec.asc": 0, - "sections/transfer-protocols.asc": 0 + "sections/transfer-protocols.asc": 100 }, "A-git-in-other-environments": { "1-git-other-environments.asc": 0, From 98ad4f8de318ecb1bc78dc51ec486421e2777aac Mon Sep 17 00:00:00 2001 From: Kyrylo Yatsenko Date: Sat, 5 Mar 2016 08:21:23 +0200 Subject: [PATCH 2/2] =?UTF-8?q?=D0=92=D0=B8=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=BD=D1=8F=20=D0=B7=D0=B0=D1=83=D0=B2=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sections/transfer-protocols.asc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/book/10-git-internals/sections/transfer-protocols.asc b/book/10-git-internals/sections/transfer-protocols.asc index 939342cd..dcbcda00 100644 --- a/book/10-git-internals/sections/transfer-protocols.asc +++ b/book/10-git-internals/sections/transfer-protocols.asc @@ -1,7 +1,7 @@ === Протоколи передачі Git може передавати дані між двома репозиторіями двома головними способами: ``тупим'' протоколом та ``розумним''. -Ця секція швидке розгляне, як ці два головні протоколи працюють. +У цій секції швидко розглянемо, як ці два головні протоколи працюють. ==== Тупий протокол @@ -10,7 +10,7 @@ Git може передавати дані між двома репозитор [NOTE] ==== -Нині тупий протокол доволі зрідка використовується. +Нині тупий протокол використовується доволі зрідка. Його важко зробити безпечним чи приватним, отже більшість серверів розгортання Git (як хмарних, як і особистих) відмовляються ним користуватись. Зазвичай варто використовувати розумний протокол, який буде описано трохи далі. ==== @@ -151,16 +151,16 @@ $ ssh -x git@server "git-receive-pack 'simplegit-progit.git'" 0000 ---- -Команда `git-receive-pack` негайно відповідає одним рядком для кожного посилання, яке сервер наразі має – у даному випадку, лише гілка `master` та її SHA-1. +Команда `git-receive-pack` негайно відповідає одним рядком для кожного посилання, яке сервер наразі має – у цьому випадку лише гілка `master` та її SHA-1. Перший рядок також має список можливостей сервера (тут, `report-status`, `delete-refs`, а також деякі інші, включно з ідентифікатором клієнта). -Кожен рядок починається з чотирьохсимвольного шістнадцяткове значення, яке задає, наскільки довгою є решта рядка. +Кожен рядок починається з чотирьохсимвольного шістнадцяткового значення, яке задає, наскільки довгою є решта рядка. Ваш перший рядок починається з 005b, що шістнадцятковою означає 91, тобто в цьому рядку ще 91 байт. Наступний починається з 003e, тобто 62, отже вам треба зчитати решту 62 байти. Наступний рядок 0000, що означає, що сервер закінчив перелічування посилань. Тепер, коли `send-pack` знає стан сервера, він може визначити, які коміти в нього є, а у сервера немає. -Для кожного посилання, яки цей push буде оновлювати, процес `send-pack` надає процесу `receive-pack` цю інформацію. +Для кожного посилання, яке цей push буде оновлювати, процес `send-pack` надає процесу `receive-pack` цю інформацію. Наприклад, якщо ви оновлюєте гілку `master` та додаєте гілку `experiment`, то відповідь `send-pack` може виглядати так: [source] @@ -175,10 +175,10 @@ $ ssh -x git@server "git-receive-pack 'simplegit-progit.git'" Git надсилає рядок для кожного посилання, яке ви оновлюєте, з довжиною рядка, старим SHA-1, новим SHA-1, та посиланням, яке оновлюється. Перший рядок також містить можливості клієнта. Значення SHA-1 зі всіма нулями означає, що раніше нічого не було – оскільки ви додаєте посилання experiment. -Якщо ви вилучаєте посилання, от буде навпаки: всі нулі з правого боку. +Якщо ви вилучаєте посилання, то буде навпаки: всі нулі з правого боку. Далі, клієнт надсилає пакунок, що містить усі об’єкти, яких ще немає на сервері. -Нарешті, сервер відповідає успіхом чи провалом. +Нарешті, сервер відповідає успіхом чи невдачею. [source] ---- @@ -238,10 +238,10 @@ $ ssh -x git@server "git-upload-pack 'simplegit-progit.git'" 0000 ---- -Це дуже схоже на те, як відповідає `receive-pack`, проте можливості (capabilities) інші. +Це дуже схоже на те, як відповідає `receive-pack`, проте можливості інші. На додаток, він відправляє те, на що вказує HEAD (`symref=HEAD:refs/heads/master`), отже клієнт знає, на що переключитись, якщо йде клонування. -Тепер, процес `fetch-pack` дивиться, які об’єкти в нього є, та відповідає об’єктами, які йому потрібні, для чого надсилає ``want'' (хочу) та потім SHA-1, які бажає. +Тепер, процес `fetch-pack` дивиться які об’єкти в нього є, та відповідає об’єктами, які йому потрібні, для чого надсилає ``want'' (хочу) та потім SHA-1, які бажає. Він надсилає всі об’єкти, які в нього вже є з позначкою ``have'' (маю), а потім SHA-1. Наприкінці цього списку, він пише ``done'' (готово), щоб процес `upload-pack` почав надсилати пакунок з необхідними даними: