-
1. Primeiros Passos
- 1.1 Sobre Controle de Versão
- 1.2 Uma Breve História do Git
- 1.3 O que é Git?
- 1.4 A Linha de Comando
- 1.5 Instalando o Git
- 1.6 Configuração inicial do Git
- 1.7 Obtendo Ajuda
- 1.8 Resumo
-
2. Fundamentos do Git
-
3. Ramificação (Branching) no Git
-
4. Git no Servidor
- 4.1 Os Protocolos
- 4.2 Colocando o Git em um Servidor
- 4.3 Gerando a sua Chave Pública SSH
- 4.4 Configurando o Servidor
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Opções de Hospedagem de Terceiros
- 4.10 Resumo
-
5. Git Distribuído
-
6. GitHub
-
7. Ferramentas do Git
- 7.1 Seleção de Revisão
- 7.2 Área de Stage Interativa
- 7.3 Fazendo Stash e Limpando
- 7.4 Assinando Seu Trabalho
- 7.5 Pesquisando (Searching)
- 7.6 Reescrevendo o Histórico
- 7.7 Reset Desmistificado
- 7.8 Merging Avançado
- 7.9 Rerere
- 7.10 Depurando com Git
- 7.11 Submódulos
- 7.12 Empacotando (Bundling)
- 7.13 Substituir (Replace)
- 7.14 Armazenamento de Credenciais
- 7.15 Resumo
-
8. Customizando o Git
- 8.1 Configuração do Git
- 8.2 Atributos do Git
- 8.3 Hooks do Git
- 8.4 Uma Política de Exemplo Imposta pelo Git
- 8.5 Resumo
-
9. Git e Outros Sistemas
- 9.1 Git como Cliente
- 9.2 Migrando para o Git
- 9.3 Resumo
-
10. Git Internals (Por Dentro do Git)
- 10.1 Encanamento e Porcelana (Plumbing and Porcelain)
- 10.2 Objetos do Git
- 10.3 Referências do Git
- 10.4 Arquivos de pacote (Packfiles)
- 10.5 Refspec
- 10.6 Protocolos de Transferência
- 10.7 Manutenção e Recuperação de Dados
- 10.8 Variáveis de Ambiente
- 10.9 Resumo
-
A1. Appendix A: O Git em Outros Ambientes
- A1.1 Interfaces Gráficas
- A1.2 Git no Visual Studio
- A1.3 Git no Visual Studio Code
- A1.4 Git no IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git no Sublime Text
- A1.6 Git no Bash
- A1.7 Git no Zsh
- A1.8 Git no PowerShell
- A1.9 Resumo
-
A2. Appendix B: Incorporando o Git nos seus Aplicativos
- A2.1 Linha de Comando do Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Appendix C: Comandos do Git
- A3.1 Configuração e Ajustes
- A3.2 Obtendo e Criando Projetos
- A3.3 Snapshots Básicos
- A3.4 Branches e Merges
- A3.5 Compartilhando e Atualizando Projetos
- A3.6 Inspeção e Comparação
- A3.7 Depuração
- A3.8 Patches
- A3.9 E-mail
- A3.10 Sistemas Externos
- A3.11 Administração
- A3.12 Comandos de Encanamento
4.1 Git no Servidor - Os Protocolos
Neste ponto, você deve ser capaz de realizar a maioria das tarefas do dia a dia para as quais usará o Git. No entanto, para fazer qualquer colaboração no Git, você precisará ter um repositório Git remoto. Embora você possa tecnicamente fazer push de alterações e pull de alterações dos repositórios de indivíduos, fazer isso é desencorajado porque você pode facilmente confundir no que eles estão trabalhando se não for cuidadoso. Além disso, você quer que seus colaboradores possam acessar o repositório mesmo se o seu computador estiver offline — ter um repositório comum mais confiável costuma ser útil. Portanto, o método preferido para colaborar com alguém é configurar um repositório intermediário ao qual ambos tenham acesso e fazer push e pull dele.
Executar um servidor Git é bastante simples. Primeiro, você escolhe quais protocolos deseja que o seu servidor suporte. A primeira seção deste capítulo abordará os protocolos disponíveis e os prós e contras de cada um. As próximas seções explicarão algumas configurações típicas usando esses protocolos e como colocar o seu servidor para rodar com eles. Por último, abordaremos algumas opções hospedadas (hosted), se você não se importa em hospedar o seu código no servidor de outra pessoa e não quer passar pelo aborrecimento de configurar e manter o seu próprio servidor.
Se você não tem interesse em executar o seu próprio servidor, pode pular para a última seção do capítulo para ver algumas opções para configurar uma conta hospedada (hosted account) e depois passar para o próximo capítulo, onde discutimos os vários detalhes do trabalho em um ambiente de controle de fonte distribuído.
Um repositório remoto geralmente é um bare repository (repositório nu) — um repositório Git que não tem diretório de trabalho.
Como o repositório é usado apenas como um ponto de colaboração, não há motivo para ter um snapshot com checkout no disco; são apenas os dados do Git.
Nos termos mais simples, um repositório nu é o conteúdo do diretório .git do seu projeto e nada mais.
Os Protocolos
O Git pode usar quatro protocolos distintos para transferir dados: Local, HTTP, Secure Shell (SSH) e Git. Aqui, discutiremos o que eles são e em quais circunstâncias básicas você gostaria (ou não gostaria) de usá-los.
Protocolo Local
O mais básico é o protocolo Local, no qual o repositório remoto está em outro diretório no mesmo host. Isso é frequentemente usado se todos na sua equipe tiverem acesso a um sistema de arquivos compartilhado, como uma montagem NFS, ou no caso menos provável de que todos façam login no mesmo computador. Este último não seria o ideal, pois todas as suas instâncias de repositório de código residiriam no mesmo computador, tornando uma perda catastrófica muito mais provável.
Se você tiver um sistema de arquivos compartilhado montado, poderá clonar, fazer o push e o pull de um repositório local baseado em arquivo. Para clonar um repositório como esse ou para adicioná-lo como remoto a um projeto existente, use o caminho para o repositório como a URL. Por exemplo, para clonar um repositório local, você pode executar algo assim:
$ git clone /srv/git/project.git
Ou você pode fazer isso:
$ git clone file:///srv/git/project.git
O Git opera de forma ligeiramente diferente se você especificar explicitamente file:// no início da URL.
Se você apenas especificar o caminho, o Git tentará usar hardlinks (links físicos) ou copiar diretamente os arquivos de que precisa.
Se você especificar file://, o Git aciona os processos que ele normalmente usa para transferir dados por uma rede, o que geralmente é muito menos eficiente.
O principal motivo para especificar o prefixo file:// é se você quiser uma cópia limpa do repositório, sem as referências estranhas (extraneous) ou os objetos deixados de fora — geralmente após uma importação de outro VCS ou algo semelhante (consulte Git Internals (Por Dentro do Git) para tarefas de manutenção).
Usaremos o caminho normal aqui porque fazer isso é quase sempre mais rápido.
Para adicionar um repositório local a um projeto Git existente, você pode executar algo assim:
$ git remote add local_proj /srv/git/project.git
Então, você pode fazer o push e o pull desse remoto através do seu novo nome de remoto local_proj como se estivesse fazendo isso por uma rede.
Os Prós
Os prós dos repositórios baseados em arquivos são que eles são simples e usam as permissões de arquivos e o acesso à rede existentes. Se você já tem um sistema de arquivos compartilhado ao qual toda a sua equipe tem acesso, configurar um repositório é muito fácil. Você coloca a cópia do repositório nu em algum lugar ao qual todos tenham acesso compartilhado e define as permissões de leitura/gravação como faria para qualquer outro diretório compartilhado. Discutiremos como exportar uma cópia do repositório nu para este propósito em Colocando o Git em um Servidor.
Essa também é uma ótima opção para obter rapidamente o trabalho do repositório de trabalho de outra pessoa.
Se você e um colega de trabalho estiverem trabalhando no mesmo projeto e eles quiserem que você verifique algo, executar um comando como git pull /home/john/project costuma ser mais fácil do que eles fazerem o push para um servidor remoto e você, em seguida, fazer o fetch a partir dele.
Os Contras
Os contras deste método são que o acesso compartilhado geralmente é mais difícil de configurar e alcançar de vários locais do que o acesso básico à rede. Se você deseja fazer o push do seu laptop quando está em casa, precisa montar o disco remoto, o que pode ser difícil e lento em comparação com o acesso baseado em rede.
É importante mencionar que esta não é necessariamente a opção mais rápida se você estiver usando um tipo de montagem compartilhada. Um repositório local só é rápido se você tiver acesso rápido aos dados. Um repositório em NFS geralmente é mais lento do que o repositório via SSH no mesmo servidor, permitindo que o Git seja executado nos discos locais de cada sistema.
Finalmente, esse protocolo não protege o repositório contra danos acidentais. Cada usuário tem acesso shell total ao diretório “remoto”, e não há nada que o impeça de alterar ou remover arquivos internos do Git e corromper o repositório.
Os Protocolos HTTP
O Git pode se comunicar via HTTP usando dois modos diferentes. Antes do Git 1.6.6, havia apenas uma maneira de fazer isso, que era muito simples e geralmente apenas para leitura (read-only). Na versão 1.6.6, um protocolo novo e mais inteligente foi introduzido, que envolvia o Git sendo capaz de negociar inteligentemente a transferência de dados de uma maneira semelhante a como ele faz via SSH. Nos últimos anos, esse novo protocolo HTTP se tornou muito popular, pois é mais simples para o usuário e mais inteligente sobre como se comunica. A versão mais recente costuma ser chamada de protocolo HTTP Inteligente (Smart HTTP) e a maneira mais antiga como HTTP Burro (Dumb HTTP). Abordaremos primeiro o novo protocolo Smart HTTP.
Smart HTTP
O Smart HTTP opera de forma muito semelhante aos protocolos SSH ou Git, mas roda sobre portas HTTPS padrão e pode usar vários mecanismos de autenticação HTTP, o que significa que geralmente é mais fácil para o usuário do que algo como o SSH, já que você pode usar coisas como autenticação de nome de usuário/senha em vez de ter que configurar chaves SSH.
Provavelmente se tornou a maneira mais popular de usar o Git agora, já que ele pode ser configurado tanto para servir anonimamente como o protocolo git://, quanto para fazer push com autenticação e criptografia como o protocolo SSH.
Em vez de ter que configurar URLs diferentes para essas coisas, agora você pode usar uma única URL para ambas.
Se você tentar fazer o push e o repositório exigir autenticação (o que normalmente deveria), o servidor pode solicitar um nome de usuário e uma senha.
O mesmo vale para o acesso de leitura.
Na verdade, para serviços como o GitHub, a URL que você usa para visualizar o repositório online (por exemplo, https://github.com/schacon/simplegit) é a mesma URL que você pode usar para clonar e, se tiver acesso, para fazer push.
Dumb HTTP
Se o servidor não responder com um serviço inteligente (smart service) HTTP do Git, o cliente Git tentará recorrer (fall back) ao protocolo Dumb HTTP, mais simples.
O protocolo Dumb espera que o repositório Git nu (bare) seja servido como arquivos normais do servidor da web.
A beleza do Dumb HTTP é a simplicidade de configurá-lo.
Basicamente, tudo o que você precisa fazer é colocar um repositório Git nu (bare) sob a raiz do documento HTTP e configurar um gancho (hook) específico de post-update, e pronto (consulte Hooks do Git).
A partir desse ponto, qualquer um que possa acessar o servidor da web no qual você colocou o repositório também poderá cloná-lo.
Para permitir acesso de leitura ao seu repositório via HTTP, faça algo assim:
$ cd /var/www/htdocs/
$ git clone --bare /path/to/git_project gitproject.git
$ cd gitproject.git
$ mv hooks/post-update.sample hooks/post-update
$ chmod a+x hooks/post-update
Isso é tudo.
O hook post-update que vem com o Git por padrão executa o comando apropriado (git update-server-info) para fazer com que a busca (fetching) e a clonagem HTTP funcionem corretamente.
Este comando é executado quando você faz o push para este repositório (via SSH, talvez); então, outras pessoas podem clonar via algo como:
$ git clone https://example.com/gitproject.git
Neste caso particular, estamos usando o caminho /var/www/htdocs, que é comum para configurações do Apache, mas você pode usar qualquer servidor da web estático — basta colocar o repositório nu no seu caminho.
Os dados do Git são servidos como arquivos estáticos básicos (consulte o capítulo Git Internals (Por Dentro do Git) para obter detalhes sobre como exatamente ele é servido).
Geralmente, você optaria por executar um servidor Smart HTTP de leitura/gravação ou simplesmente ter os arquivos acessíveis como leitura (read-only) da maneira Dumb. É raro executar uma mistura dos dois serviços.
Os Prós
Nós nos concentraremos nos prós da versão Smart do protocolo HTTP.
A simplicidade de ter uma única URL para todos os tipos de acesso e ter o servidor solicitando autenticação apenas quando ela é necessária torna as coisas muito fáceis para o usuário final. Ser capaz de se autenticar com um nome de usuário e uma senha também é uma grande vantagem sobre o SSH, já que os usuários não precisam gerar chaves SSH localmente e fazer o upload da chave pública deles para o servidor antes de poder interagir com ele. Para usuários menos sofisticados, ou usuários em sistemas em que o SSH é menos comum, essa é uma grande vantagem na usabilidade. Também é um protocolo muito rápido e eficiente, semelhante ao SSH.
Você também pode servir os seus repositórios no modo de leitura (read-only) via HTTPS, o que significa que você pode criptografar a transferência de conteúdo; ou você pode ir tão longe a ponto de fazer os clientes usarem certificados SSL assinados específicos.
Outra coisa boa é que HTTP e HTTPS são protocolos tão comumente usados que os firewalls corporativos costumam ser configurados para permitir o tráfego em suas portas.
Os Contras
O Git via HTTPS pode ser um pouco mais complicado de configurar em comparação com o SSH em alguns servidores. Fora isso, há muito pouca vantagem que outros protocolos tenham sobre o Smart HTTP para servir conteúdo Git.
Se você estiver usando HTTP para fazer o push autenticado, fornecer as suas credenciais às vezes é mais complicado do que usar chaves via SSH. Há, no entanto, várias ferramentas de armazenamento em cache (caching tools) de credenciais que você pode usar, incluindo o acesso ao Keychain no macOS e o Gerenciador de Credenciais (Credential Manager) no Windows, para tornar isso bem indolor. Leia Armazenamento de Credenciais para ver como configurar o cache de senha HTTP seguro no seu sistema.
O Protocolo SSH
Um protocolo de transporte comum para o Git ao fazer a auto-hospedagem (self-hosting) é sobre SSH. Isso ocorre porque o acesso SSH a servidores já está configurado na maioria dos lugares — e se não estiver, é fácil de fazer. O SSH também é um protocolo de rede autenticado e, por ser onipresente, geralmente é fácil de configurar e usar.
Para clonar um repositório Git via SSH, você pode especificar uma URL ssh:// como esta:
$ git clone ssh://[user@]server/project.git
Ou você pode usar a sintaxe mais curta, semelhante a scp, para o protocolo SSH:
$ git clone [user@]server:project.git
Em ambos os casos acima, se você não especificar o nome de usuário opcional, o Git assume o usuário com o qual você está logado no momento.
Os Prós
Os prós do uso de SSH são muitos. Primeiro, o SSH é relativamente fácil de configurar — os daemons SSH são comuns, muitos administradores de rede têm experiência com eles e muitas distribuições de sistema operacional são configuradas com eles ou têm ferramentas para gerenciá-los. Em seguida, o acesso via SSH é seguro — toda a transferência de dados é criptografada e autenticada. Por último, como os protocolos HTTPS, Git e Local, o SSH é eficiente, tornando os dados os mais compactos possíveis antes de transferi-los.
Os Contras
O aspecto negativo do SSH é que ele não suporta acesso anônimo ao seu repositório Git. Se você estiver usando SSH, as pessoas devem ter acesso SSH à sua máquina, mesmo em uma capacidade somente leitura (read-only), o que não torna o SSH propício para projetos de código aberto (open source) nos quais as pessoas podem simplesmente querer clonar o seu repositório para examiná-lo. Se você estiver usando-o apenas na sua rede corporativa, o SSH pode ser o único protocolo com o qual você precise lidar. Se você quiser permitir acesso anônimo somente leitura (read-only) aos seus projetos e também quiser usar SSH, terá que configurar o SSH para você fazer push, mas usar outra coisa para que os outros façam fetch.
O Protocolo Git
Por fim, temos o protocolo Git.
Trata-se de um daemon especial que vem empacotado com o Git; ele escuta em uma porta dedicada (9418) que fornece um serviço semelhante ao protocolo SSH, mas sem nenhuma autenticação ou criptografia.
Para que um repositório seja servido por meio do protocolo Git, você deve criar um arquivo git-daemon-export-ok — o daemon não servirá um repositório sem que esse arquivo esteja lá — mas, além disso, não há segurança.
O repositório Git está disponível para qualquer pessoa clonar ou não está.
Isso significa que geralmente não há push por meio deste protocolo.
Você pode habilitar o acesso de push, mas, dada a falta de autenticação, qualquer pessoa na internet que encontre a URL do seu projeto pode fazer push para esse projeto.
Basta dizer que isso é raro.
Os Prós
O protocolo Git geralmente é o protocolo de transferência de rede mais rápido disponível. Se você estiver servindo muito tráfego para um projeto público ou servindo um projeto muito grande que não requer autenticação de usuário para acesso de leitura (read access), é provável que você queira configurar um daemon do Git para servir o seu projeto. Ele usa o mesmo mecanismo de transferência de dados que o protocolo SSH, mas sem a sobrecarga (overhead) de criptografia e autenticação.
Os Contras
Devido à falta de TLS ou outra criptografia, a clonagem por meio de git:// pode levar a uma vulnerabilidade de execução arbitrária de código e, portanto, deve ser evitada, a menos que você saiba o que está fazendo.
-
Se você executar
git clone git://example.com/project.git, um invasor que controle, por exemplo, o seu roteador, poderá modificar o repositório que você acabou de clonar, inserindo código malicioso nele. Se você então compilar/executar o código que acabou de clonar, você executará o código malicioso. Executargit clone http://example.com/project.gitdeve ser evitado pelo mesmo motivo. -
Executar
git clone https://example.com/project.gitnão sofre do mesmo problema (a menos que o invasor consiga fornecer um certificado TLS para example.com). Executargit clone git@example.com:project.gitsó sofre deste problema se você aceitar uma impressão digital (fingerprint) de chave SSH errada.
Também não possui autenticação, ou seja, qualquer pessoa pode clonar o repositório (embora isso seja frequentemente exatamente o que você deseja).
Também é, provavelmente, o protocolo mais difícil de configurar.
Ele deve executar o seu próprio daemon, o que requer configuração do xinetd ou systemd ou algo semelhante, o que nem sempre é um passeio no parque (walk in the park).
Também requer acesso de firewall à porta 9418, que não é uma porta padrão que os firewalls corporativos sempre permitem.
Atrás de grandes firewalls corporativos, essa porta obscura geralmente é bloqueada.