-
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
6.5 GitHub - Criando Scripts para o GitHub
Criando Scripts para o GitHub
Então, agora cobrimos todos os principais recursos e fluxos de trabalho do GitHub, mas qualquer grande grupo ou projeto terá personalizações que podem querer fazer ou serviços externos que podem querer integrar.
Para nossa sorte, o GitHub é realmente bastante hackeável de muitas maneiras. Nesta seção cobriremos como usar o sistema de hooks do GitHub e a sua API para fazer o GitHub funcionar como nós queremos.
Serviços e Hooks
A seção Hooks and Services da administração de repositório do GitHub é a maneira mais fácil de fazer o GitHub interagir com sistemas externos.
Serviços
Primeiro daremos uma olhada em Serviços. Ambas as integrações de Hooks e Serviços podem ser encontradas na seção Settings do seu repositório, onde vimos anteriormente como adicionar Colaboradores e alterar o branch padrão do seu projeto. Na aba “Webhooks and Services” (Webhooks e Serviços), você verá algo parecido com Seção de configuração de Serviços e Hooks.
Existem dezenas de serviços para escolher, a maioria integrações com outros sistemas comerciais e de código aberto. A maioria deles é para serviços de Integração Contínua, rastreadores de bugs e issues, sistemas de sala de bate-papo e sistemas de documentação. Passaremos pela configuração de um bem simples, o hook de E-mail. Se você escolher “email” no menu suspenso “Add Service” (Adicionar Serviço), você obterá uma tela de configuração como Configuração de serviço de e-mail.
Neste caso, se clicarmos no botão “Add service” (Adicionar serviço), o endereço de e-mail que especificamos receberá um e-mail toda vez que alguém fizer um push para o repositório. Os serviços podem escutar muitos tipos diferentes de eventos, mas a maioria apenas escuta eventos de push e, em seguida, faz algo com esses dados.
Se houver um sistema que você esteja usando e que gostaria de integrar com o GitHub, você deve verificar aqui para ver se há uma integração de serviço existente disponível. Por exemplo, se você estiver usando o Jenkins para executar testes em sua base de código, poderá habilitar a integração do serviço embutido do Jenkins para iniciar uma execução de teste toda vez que alguém fizer push no seu repositório.
Hooks
Se você precisar de algo mais específico ou quiser se integrar a um serviço ou site que não está incluído nesta lista, você pode usar o sistema de hooks mais genérico. Os hooks de repositório do GitHub são bem simples. Você especifica uma URL e o GitHub fará o post de um payload HTTP para essa URL em qualquer evento que você desejar.
Geralmente, a maneira como isso funciona é que você pode configurar um pequeno serviço web para escutar um payload do hook do GitHub e então fazer algo com os dados quando eles forem recebidos.
Para ativar um hook, você clica no botão “Add webhook” em Seção de configuração de Serviços e Hooks. Isso o levará a uma página semelhante a Configuração de Web hook.
A configuração para um web hook é bastante simples.
Na maioria dos casos, você simplesmente insere uma URL e uma chave secreta e aperta “Add webhook”.
Existem algumas opções para quais eventos você deseja que o GitHub envie um payload — o padrão é receber um payload apenas para o evento push, quando alguém envia (push) novo código para qualquer branch do seu repositório.
Vejamos um pequeno exemplo de um serviço web que você pode configurar para lidar com um web hook. Nós usaremos o framework web Ruby Sinatra, já que ele é bastante conciso e você deve ser capaz de ver facilmente o que estamos fazendo.
Digamos que queremos receber um e-mail se uma pessoa específica fizer push em um branch específico do nosso projeto, modificando um arquivo específico. Nós poderíamos muito facilmente fazer isso com um código como este:
require 'sinatra'
require 'json'
require 'mail'
post '/payload' do
push = JSON.parse(request.body.read) # parse the JSON
# gather the data we're looking for
pusher = push["pusher"]["name"]
branch = push["ref"]
# get a list of all the files touched
files = push["commits"].map do |commit|
commit['added'] + commit['modified'] + commit['removed']
end
files = files.flatten.uniq
# check for our criteria
if pusher == 'schacon' &&
branch == 'ref/heads/special-branch' &&
files.include?('special-file.txt')
Mail.deliver do
from 'tchacon@example.com'
to 'tchacon@example.com'
subject 'Scott Changed the File'
body "ALARM"
end
end
end
Aqui estamos pegando o payload JSON que o GitHub nos entrega e procurando quem fez o push, em qual branch fizeram o push e quais arquivos foram tocados em todos os commits que sofreram push. Em seguida, verificamos isso contra os nossos critérios e enviamos um e-mail caso corresponda.
Para desenvolver e testar algo assim, você tem um console de desenvolvedor legal na mesma tela onde você configura o hook. Você pode ver as últimas entregas que o GitHub tentou fazer para aquele webhook. Para cada hook, você pode analisar quando ele foi entregue, se foi bem-sucedido e o corpo e os cabeçalhos tanto para a requisição quanto para a resposta. Isso torna incrivelmente fácil testar e depurar seus hooks.
O outro grande recurso disso é que você pode reenviar qualquer um dos payloads para testar o seu serviço facilmente.
Para mais informações sobre como escrever webhooks e todos os diferentes tipos de eventos que você pode escutar, vá para a documentação do GitHub Developer em https://docs.github.com/en/webhooks-and-events/webhooks/about-webhooks.
A API do GitHub
Serviços e hooks oferecem uma forma de receber notificações push sobre eventos que acontecem nos seus repositórios, mas e se você precisar de mais informações sobre esses eventos? E se você precisar automatizar algo como adicionar colaboradores ou rotular issues?
É aqui que a API do GitHub é útil. O GitHub tem muitos endpoints de API para fazer de forma automatizada quase tudo que você pode fazer no site. Nesta seção, aprenderemos como autenticar e se conectar à API, como comentar em uma issue e como alterar o status de um Pull Request através da API.
Uso Básico
A coisa mais básica que você pode fazer é uma simples requisição GET num endpoint que não requer autenticação. Isto pode ser um usuário ou uma informação somente leitura num projeto de código aberto. Por exemplo, se quisermos saber mais sobre um usuário chamado “schacon”, podemos rodar algo como isto:
$ curl https://api.github.com/users/schacon
{
"login": "schacon",
"id": 70,
"avatar_url": "https://avatars.githubusercontent.com/u/70",
# …
"name": "Scott Chacon",
"company": "GitHub",
"following": 19,
"created_at": "2008-01-27T17:19:28Z",
"updated_at": "2014-06-10T02:37:23Z"
}
Há toneladas de endpoints como esse para obter informações sobre organizações, projetos, issues, commits — basicamente qualquer coisa que você possa ver publicamente no GitHub.
Você pode até mesmo usar a API para renderizar Markdown arbitrário ou encontrar um template .gitignore.
$ curl https://api.github.com/gitignore/templates/Java
{
"name": "Java",
"source": "*.class
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.ear
# virtual machine crash logs, see https://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
"
}
Comentando em uma Issue
No entanto, se você quiser fazer uma ação no site como comentar em uma Issue ou Pull Request ou se você quiser visualizar ou interagir com conteúdo privado, você precisará se autenticar.
Existem várias maneiras de se autenticar. Você pode usar autenticação básica com apenas seu nome de usuário e senha, mas geralmente é uma ideia melhor usar um token de acesso pessoal. Você pode gerar isso a partir da aba “Applications” (Aplicações) da sua página de configurações.
Ele perguntará quais escopos você deseja para esse token e uma descrição. Certifique-se de usar uma boa descrição para se sentir confortável ao remover o token quando o seu script ou aplicação não for mais usado.
O GitHub mostrará o token apenas uma vez, então certifique-se de copiá-lo. Você pode agora usar isso para se autenticar no seu script em vez de usar um nome de usuário e senha. Isso é legal porque você pode limitar o escopo do que deseja fazer e o token é revogável.
Isso também tem a vantagem adicional de aumentar o seu limite de requisições (rate limit). Sem autenticação, você será limitado a 60 requisições por hora. Se você se autenticar, pode fazer até 5.000 requisições por hora.
Então, vamos usá-lo para fazer um comentário em uma de nossas issues.
Digamos que queremos deixar um comentário em uma issue específica, a Issue #6.
Para fazer isso, temos que fazer uma requisição HTTP POST para repos/<usuario>/<repo>/issues/<num>/comments com o token que acabamos de gerar como um cabeçalho Authorization.
$ curl -H "Content-Type: application/json" \
-H "Authorization: token TOKEN" \
--data '{"body":"A new comment, :+1:"}' \
https://api.github.com/repos/schacon/blink/issues/6/comments
{
"id": 58322100,
"html_url": "https://github.com/schacon/blink/issues/6#issuecomment-58322100",
...
"user": {
"login": "tonychacon",
"id": 7874698,
"avatar_url": "https://avatars.githubusercontent.com/u/7874698?v=2",
"type": "User",
},
"created_at": "2014-10-08T07:48:19Z",
"updated_at": "2014-10-08T07:48:19Z",
"body": "A new comment, :+1:"
}
Agora, se você for a essa issue, poderá ver o comentário que acabamos de postar com sucesso, como em Um comentário postado da API do GitHub.
Você pode usar a API para fazer basicamente qualquer coisa que você pode fazer no site — criar e configurar marcos (milestones), atribuir pessoas a Issues e Pull Requests, criar e alterar rótulos (labels), acessar dados de commit, criar novos commits e branches, abrir, fechar ou mesclar Pull Requests, criar e editar equipes, comentar em linhas de código em um Pull Request, pesquisar no site e muito mais.
Alterando o Status de um Pull Request
Há um último exemplo que veremos, já que é realmente útil se você estiver trabalhando com Pull Requests. Cada commit pode ter um ou mais status associados a ele e há uma API para adicionar e consultar esse status.
A maioria dos serviços de Integração Contínua e testes faz uso desta API para reagir a pushes, testando o código que sofreu push, e então relatando de volta se aquele commit passou em todos os testes. Você também poderia usar isso para verificar se a mensagem de commit está formatada corretamente, se o remetente seguiu todas as suas diretrizes de contribuição, se o commit foi validamente assinado — qualquer número de coisas.
Digamos que você configure um webhook no seu repositório que atinge um pequeno serviço web que verifica uma string Signed-off-by na mensagem de commit.
require 'httparty'
require 'sinatra'
require 'json'
post '/payload' do
push = JSON.parse(request.body.read) # parse the JSON
repo_name = push['repository']['full_name']
# look through each commit message
push["commits"].each do |commit|
# look for a Signed-off-by string
if /Signed-off-by/.match commit['message']
state = 'success'
description = 'Successfully signed off!'
else
state = 'failure'
description = 'No signoff found.'
end
# post status to GitHub
sha = commit["id"]
status_url = "https://api.github.com/repos/#{repo_name}/statuses/#{sha}"
status = {
"state" => state,
"description" => description,
"target_url" => "http://example.com/how-to-signoff",
"context" => "validate/signoff"
}
HTTParty.post(status_url,
:body => status.to_json,
:headers => {
'Content-Type' => 'application/json',
'User-Agent' => 'tonychacon/signoff',
'Authorization' => "token #{ENV['TOKEN']}" }
)
end
end
Espero que isso seja bastante simples de acompanhar.
Neste manipulador de web hook (handler), olhamos cada commit que acabou de sofrer push, procuramos pela string 'Signed-off-by' na mensagem de commit e finalmente fazemos um POST via HTTP para o endpoint da API /repos/<usuario>/<repo>/statuses/<commit_sha> com o status.
Neste caso, você pode enviar um estado ('success', 'failure', 'error'), uma descrição do que aconteceu, uma URL de destino (target URL) onde o usuário pode ir para obter mais informações e um “context” (contexto) no caso de haver vários status para um único commit. Por exemplo, um serviço de teste pode fornecer um status e um serviço de validação como este também pode fornecer um status — o campo “context” é como eles são diferenciados.
Se alguém abrir um novo Pull Request no GitHub e este hook estiver configurado, você poderá ver algo como Status do commit via API.
Você pode ver agora uma pequena marca de seleção (check mark) verde ao lado do commit que tem uma string “Signed-off-by” na mensagem e uma cruz vermelha naquele em que o autor esqueceu de assinar (sign off). Você também pode ver que o Pull Request pega o status do último commit no branch e o avisa se for uma falha. Isso é realmente útil se você estiver usando esta API para resultados de testes, para que não mescle acidentalmente algo em que o último commit esteja falhando nos testes.
Octokit
Embora tenhamos feito quase tudo através de curl e simples requisições HTTP nestes exemplos, existem várias bibliotecas de código aberto que disponibilizam esta API de uma maneira mais idiomática.
No momento em que este livro foi escrito, as linguagens suportadas incluíam Go, Objective-C, Ruby e .NET.
Confira https://github.com/octokit para obter mais informações sobre eles, pois eles lidam com grande parte do HTTP para você.
Esperamos que estas ferramentas possam ajudá-lo a personalizar e modificar o GitHub para funcionar melhor com os seus fluxos de trabalho específicos. Para a documentação completa de toda a API, bem como guias para tarefas comuns, confira https://docs.github.com/.