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
- Documentação oficial do Git - Protocolos de transferência — Guia completo sobre os quatro protocolos suportados pelo Git, com exemplos de configuração de servidor.
- Git Smart HTTP - Documentação do Git — Documentação técnica do backend HTTP inteligente do Git, incluindo variáveis de ambiente e exemplos de configuração Apache.
- Git daemon - Documentação oficial — Referência completa do daemon Git para o protocolo git://, com opções de linha de comando e configuração de exportação.
- Configurando servidor Git com SSH - Atlassian — Tutorial prático sobre como configurar um servidor Git via SSH, incluindo chaves e restrições de segurança.
- Git Internals - Transfer Protocols (Git Book) — Explicação detalhada dos mecanismos internos de transferência, incluindo pkt-line e negociação de pacotes.
- Otimizando transferências Git - GitHub Docs — Guia de boas práticas para otimizar clones e pushes, com configurações de buffer e shallow clones.
- Protocolo Git vs HTTP vs SSH - Stack Overflow — Discussão técnica comparando os protocolos, com análise de desempenho e segurança.