Spec-Zone.ru › Git

gitprotocol-http

Название

gitprotocol-http — протоколы Git на основе HTTP

Краткое описание

<over-the-wire-protocol>

Описание

Git поддерживает два протокола передачи данных на основе HTTP. «Тупой» протокол, для работы которого на стороне сервера требуется только стандартный HTTP-сервер, и «умный» протокол, для которого необходим CGI (или модуль сервера), поддерживающий Git. В этом документе описаны оба протокола.

Особенность архитектуры заключается в том, что умные клиенты могут автоматически преобразовывать URL «тупого» протокола в URL умного протокола. Это позволяет всем пользователям указывать один и тот же опубликованный URL, а узлам автоматически выбирать наиболее эффективный доступный транспорт.

Формат URL

URL репозиториев Git, доступ к которым осуществляется через HTTP, используют стандартный синтаксис URL HTTP, описанный в RFC 1738, поэтому имеют следующий вид:

http://<host>:<port>/<path>?<searchpart>

В этом документе заполнитель $GIT_URL обозначает URL репозитория http://, указанный конечным пользователем.

Серверы ДОЛЖНЫ обрабатывать все запросы к расположениям, соответствующим $GIT_URL, поскольку и «умный», и «тупой» протоколы HTTP, используемые Git, добавляют дополнительные компоненты пути в конец строки $GIT_URL, указанной пользователем.

Пример запроса «тупого» клиента для получения свободного объекта:

$GIT_URL:     http://example.com:8080/git/repo.git
URL request:  http://example.com:8080/git/repo.git/objects/d0/49f6c27a2244e12041955e262a404c7faba355

Пример «умного» запроса к шлюзу, обрабатывающему все запросы:

$GIT_URL:     http://example.com/daemon.cgi?svc=git&q=
URL request:  http://example.com/daemon.cgi?svc=git&q=/info/refs&service=git-receive-pack

Пример запроса к подмодулю:

$GIT_URL:     http://example.com/git/repo.git/path/submodule.git
URL request:  http://example.com/git/repo.git/path/submodule.git/info/refs

Клиенты ДОЛЖНЫ удалять завершающий символ /, если он присутствует, из строки $GIT_URL, указанной пользователем, чтобы в URL, отправляемых серверу, не появлялись пустые компоненты пути (//). Совместимые клиенты ДОЛЖНЫ раскрывать $GIT_URL/info/refs как foo/info/refs, а не как foo//info/refs.

Аутентификация

Если для доступа к репозиторию требуется аутентификация, используется стандартная аутентификация HTTP; она МОЖЕТ быть настроена и включена программным обеспечением HTTP-сервера.

Поскольку доступ к репозиториям Git осуществляется с использованием стандартных компонентов пути, администраторы серверов МОГУТ применять на HTTP-сервере разрешения на основе каталогов для управления доступом к репозиториям.

Клиенты ДОЛЖНЫ поддерживать базовую аутентификацию, описанную в RFC 2617. Серверы ДОЛЖНЫ поддерживать базовую аутентификацию, используя HTTP-сервер, расположенный перед программным обеспечением Git-сервера.

Серверы НЕ ДОЛЖНЫ требовать HTTP-cookie для аутентификации или управления доступом.

Клиенты и серверы МОГУТ поддерживать другие распространённые формы аутентификации на основе HTTP, например дайджест-аутентификацию.

SSL

Клиенты и серверы ДОЛЖНЫ поддерживать SSL, особенно для защиты паролей при использовании базовой аутентификации HTTP.

Состояние сеанса

С точки зрения HTTP-сервера протокол Git поверх HTTP (как и сам HTTP) не хранит состояние. Всё состояние ДОЛЖНО сохраняться и управляться клиентским процессом. Это позволяет выполнять простую циклическую балансировку нагрузки на стороне сервера без необходимости управлять состоянием.

Для корректной работы клиенты НЕ ДОЛЖНЫ требовать управления состоянием на стороне сервера.

Для корректной работы серверы НЕ ДОЛЖНЫ требовать HTTP-cookie. Клиенты МОГУТ сохранять и пересылать HTTP-cookie при обработке запросов, как описано в RFC 2616 (HTTP/1.1). Серверы ДОЛЖНЫ игнорировать cookie, отправленные клиентом.

Общая обработка запросов

Если не указано иное, клиент и сервер ДОЛЖНЫ исходить из стандартного поведения HTTP. Оно включает, помимо прочего:

Если по адресу $GIT_URL нет репозитория или не существует ресурс, на который указывает расположение, соответствующее $GIT_URL, сервер НЕ ДОЛЖЕН возвращать ответ 200 OK. Сервер ДОЛЖЕН возвращать 404 Not Found, 410 Gone или другой подходящий код состояния HTTP, который не подразумевает, что запрошенный ресурс существует.

Если по адресу $GIT_URL есть репозиторий, но доступ к нему в данный момент запрещён, сервер ДОЛЖЕН вернуть код состояния HTTP 403 Forbidden.

Серверы ДОЛЖНЫ поддерживать HTTP 1.0 и HTTP 1.1. Серверы ДОЛЖНЫ поддерживать передачу тел запросов и ответов с использованием блочного кодирования.

Клиенты ДОЛЖНЫ поддерживать HTTP 1.0 и HTTP 1.1. Клиенты ДОЛЖНЫ поддерживать передачу тел запросов и ответов с использованием блочного кодирования.

Серверы МОГУТ возвращать заголовки ETag и/или Last-Modified.

Клиенты МОГУТ повторно проверять кэшированные сущности, добавляя в запрос заголовки If-Modified-Since и/или If-None-Match.

Если в запросе присутствуют соответствующие заголовки, а сущность не изменилась, серверы МОГУТ возвращать 304 Not Modified. Клиенты ДОЛЖНЫ обрабатывать 304 Not Modified так же, как 200 OK, повторно используя кэшированную сущность.

Клиенты МОГУТ повторно использовать кэшированную сущность без повторной проверки, если заголовок Cache-Control и/или Expires разрешает кэширование. Клиенты и серверы ДОЛЖНЫ соблюдать правила управления кэшем, изложенные в RFC 2616.

Обнаружение ссылок

Все HTTP-клиенты ДОЛЖНЫ начинать обмен данными для получения или отправки, обнаруживая ссылки, доступные в удалённом репозитории.

«Тупые» клиенты

HTTP-клиенты, поддерживающие только «тупой» протокол, ДОЛЖНЫ обнаруживать ссылки, отправляя запрос к специальному файлу info/refs репозитория.

«Тупые» HTTP-клиенты ДОЛЖНЫ отправлять запрос GET к $GIT_URL/info/refs без параметров поиска или запроса.

C: GET $GIT_URL/info/refs HTTP/1.0
S: 200 OK
S:
S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31        refs/heads/maint
S: d049f6c27a2244e12041955e262a404c7faba355        refs/heads/master
S: 2cb58b79488a98d2721cea644875a8dd0026b115        refs/tags/v1.0
S: a3c2e2402b99163d1d59756e5f207ae21cccba4c        refs/tags/v1.0^{}

Тип Content-Type возвращаемой сущности info/refs ДОЛЖЕН быть text/plain; charset=utf-8, но МОЖЕТ быть любым. Клиенты НЕ ДОЛЖНЫ пытаться проверять возвращённый Content-Type. «Тупые» серверы НЕ ДОЛЖНЫ возвращать тип, начинающийся с application/x-git-.

Для отключения кэширования возвращаемой сущности МОГУТ быть возвращены заголовки Cache-Control.

При анализе ответа клиентам РЕКОМЕНДУЕТСЯ проверять только код состояния HTTP. Допустимы ответы 200 OK или 304 Not Modified.

Возвращаемое содержимое представляет собой текстовый файл в формате UNIX, описывающий каждую ссылку и её известное значение. ФАЙЛ РЕКОМЕНДУЕТСЯ сортировать по имени согласно порядку сортировки локали C. В файл НЕ РЕКОМЕНДУЕТСЯ включать ссылку по умолчанию с именем HEAD.

info_refs   =  *( ref_record )
ref_record  =  any_ref / peeled_ref
any_ref     =  obj-id HTAB refname LF
peeled_ref  =  obj-id HTAB refname LF
 obj-id HTAB refname "^{}" LF

«Умные» клиенты

HTTP-клиенты, поддерживающие «умный» протокол (или оба протокола — «умный» и «тупой»), ДОЛЖНЫ обнаруживать ссылки, отправляя параметризованный запрос к файлу info/refs репозитория.

Запрос ДОЛЖЕН содержать ровно один параметр запроса — service=$servicename, где $servicename ДОЛЖНО быть именем службы, к которой клиент хочет обратиться для выполнения операции. Запрос НЕ ДОЛЖЕН содержать дополнительные параметры запроса.

C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0

Ответ «тупого» сервера:

S: 200 OK
S:
S: 95dcfa3633004da0049d3d0fa03f80589cbcaf31        refs/heads/maint
S: d049f6c27a2244e12041955e262a404c7faba355        refs/heads/master
S: 2cb58b79488a98d2721cea644875a8dd0026b115        refs/tags/v1.0
S: a3c2e2402b99163d1d59756e5f207ae21cccba4c        refs/tags/v1.0^{}

Ответ «умного» сервера:

S: 200 OK
S: Content-Type: application/x-git-upload-pack-advertisement
S: Cache-Control: no-cache
S:
S: 001e# service=git-upload-pack\n
S: 0000
S: 004895dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\0multi_ack\n
S: 003fd049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n
S: 003c2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n
S: 003fa3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n
S: 0000

Клиент может отправлять дополнительные параметры (см. gitprotocol-pack[5]) в виде строки, разделённой двоеточиями, в HTTP-заголовке Git-Protocol.

Использует параметр --http-backend-info-refs команды git-upload-pack[1].

Ответ «тупого» сервера

«Тупые» серверы ДОЛЖНЫ отвечать в формате ответа «тупого» сервера.

Более подробное описание ответа «тупого» сервера см. в предыдущем разделе о «тупых» клиентах.

Ответ «умного» сервера

Если сервер не распознаёт запрошенное имя службы или администратор сервера отключил запрошенную службу, сервер ДОЛЖЕН вернуть код состояния HTTP 403 Forbidden.

В противном случае «умные» серверы ДОЛЖНЫ отвечать в формате ответа «умного» сервера для запрошенной службы.

Для отключения кэширования возвращаемой сущности РЕКОМЕНДУЕТСЯ использовать заголовки Cache-Control.

Значение Content-Type ДОЛЖНО быть application/x-$servicename-advertisement. Если возвращён другой тип содержимого, клиентам РЕКОМЕНДУЕТСЯ перейти на «тупой» протокол. При переходе на «тупой» протокол клиентам НЕ РЕКОМЕНДУЕТСЯ отправлять дополнительный запрос к $GIT_URL/info/refs; вместо этого РЕКОМЕНДУЕТСЯ использовать уже полученный ответ. Клиенты НЕ ДОЛЖНЫ продолжать работу, если они не поддерживают «тупой» протокол.

Клиенты ДОЛЖНЫ проверить, что код состояния равен либо 200 OK, либо 304 Not Modified.

Клиенты ДОЛЖНЫ проверить, что первые пять байт сущности ответа соответствуют регулярному выражению ^[0-9a-f]{4}#. Если проверка не пройдена, клиенты НЕ ДОЛЖНЫ продолжать работу.

Клиенты ДОЛЖНЫ разобрать весь ответ как последовательность записей pkt-line.

Клиенты ДОЛЖНЫ проверить, что первая запись pkt-line — это # service=$servicename. Серверы ДОЛЖНЫ устанавливать $servicename равным значению параметра запроса. В конце этой строки РЕКОМЕНДУЕТСЯ добавлять LF. Клиенты ДОЛЖНЫ игнорировать LF в конце строки.

Серверы ДОЛЖНЫ завершать ответ специальным маркером конца записи pkt-line 0000.

Возвращаемый ответ представляет собой поток pkt-line с описанием каждой ссылки и её известного значения. Поток РЕКОМЕНДУЕТСЯ сортировать по имени согласно порядку сортировки локали C. В поток РЕКОМЕНДУЕТСЯ включать ссылку по умолчанию с именем HEAD в качестве первой ссылки. Поток ДОЛЖЕН содержать объявления возможностей после NUL в первой ссылке.

Возвращаемый ответ содержит «version 1», если в качестве дополнительного параметра было передано «version=1».

smart_reply     =  PKT-LINE("# service=$servicename" LF)
     "0000"
     *1("version 1")
     ref_list
     "0000"
ref_list        =  empty_list / non_empty_list
empty_list      =  PKT-LINE(zero-id SP "capabilities^{}" NUL cap-list LF)
non_empty_list  =  PKT-LINE(obj-id SP name NUL cap_list LF)
     *ref_record
cap-list        =  capability *(SP capability)
capability      =  1*(LC_ALPHA / DIGIT / "-" / "_")
LC_ALPHA        =  %x61-7A
ref_record      =  any_ref / peeled_ref
any_ref         =  PKT-LINE(obj-id SP name LF)
peeled_ref      =  PKT-LINE(obj-id SP name LF)
     PKT-LINE(obj-id SP name "^{}" LF

Умная служба git-upload-pack

Эта служба читает данные из репозитория, на который указывает $GIT_URL.

Клиенты ДОЛЖНЫ сначала выполнить обнаружение ссылок с помощью $GIT_URL/info/refs?service=git-upload-pack.

C: POST $GIT_URL/git-upload-pack HTTP/1.0
C: Content-Type: application/x-git-upload-pack-request
C:
C: 0032want 0a53e9ddeaddad63ad106860237bbf53411d11a7\n
C: 0032have 441b40d833fdfa93eb2908e52742248faf0ee993\n
C: 0000
S: 200 OK
S: Content-Type: application/x-git-upload-pack-result
S: Cache-Control: no-cache
S:
S: ....ACK %s, continue
S: ....NAK

Клиенты НЕ ДОЛЖНЫ повторно использовать кэшированный ответ или проверять его актуальность. Серверы ДОЛЖНЫ включать достаточное количество заголовков Cache-Control, чтобы предотвратить кэширование ответа.

Серверам РЕКОМЕНДУЕТСЯ поддерживать все описанные здесь возможности.

Клиенты ДОЛЖНЫ отправлять в теле запроса как минимум одну команду «want». Клиенты НЕ ДОЛЖНЫ указывать в команде «want» идентификатор, отсутствовавший в ответе, полученном при обнаружении ссылок, если только сервер не объявляет возможность allow-tip-sha1-in-want или allow-reachable-sha1-in-want.

compute_request   =  want_list
       have_list
       request_end
request_end       =  "0000" / "done"
want_list         =  PKT-LINE(want SP cap_list LF)
       *(want_pkt)
want_pkt          =  PKT-LINE(want LF)
want              =  "want" SP id
cap_list          =  capability *(SP capability)
have_list         =  *PKT-LINE("have" SP id LF)

TODO: Описать подробнее.

Алгоритм согласования

Вычисление минимального пакета выполняется следующим образом (C = клиент, S = сервер):

init step:

C: С помощью обнаружения ссылок получить объявленные ссылки.

C: Поместить все найденные объекты в набор advertised.

C: Создать пустой набор common для хранения объектов, которые впоследствии будут признаны имеющимися на обоих концах.

C: Создать набор want из объектов набора advertised, которые клиент хочет получить, исходя из результатов обнаружения ссылок.

C: Создать очередь c_pending, упорядоченную по времени фиксации (сначала извлекаются самые новые). Добавить все ссылки клиента. При извлечении фиксации из очереди её родительские фиксации РЕКОМЕНДУЕТСЯ автоматически добавлять обратно в очередь. Фиксации МОГУТ попадать в очередь только один раз.

one compute step:

C: Отправить один запрос $GIT_URL/git-upload-pack:

C: 0032want <want-#1>...............................
C: 0032want <want-#2>...............................
....
C: 0032have <common-#1>.............................
C: 0032have <common-#2>.............................
....
C: 0032have <have-#1>...............................
C: 0032have <have-#2>...............................
....
C: 0000

Поток организован в «команды», каждая из которых помещается в отдельную запись pkt-line. В строке команды текст до первого пробела является именем команды, а оставшаяся часть строки до первого LF — её значением. Строки команд завершаются символом LF в качестве последнего байта значения pkt-line.

Если команды присутствуют в потоке запроса, они ДОЛЖНЫ следовать в указанном порядке:

  • «want»

  • «have»

Поток завершается маркером сброса pkt-line (0000).

Значением одной команды «want» или «have» ДОЛЖНО быть одно имя объекта в шестнадцатеричном формате. Несколько имён объектов ДОЛЖНЫ передаваться с помощью нескольких команд. Имена объектов ДОЛЖНЫ указываться в формате объектов, согласованном с помощью возможности object-format (по умолчанию SHA-1).

Список have создаётся путём извлечения первых 32 фиксаций из c_pending. Можно передать меньше, если набор c_pending опустеет.

Если клиент отправил 256 фиксаций «have» и ещё не получил ни одну из них обратно от s_common либо если набор c_pending опустел, ему РЕКОМЕНДУЕТСЯ включить команду «done», чтобы сообщить серверу, что он не будет продолжать:

C: 0009done

S: Разобрать запрос git-upload-pack:

Убедиться, что все объекты из want напрямую достижимы из ссылок.

Сервер МОЖЕТ пройти назад по истории или reflog, чтобы разрешить слегка устаревшие запросы.

Если не получено ни одного объекта «want», отправить ошибку: TODO: Определить ошибку для случая, когда не запрошено ни одной строки «want».

Если какой-либо объект «want» недостижим, отправить ошибку: Получив недопустимую или некорректную строку want, Git-сервер отвечает сообщением об ошибке, содержащим имя соответствующего объекта.

Создать пустой список s_common.

Если была отправлена команда «have»:

Перебрать объекты в порядке, указанном клиентом.

Для каждого объекта, если он есть на сервере и достижим из ссылки, добавить его в s_common. Если фиксация добавлена в s_common, не добавлять её предков, даже если они также присутствуют в have.

S: Отправить ответ git-upload-pack:

Если сервер нашёл замкнутый набор объектов для упаковки или запрос завершается командой «done», он отвечает пакетом. TODO: Описать ответ с пакетом.

S: PACK...

Возвращаемый поток использует протокол side-band-64k, поддерживаемый службой git-upload-pack, а пакет передаётся в потоке 1. В потоке 2 МОГУТ появляться сообщения о ходе выполнения со стороны сервера.

Здесь «замкнутый набор объектов» определяется как набор, в котором от каждой «want» существует хотя бы один путь к объекту «common».

Если серверу требуется дополнительная информация, он отвечает статусом продолжения: TODO: Описать ответ без пакета.

C: Разобрать ответ upload-pack: TODO: Описать разбор ответа.

Do another compute step.

Умная служба git-receive-pack

Эта служба читает данные из репозитория, на который указывает $GIT_URL.

Клиенты ДОЛЖНЫ сначала выполнить обнаружение ссылок с помощью $GIT_URL/info/refs?service=git-receive-pack.

C: POST $GIT_URL/git-receive-pack HTTP/1.0
C: Content-Type: application/x-git-receive-pack-request
C:
C: ....0a53e9ddeaddad63ad106860237bbf53411d11a7 441b40d833fdfa93eb2908e52742248faf0ee993 refs/heads/maint\0 report-status
C: 0000
C: PACK....
S: 200 OK
S: Content-Type: application/x-git-receive-pack-result
S: Cache-Control: no-cache
S:
S: ....

Клиенты НЕ ДОЛЖНЫ повторно использовать кэшированный ответ или проверять его актуальность. Серверы ДОЛЖНЫ включать достаточное количество заголовков Cache-Control, чтобы предотвратить кэширование ответа.

Серверам РЕКОМЕНДУЕТСЯ поддерживать все описанные здесь возможности.

Клиенты ДОЛЖНЫ отправлять в теле запроса как минимум одну команду. В части тела запроса, содержащей команды, клиентам РЕКОМЕНДУЕТСЯ передавать в качестве old_id идентификатор, полученный при обнаружении ссылок.

update_request  =  command_list
     "PACK" <binary-data>
command_list    =  PKT-LINE(command NUL cap_list LF)
     *(command_pkt)
command_pkt     =  PKT-LINE(command LF)
cap_list        =  *(SP capability) SP
command         =  create / delete / update
create          =  zero-id SP new_id SP name
delete          =  old_id SP zero-id SP name
update          =  old_id SP new_id SP name

TODO: Описать подробнее.

Ссылки

RFC 1738: Унифицированные указатели ресурсов (URL) RFC 2616: Протокол передачи гипертекста — HTTP/1.1

См. также

gitprotocol-pack[5] gitprotocol-capabilities[5]

gitprotocol-http

© 2005–2026 Linus Torvalds and others
Licensed under the GNU General Public License version 2.
https://git-scm.com/docs/gitprotocol-http

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API