-
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
7.14 Ferramentas do Git - Armazenamento de Credenciais
Armazenamento de Credenciais
Se você usa o transporte SSH para se conectar a remotes, pode ter uma chave sem frase secreta, o que permite transferir dados com segurança sem digitar seu nome de usuário e sua senha. No entanto, isso não é possível com os protocolos HTTP – toda conexão exige um nome de usuário e uma senha. Isso se torna ainda mais difícil em sistemas com autenticação de dois fatores, nos quais o token usado como senha é gerado aleatoriamente e é impronunciável.
Felizmente, o Git possui um sistema de credenciais que pode ajudar com isso. O Git oferece algumas opções prontas para uso:
-
O padrão é não armazenar nada em cache. Toda conexão solicitará seu nome de usuário e sua senha.
-
O modo “cache” mantém as credenciais na memória por determinado período. Nenhuma senha é armazenada em disco, e elas são removidas do cache depois de 15 minutos.
-
O modo “store” salva as credenciais em um arquivo de texto puro no disco, e elas nunca expiram. Isso significa que, enquanto você não alterar sua senha no host Git, nunca mais precisará digitar suas credenciais. A desvantagem dessa abordagem é que suas senhas ficam armazenadas sem criptografia em um arquivo de texto puro no seu diretório pessoal.
-
Se você usa macOS, o Git inclui um modo “osxkeychain”, que armazena as credenciais no chaveiro seguro associado à sua conta do sistema. Esse método armazena as credenciais em disco, e elas nunca expiram, mas são criptografadas pelo mesmo sistema que armazena certificados HTTPS e dados de preenchimento automático do Safari.
-
Se você usa Windows, pode habilitar o recurso Git Credential Manager ao instalar o Git for Windows ou instalar separadamente a versão mais recente do GCM como um serviço independente. Ele é semelhante ao helper “osxkeychain” descrito acima, mas usa o Gerenciador de Credenciais do Windows para controlar informações confidenciais. Ele também pode fornecer credenciais ao WSL1 ou WSL2. Consulte as instruções de instalação do GCM para obter mais informações.
Você pode escolher um desses métodos definindo um valor de configuração do Git:
$ git config --global credential.helper cache
Alguns desses helpers possuem opções.
O helper “store” aceita um argumento --file <path>, que personaliza o local em que o arquivo de texto puro é salvo (o padrão é ~/.git-credentials).
O helper “cache” aceita a opção --timeout <seconds>, que altera o tempo durante o qual seu daemon permanece em execução (o padrão é “900”, ou 15 minutos).
Este é um exemplo de como configurar o helper “store” com um nome de arquivo personalizado:
$ git config --global credential.helper 'store --file ~/.my-credentials'
O Git permite até mesmo configurar vários helpers.
Ao procurar credenciais para um host específico, o Git consultará os helpers em ordem e parará assim que receber a primeira resposta.
Ao salvar credenciais, o Git enviará o nome de usuário e a senha para todos os helpers da lista, e cada um poderá decidir o que fazer com eles.
Este é o aspecto de um arquivo .gitconfig caso você tivesse um arquivo de credenciais em um pen drive, mas quisesse usar o cache em memória para evitar digitação quando o dispositivo não estivesse conectado:
[credential]
helper = store --file /mnt/thumbdrive/.git-credentials
helper = cache --timeout 30000
Por Baixo dos Panos
Como tudo isso funciona?
O comando principal do Git para o sistema de helpers de credenciais é git credential, que recebe um comando como argumento e mais dados pela entrada padrão.
Talvez seja mais fácil entender com um exemplo.
Suponha que um helper de credenciais tenha sido configurado e armazenado credenciais para mygithost.
Esta sessão usa o comando “fill”, invocado quando o Git tenta encontrar credenciais para um host:
$ git credential fill (1)
protocol=https (2)
host=mygithost
(3)
protocol=https (4)
host=mygithost
username=bob
password=s3cre7
$ git credential fill (5)
protocol=https
host=unknownhost
Username for 'https://unknownhost': bob
Password for 'https://bob@unknownhost':
protocol=https
host=unknownhost
username=bob
password=s3cre7
-
Esta é a linha de comando que inicia a interação.
-
Em seguida, Git-credential aguarda dados na entrada padrão. Fornecemos as informações que conhecemos: o protocolo e o nome do host.
-
Uma linha em branco indica que a entrada terminou e que o sistema de credenciais deve responder com o que sabe.
-
Então, Git-credential assume o controle e grava na saída padrão as informações que encontrou.
-
Se nenhuma credencial for encontrada, o Git solicita ao usuário o nome de usuário e a senha e os devolve na saída padrão do processo que o invocou (aqui, ela está associada ao mesmo console).
Na verdade, o sistema de credenciais invoca um programa separado do próprio Git; qual programa e de que maneira dependem do valor de configuração credential.helper.
Ele pode assumir várias formas:
| Valor de Configuração | Comportamento |
|---|---|
|
Executa |
|
Executa |
|
Executa |
|
O código depois de |
Portanto, os helpers descritos acima na verdade se chamam git-credential-cache, git-credential-store e assim por diante, e podemos configurá-los para receber argumentos de linha de comando.
A forma geral é “git-credential-foo [args] <action>.”
O protocolo de entrada e saída padrão é o mesmo de git-credential, mas esses helpers usam um conjunto de ações ligeiramente diferente:
-
geté uma solicitação de um par de nome de usuário e senha. -
storeé uma solicitação para salvar um conjunto de credenciais na memória desse helper. -
eraseremove da memória desse helper as credenciais correspondentes às propriedades fornecidas.
Para as ações store e erase, nenhuma resposta é necessária (o Git a ignora de qualquer forma).
Para a ação get, porém, o Git se interessa muito pelo que o helper tem a dizer.
Se o helper não souber nada útil, poderá simplesmente encerrar sem produzir saída; se souber, deverá complementar as informações fornecidas com as que armazenou.
A saída é tratada como uma série de atribuições; tudo o que for fornecido substituirá o que o Git já sabe.
Este é o mesmo exemplo anterior, mas sem passar por git-credential e usando diretamente git-credential-store:
$ git credential-store --file ~/git.store store (1)
protocol=https
host=mygithost
username=bob
password=s3cre7
$ git credential-store --file ~/git.store get (2)
protocol=https
host=mygithost
username=bob (3)
password=s3cre7
-
Aqui instruímos
git-credential-storea salvar algumas credenciais: o nome de usuário “bob” e a senha “s3cre7” devem ser usados quandohttps://mygithostfor acessado. -
Agora recuperaremos essas credenciais. Fornecemos as partes da conexão que já conhecemos (
https://mygithost) e uma linha em branco. -
git-credential-storeresponde com o nome de usuário e a senha que armazenamos acima.
Este é o conteúdo do arquivo ~/git.store:
https://bob:s3cre7@mygithost
Ele é apenas uma série de linhas, cada uma contendo uma URL acompanhada de credenciais.
Os helpers osxkeychain e wincred usam o formato nativo dos armazenamentos nos quais se apoiam, enquanto cache usa seu próprio formato em memória (que nenhum outro processo consegue ler).
Um Cache de Credenciais Personalizado
Como git-credential-store e programas semelhantes são separados do Git, não é difícil perceber que qualquer programa pode ser um helper de credenciais do Git.
Os helpers fornecidos pelo Git atendem a muitos casos de uso comuns, mas não a todos.
Por exemplo, suponha que sua equipe tenha credenciais compartilhadas por todos, talvez para fazer deploy.
Elas ficam armazenadas em um diretório compartilhado, mas você não quer copiá-las para seu próprio armazenamento de credenciais, pois elas mudam com frequência.
Nenhum dos helpers existentes atende a esse caso; vejamos o que seria necessário para criar o nosso.
Esse programa precisa ter várias características importantes:
-
A única ação à qual precisamos prestar atenção é
get;storeeerasesão operações de escrita, portanto simplesmente encerraremos sem erros ao recebê-las. -
O formato do arquivo de credenciais compartilhadas é o mesmo usado por
git-credential-store. -
A localização desse arquivo é bastante padronizada, mas devemos permitir que o usuário passe um caminho personalizado por precaução.
Mais uma vez, escreveremos essa extensão em Ruby, mas qualquer linguagem funcionará, desde que o Git possa executar o produto final. Este é o código-fonte completo do nosso novo helper de credenciais:
#!/usr/bin/env ruby
require 'optparse'
path = File.expand_path '~/.git-credentials' # (1)
OptionParser.new do |opts|
opts.banner = 'USAGE: git-credential-read-only [options] <action>'
opts.on('-f', '--file PATH', 'Specify path for backing store') do |argpath|
path = File.expand_path argpath
end
end.parse!
exit(0) unless ARGV[0].downcase == 'get' # (2)
exit(0) unless File.exist? path
known = {} # (3)
while line = STDIN.gets
break if line.strip == ''
k,v = line.strip.split '=', 2
known[k] = v
end
File.readlines(path).each do |fileline| # (4)
prot,user,pass,host = fileline.scan(/^(.*?):\/\/(.*?):(.*?)@(.*)$/).first
if prot == known['protocol'] and host == known['host'] and user == known['username'] then
puts "protocol=#{prot}"
puts "host=#{host}"
puts "username=#{user}"
puts "password=#{pass}"
exit(0)
end
end
-
Aqui analisamos as opções da linha de comando, permitindo que o usuário especifique o arquivo de entrada. O padrão é
~/.git-credentials. -
Esse programa só responde se a ação for
gete o arquivo de armazenamento existir. -
Esse laço lê a entrada padrão até encontrar a primeira linha em branco. As entradas são armazenadas no hash
knownpara consulta posterior. -
Esse laço lê o conteúdo do arquivo de armazenamento em busca de correspondências. Se o protocolo, o host e o nome de usuário de
knowncorresponderem à linha, o programa imprimirá os resultados na saída padrão e encerrará.
Salvaremos nosso helper como git-credential-read-only, colocaremos o arquivo em algum local do PATH e o marcaremos como executável.
Esta é a aparência de uma sessão interativa:
$ git credential-read-only --file=/mnt/shared/creds get
protocol=https
host=mygithost
username=bob
protocol=https
host=mygithost
username=bob
password=s3cre7
Como seu nome começa com “git-”, podemos usar a sintaxe simples no valor de configuração:
$ git config --global credential.helper 'read-only --file /mnt/shared/creds'
Como você pode ver, estender esse sistema é bastante simples e pode resolver alguns problemas comuns para você e sua equipe.