Protocolos de transferência do Git

1. Visão geral dos protocolos de transferência

Os protocolos de transferência são a espinha dorsal da comunicação entre repositórios Git. Eles definem como os dados são empacotados, autenticados e transmitidos pela rede ou pelo sistema de arquivos. O Git implementa dois grandes grupos de protocolos: os inteligentes (smart) e os burros (dumb).

  • Protocolos inteligentes: negociam capabilities, enviam apenas objetos necessários e usam compressão delta. São a escolha moderna e eficiente.
  • Protocolos burros: transferem objetos brutos sem negociação prévia. Funcionam, mas são extremamente ineficientes para repositórios grandes.

Quando você executa git fetch, git push ou git clone, o Git automaticamente negocia o melhor protocolo disponível com base na URL fornecida. Essa negociação ocorre no handshake inicial, onde o cliente e o servidor trocam informações sobre suas capacidades.

2. Protocolo local (file://)

O protocolo local utiliza o sistema de arquivos diretamente. A URL segue o formato file:///caminho/para/repositorio ou simplesmente o caminho absoluto.

git clone /home/user/projeto.git
git clone file:///home/user/projeto.git

Vantagens:
- Extremamente rápido (sem overhead de rede)
- Simples de configurar (apenas permissões de arquivo)
- Ideal para backups locais e compartilhamento em sistemas de arquivos montados (NFS, SMB)

Limitações:
- Não funciona para repositórios remotos em outra máquina sem compartilhamento de arquivos
- Não oferece autenticação granular (apenas permissões do sistema operacional)
- Pode sofrer com concorrência se múltiplos usuários escreverem simultaneamente

Casos de uso típicos:
- Repositórios espelho locais
- Ambientes de desenvolvimento com acesso ao mesmo sistema de arquivos
- Migrações e backups

3. Protocolo HTTP/HTTPS (modos dumb e smart)

Modo Dumb HTTP

No modo burro, o Git serve objetos como arquivos estáticos via servidor web comum (Apache, Nginx). Cada objeto é baixado individualmente com requisições GET.

# Configuração mínima (dumb) no servidor
# Apenas expor o diretório .git como estático
git update-server-info

Problemas: Sem negociação, cada fetch baixa todos os objetos novamente. Extremamente ineficiente.

Modo Smart HTTP

O modo inteligente usa CGI para executar comandos Git no servidor. O cliente negocia com git-upload-pack (para fetch) e git-receive-pack (para push).

# Exemplo de configuração no servidor Apache
SetEnv GIT_PROJECT_ROOT /var/www/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/lib/git-core/git-http-backend/

Vantagens do Smart HTTP:
- Autenticação via HTTP Basic ou SSL/TLS
- Suporte a push e pull com negociação inteligente
- Funciona em qualquer infraestrutura web
- Ideal para repositórios públicos (GitHub, GitLab usam este protocolo)

Configuração de cliente para HTTPS:

# Aumentar buffer para pushes grandes
git config http.postBuffer 524288000

# Limitar velocidade mínima (evita timeouts)
git config http.lowSpeedLimit 1000
git config http.lowSpeedTime 300

4. Protocolo SSH

O SSH é o protocolo mais seguro e flexível para repositórios Git. Ele autentica via chaves públicas/privadas e executa comandos Git remotamente.

# Clonar via SSH
git clone git@servidor:/caminho/repositorio.git

# Ou usando porta customizada
git clone ssh://git@servidor:2222/caminho/repositorio.git

Como funciona: O SSH executa git-upload-pack ou git-receive-pack no servidor remoto, transmitindo os dados pelo canal criptografado.

Configuração do servidor SSH:

# No arquivo ~/.ssh/authorized_keys do usuário git
# Restringir comandos para apenas Git
command="/usr/bin/git-shell -c \"$SSH_ORIGINAL_COMMAND\"",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3...

Segurança:
- Use chaves SSH com senha (passphrase)
- Configure git-shell para limitar comandos permitidos
- Restrinja acesso por IP no firewall (porta 22 ou customizada)

5. Protocolo Git (git://)

O protocolo Git usa uma porta dedicada (9418) e não oferece criptografia. É executado pelo daemon git-daemon.

# Iniciar daemon para servir repositórios
git daemon --base-path=/var/git --export-all

# Clonar via protocolo Git
git clone git://servidor/repositorio.git

Limitações de segurança:
- Sem autenticação (apenas controle por IP)
- Sem criptografia (dados trafegam em texto claro)
- Apenas leitura (não permite push)

Quando utilizar:
- Repositórios públicos de código aberto
- Redes internas confiáveis
- Mirroring de repositórios públicos

6. Mecanismos de negociação e transferência de dados

Handshake inicial

No protocolo smart, o cliente e servidor trocam pacotes iniciais (pkt-line) que anunciam referências (branches, tags) e capabilities (funcionalidades suportadas).

# Exemplo de negociação (simplificado)
Cliente: "want" (lista de commits desejados)
Servidor: "have" (lista de commits que o cliente já possui)
Ambos: negociação de "thin pack" e compressão delta

Transferência de pacotes

O formato pkt-line empacota dados em unidades de até 65520 bytes. Cada pacote tem um cabeçalho de 4 bytes indicando o tamanho.

# Estrutura de um pacote pkt-line
[4 bytes: tamanho em hexa][dados...]
Exemplo: "0010hello\n" (16 bytes no total)

Fetch vs Push

  • Fetch: O servidor envia um thin pack contendo apenas os objetos que faltam ao cliente, com compressão delta baseada nos objetos que o cliente já possui.
  • Push: O cliente envia um full pack com todos os objetos novos, sem assumir nada sobre o servidor.

7. Otimizações e boas práticas nos protocolos

Shallow clones com --depth

Reduz drasticamente o tráfego ao limitar o histórico baixado:

# Clonar apenas os últimos 5 commits
git clone --depth 5 https://github.com/exemplo/repositorio.git

# Fetch incremental com profundidade
git fetch --depth 5 origin main

Configurações HTTP

# Aumentar buffer para pushes grandes (GitHub recomenda 500MB)
git config http.postBuffer 524288000

# Timeout para conexões lentas
git config http.lowSpeedLimit 1000
git config http.lowSpeedTime 300

# Desabilitar verificação SSL (apenas para testes!)
git config http.sslVerify false

Escolha do protocolo ideal

Cenário Protocolo recomendado
Rede local confiável SSH ou local
Repositório público HTTPS ou Git
Autenticação forte SSH
Firewall restrito HTTPS (porta 443)
Apenas leitura público Git (porta 9418)

Dica final: Para ambientes corporativos, prefira SSH pela segurança e HTTPS pela compatibilidade com firewalls. Evite o protocolo Git puro em redes não confiáveis.

Referências