Escolar Documentos
Profissional Documentos
Cultura Documentos
Magia Git
Magia Git
Ben Lynn
Magia Git
Ben Lynn
Tradutor: Leonardo Siqueira Rodrigues
{leonardo.siqueira.rodrigues@gmail.com}
Fonte utilizadas
Anonymous Pro1
APHont2
ABCDEFGHIJKLMOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
012456789
ABCDEFGHIJKLMOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
012456789
3
Diavlo Black
ABCDEFGHIJKLMOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
012456789
1 http://www.ms-studio.com/FontSales/anonymouspro.html
2 http://www.aph.org/products/aphont.html
3 http://www.exljbris.nl
NDICE
Prefcio..................................................................7
Agradecimentos!......................................................7
Licena...................................................................7
Links......................................................................8
Introduo..........................................................9
Trabalhar Divertido...............................................9
Controle de Verses.................................................9
Controle distribudo................................................10
Uma superstio...................................................................11
Truques bsicos..............................................12
Salvando estados...................................................12
Adicionar, Remover, Renomear................................................12
Desfazer/Refazer avanado......................................13
Revertendo..........................................................................14
Download de arquivos.............................................14
ltima Verso........................................................14
Publicao instantnea............................................14
O que eu fiz?.........................................................15
Um pouco de clonagem.................................16
Sincronizando Computadores...................................16
Controle clssico de cdigo......................................16
Fazendo um Fork do Projeto.....................................17
Backup Supremos..................................................17
Multitarefa na velocidade da luz...............................18
Controle de Verses de Guerrilha..............................18
A tecla chefe.......................................................20
Trabalho porco.......................................................21
Correes rpidas..................................................22
Fluxo ininterrupto..................................................22
Reorganizando uma improvisao.............................23
Gerenciando o Branch.............................................23
Branch Temporrios...............................................24
Trabalhe como quiser..............................................24
Lies de historia...........................................26
Estou correto.........................................................26
e tem mais.........................................................26
Alteraes locais por ltimo.....................................27
Reescrevendo o histrico.........................................27
Fazendo histria....................................................28
Onde tudo comeou a dar errado?............................29
Quem Fez Tudo Dar Errado?....................................30
Experincia pessoal................................................30
Gro-Mestre Git.............................................32
Disponibilizao de Cdigo.......................................32
Gerao do Registro das Modificaes........................32
Git por SSH, HTTP.................................................32
Git Acima de Tudo..................................................33
Commit do que Mudou............................................33
Meu Commit To Grande!.....................................34
No perca a CABEA (HEAD)...................................35
Explorando o HEAD................................................35
Baseando se no Git.................................................36
Dubls Duros na Queda...........................................37
Segredos Revelados.......................................39
Invisibilidade.........................................................39
Integridade...........................................................39
Inteligncia...........................................................40
Indexando............................................................41
Repositrios Crus...................................................41
Origem do Git.......................................................41
Atalhos do Git.................................................42
Microsoft Windows.................................................42
Arquivos Independentes..........................................42
Quem Est Editando O Que?....................................42
Arquivo do Histrico...............................................43
Clone Inicial..........................................................43
Projetos Volteis....................................................43
Contador Global.....................................................44
Subdiretrios Vazios...............................................44
Commit Inicial.......................................................45
Magia Git
Prefcio
Git4 um canivete suo do controle de verses. Uma ferramente polivalente
realmente verstil cuja extraordinria flexibilidade torna-o complicado de aprender, sobre tudo sozinho. Coloquei nestas paginas o pouco que aprendi, pois inicialmente tive dificuldade em compreender o manual do usurio do Git5.
Como Arthur C. Clarke6 bem comentou: Qualquer tecnologia suficientemente
avanada considerada magica. Esta uma tima forma de abordar o Git: novatos podem ignorar seu funcionamento interno e v-lo como algo divertido que
pode agradar aos amigos e enfurecer os inimigos com suas horrendas habilidades.
Ao invs de entrar em detalhes, forneceremos apenas instrues para casos
especficos. Aps o uso repetido, voc gradualmente entender como cada truque, e como adaptar as receitas s suas necessidades.
Outras Edies
Traduo Chinesa7: por JunJie, Meng e JiangWei.
Pagina nica8: HTML, sem CSS.
Arquivo PDF9: pronto para imprimir.
Agradecimentos!
Agradecimentos a Dustin Sallings, Alberto Bertogli, James Cameron, Douglas
Livingstone, Michael Budde, Richard Albury, Tarmigan e Derek Mahar pelas sugestes e melhorias. [Se esqueci de voc, por favor avise, as vezes esqueo de
atualizar esta seco.]
Licena
Este guia regido pelos termos da the GNU General Public License version 310.
Naturalmente, os fontes esto num repositrio Git, e so obtido digitando:
$ git clone git://repo.or.cz/gitmagic.git
Links
Uma vez listei algumas referncias, porm consome muito tempo mante-las.
Alm disso, qualquer um pode usar um site de busca para encontrar tutoriais,
guias e comparaes do Git com Subversion11, Mercurial12, ou outro sistema de
controle de verses.
Repositrios Git grtis
http://repo.or.cz/ hospeda projetos livres, inclusive este guia.
http://gitorious.org/ outro site de hospedagem Git destinado a projetos de cdigo aberto.
http://github.com/ hospeda projetos de cdigo aberto de graa, inclusive este guia, e projetos privados tambm.
11 http://subversion.tigris.org/
12 http://www.selenic.com/mercurial/
Magia Git
Introduo
Usarei uma analogia para falar sobre controle de verses. Veja na Wikipdia o
verbete sistema de controle de verses13 para uma melhor explicao .
Trabalhar Divertido
Me divirto com jogos para computador quase minha vida toda. Em contrapartida, s comecei a usar sistemas de controle de verses quando adulto. Suspeito
que no fui o nico, e comparar os dois pode tornar estes conceitos mais fceis
de explicar e entender.
Pense na edio de seu cdigo, documento, ou qualquer outra coisa, como jogar um jogo. Uma vez que tenha feito muitos progressos, e gostaria de de salvalos. Pra isso, voc clica em Salvar no seu editor preferido.
Porm isto vai sobrescrever a verso anterior. como nos antigos jogos onde
voc s tinha uma espao para salvar: voc pode salvar, mas nunca mais poder
voltar a um estado salvo anteriormente. O que um pena, pois o estado anterior
era uma parte muito divertida do jogo e voc gostaria de poder revisita-lo outra
hora. Ou pior, o ultimo estado salvo um dificlimo e voc ter que recomear.
Controle de Verses
Ao editar, voc pode Salvar como ... num arquivo diferente, ou copiar o arquivo antes de sobrescreve-lo se voc quiser manter as verses anteriores. Pode
comprimi-los para economizar espao. Isto uma forma rudimentar e muito trabalhosa de controle de verses. Jogos de computador aperfeioaram este mtodo, muitos deles acrescentam automaticamente a data e a hora aos estados salvos.
Vamos dificultar um pouco. Digamos que so um monte de arquivos juntos,
como os fontes do seu projeto, ou arquivos para um website. Agora se quiser
manter suas verses anteriores, ter que arquivar todo um diretrio ou vrios.
Manter muitas verses na mo inconveniente e rapidamente se tornar caro.
Em alguns jogos de computador, um estado salvo consiste de um diretrio
cheio de arquivos. Estes jogos escondem estes detalhes do jogador e lhe apresentam uma interface conveniente para gerenciar as diferentes verses neste diretrio.
13 http://pt.wikipedia.org/wiki/Sistema_de_controle_de_verso
10
Introduo
Sistemas de controle de verses no so diferentes. Todos tem uma boa interface para gerenciar seu diretrio de verses. Voc pode salvar o diretrio sempre
que desejar, e pode rever qualquer um dos estado salvos quando quiser. Ao contrrio da maioria dos jogos de computador, eles so geralmente mais espertos na
economia de espao. Normalmente, apenas uns poucos arquivos mudam de verso para verso, e com poucas diferenas. Armazenar as diferenas, ao invs de
todos os arquivos, economiza espao.
Controle distribudo
Agora imagine um jogo de computador muito difcil. To difcil de terminar
que vrios jogadores experientes pelo mundo decidem formar uma equipe e
compartilhar seus estados salvos do jogo para tentar vence-lo. Speedruns so
exemplos reais: jogadores especializados em diferentes nveis do mesmo jogo colaboram na produo de resultados incrveis.
Como voc configura um sistema para que todos possam obter facilmente o
que os outros salvarem? E salvar novos estados?
Nos velhos tempos, todos os projetos utilizava controle de verses centralizado.
Um servidor em algum lugar mantm os jogos salvos. Ningum tem todos. Cada
jogador mantm, em sua maioria, apenas alguns jogos salvos em suas maquinas.
Quando algum jogador quiser avanar no jogo, ele pega o ultimo jogo salvo do
servidor, joga um pouco, salva e manda de volta para o servidor para que os outros possam usar.
E se um jogador quiser pegar um antigo jogo salvo por algum motivo? Talvez o
atual jogo salvo esteja em um nvel impossvel de jogar devido algum ter esquecido um objeto trs nveis atrs, e preciso encontrar o ultimo jogo salvo que
est em um nvel que pode ser completado com sucesso. Ou talvez queira comparar dois jogos salvo para saber o quanto um jogador avanou.
Podem existir vrios motivos para ver uma verso antiga, mas o modus operandi o mesmo. Tm que solicitar ao servidor centralizado a antiga verso. E
quanto mais jogos salvos forem necessrios, maior o trafego de informao.
A nova gerao de sistemas de controle de verses, dentre eles o Git, conhecida como sistemas distribudos, e pode ser pensada como uma generalizao dos
sistemas centralizados. Quando os jogadores pegam do servidor, eles recebem todos os jogos salvos, e no apenas o mais recente. como se estivessem espelhando o servidor.
A primeira operao de clonagem pode ser bem demorada, especialmente se
h um longo histrico, mas compensada no longo prazo. Um beneficio imediato
que, se por qualquer raso desejar uma antiga verso, a trafego de informao
com o servidor desnecessrio.
Magia Git
11
Uma superstio
Um equvoco popular que sistemas distribudos esto mal adaptados projetos
que exijam um repositrio central oficial. Nada poderia estar mais longe da verdade. Fotografar algum roubara sua alma. Igualmente, clonar o repositrio
master no diminui sua importncia.
Uma boa comparao inicial : qualquer coisa que um sistema centralizado de
controle de verses faz, um sistema distribudo de controle de verses bem concebido pode fazer melhor. Recursos de rede simplesmente mais oneroso que recursos locais. Embora vejamos mais adiante que existem inconvenientes numa
abordagem distribuda, menos provvel que faa comparaes errneas com
esta regra de ouro.
Um pequeno projeto pode precisar de apenas uma frao dos recursos oferecidos pelo sistema. Mas, voc usa algarismos romanos quando calcula com nmeros pequenos? E mais, seu projeto pode crescer alm da suas expectativas.
Usando Git, desde o inicio como ter um canivete suo, embora o use na maioria das vezes para abrir garrafas. No dia que necessitar, desesperadamente, de
uma chave de fenda voc agradecer por ter mais do que um abridor de garrafas.
12
Truques Bsicos
Truques Bsicos
Ao invs de se aprofundar no mar de comandos do Git, use estes exemplos
elementares para dar os primeiros passos. Apesar de suas simplicidades, cada um
deles so muito teis. Na verdade, no meu primeiro ms com o Git, nunca precisei ir alm das informaes deste captulo.
Salvando estados
Pensando em tentar algo mais arriscado? Antes de faz-lo, tire um fotografia
de todos os arquivos do diretrio atual com:
$ git init
$ git add .
$ git commit -m "Meu primeiro backup"
para voltar para o estado anterior. Para salvar o estado novamente, faa:
$ git commit -a -m "Outro backup"
Do mesmo modo, se voc quiser que o Git na verifique certos arquivos, talvez
por t-los apagados, faa:
$ git rm ANTIGOSARQUIVOS...
Magia Git
13
Desfazer/Refazer avanado
s vezes, voc s quer voltar e esquecer todas as mudanas realizadas a partir
de um certo ponto, pois esto todos erradas. Ento:
$ git log
mostrar uma lista dos ltimos commit e seus hash SHA1. Em seguida, digite:
$ git reset --hard SHA1_HASH
lhe levar de volta para o presente. Assim faa o Git parar de reclamar, sempre faa commit ou reset suas mudanas antes de executar um checkout.
Voltemos para a analogia dos jogos de computador :
git reset --hard: carrega um antigo salvamento e apagar todos os
salvamento mais novos do que este que foi carregado.
git checkout: carrega um antigo salvamento, mas se jogar a partir
dele, os prximos salvamento realizados se desvincularo dos salvamentos
j realizados aps o que foi carregado. Qualquer salvamento que voc fizer
ser colocado em um branch separado representado a realidade alternativa
em que entrou. Lidaremos com isso mais a frente.
Voc pode escolher restaurar apenas alguns arquivos ou diretrios acrescentando-os ao final do comando.
No gosta de copiar e colar hash? Ento use:
$ git checkout :/"Meu primeiro b"
14
Truques Bsicos
para ir ao commit que comea a frase informada. Voc tambm pode solicitar
pelo estado salvo a 5 commit atrs:
$ git checkout master~5
Revertendo
Como num tribunal, eventos podem ser retirados dos registros. Igualmente,
voc pode especificar qual commit desfazer.
$ git commit -a
$ git revert SHA1_HASH
Download de arquivos
Obtenha a cpia dum projeto gerenciado com GIT digitando:
$ git clone git://servidor/caminho/dos/arquivos
Por exemplo, para obter todos os arquivos usados para criar este site:
$ git clone git://git.or.cz/gitmagic.git
ltima Verso
Se voc j obteve a copia de um projeto usando git clone, pode agora atualizar para a ltima verso com:
$ git pull
Publicao instantnea
Suponha que voc tenha escrito um script e gostaria de compartilha-lo. Voc
poderia simplesmente dizer para pegarem do seu computador, mas se o fizerem
enquanto voc esta melhorando o script ou experimentado algumas mudanas,
eles podem ter problemas. Obviamente, por isso que existem ciclos de liberao. Desenvolvedores podem trabalhar num projeto com frequncia, mas s disponibilizam o cdigo quando sentem que o mesmo esta apresentvel.
Para fazer isso com Git, no diretrio onde est seu script, execute:
Magia Git
15
$ git init
$ git add .
$ git commit -m "Primeira liberao"
para obter seu script. Assume-se que eles tm acesso ssh. Se no, execute
git daemon e avise-os para executar:
$ git clone git://seu.computador/caminho/do/script
A partir de agora, toda vez que seu script estiver pronto para liberar, execute:
$ git commit -a -m "Nova liberao"
e seu usurios podem atualizar suas verses, indo para o diretrio que contm
seu script, e executando:
$ git pull
Seu usurios nunca ficaro com uma verso do seu script que voc no queira.
Obviamente este truque serve para tudo, no apenas script.
O que eu fiz?
Saiba quais as mudanas que voc fez desde o ltima commit com:
$ git diff
Ou desde ontem:
$ git diff "@{yesterday}"
Tente tambm:
$ git whatchanged --since="2 weeks ago"
As vezes navego pelo histrico com o qgit14, em razo de sua interface mais
fotognica, ou com o tig15, uma interface em modo texto tima para conexes
lentas. Alternativamente, instale um servidor web, execute git instaweb e use
um navegador.
14 http://sourceforge.net/projects/qgit
15 http://jonas.nitro.dk/tig/
16
Um Pouco De Clonagem
Um Pouco De Clonagem
Em sistemas de controle de verses mais antigos, checkout a operao padro para se obter arquivos. Obtendo assim os arquivos do ponto de salvamento
informado.
No Git e em outros sistemas distribudos de controle de verses, clonagem a
operao padro. Para obter os arquivos clonasse o repositrio inteiro. Em outras
palavras, voc praticamente faz um espelhamento do servidor central. Tudo o
que se pode fazer no repositrio principal, voc pode fazer no seu repositrio local.
Sincronizando Computadores
Esta foi a razo pela qual usei o Git pela primeira vez. Eu posso aguentar fazer
tarball16 ou usar o rsync para backup e sincronizaes bsicas. Mas as vezes edito
no meu laptop, outras no meu desktop, e os dois podem no ter conversado entre si nesse perodo.
Inicialize um repositrio Git e commit seus arquivos em uma das maquinas.
Ento na outra:
$ git clone outro.computador:/caminho/dos/arquivos
para criar uma segunda copia dos seus arquivos e do repositrio Git. A partir
de agora, use:
$ git commit -a
$ git pull outro.computador:/caminho/dos/arquivos
o que deixar os arquivos da maquina em que voc est trabalhando, no mesmo estado que esto no outro computador. Se voc recentemente fez alguma alterao conflitante no mesmo arquivo, o Git lhe informar e voc poder fazer
um novo commit e ento escolher o que fazer para resolv-lo.
Magia Git
17
Algumas hospedagens publicas, tais como o repo.or.cz, tero mtodos diferentes para configurar o repositrio inicial em branco, como atravs do preenchimento de um formulrio no site deles.
Mande seu projeto para o servidor principal com:
$ git push git://servidor.principal/caminho/do/proj.git HEAD
Backup Supremos
Gostaria de numerosos arquivos geograficamente dispersos, redundantes e
anti-falsificaes? Se seu projeto tem muitos desenvolvedores, no faa nada!
Cada clonagem do seu cdigo um backup efetivo. E no apenas uma cpia do
17 http://pt.wikipedia.org/wiki/Fork
18
Um Pouco De Clonagem
estado atual, e sim o histrico completo do seu projeto. Graas ao hash criptogrfico, se cada clonagem for corrompida, ele ser identificado assim que tentar
se comunicar com os outros.
Se seu projeto no to popular, encontre quantos servidores puder para hospedar seus clones.
Um paranoico verdadeiro sempre anotar os ltimos 20 byte do hash SHA1 do
cabealho (HEAD) em algum lugar seguro. Tem que ser seguro, e no privado.
Por exemplo, publica-lo em um jornal funciona bem, pois muito difcil para um
atacante alterar todas as cpias de um jornal.
Agora vai para o novo diretrio e trabalhe nele, no no anterior, usando Git
para felicidade geral da nao. De vez em quando voc desejar sincronizar com
os outros, neste caso, v para o diretrio original, sincronize usando o outro sistema de controle de verses, e ento digite:
Magia Git
19
$ git add .
$ git commit -m "Sincronizando com os outros"
18 http://google-opensource.blogspot.com/2008/05/export-git-project-to-google-code.html
20
A tecla chefe
Sempre jogue um desses jogos que ao apertar de um boto (a tecla chefe), a
tela instantaneamente mudar para uma planilha ou algo mais srio. Assim se o
chefe passar pelo seu escritrio enquanto voc estiver jogando, poder rapidamente esconder o jogo.
Em algum diretrio:
$
$
$
$
21
Magia Git
Criamos um repositrio Git que rastrear um arquivo texto contendo uma certa mensagem. Agora digite:
$ git checkout -b chefe # nada parece ter mudado aps isto
$ echo "Meu chefe mais esperto que eu" > meuarquivo.txt
$ git commit -a -m "Outro commit"
Voc pode trocar entre as duas verses do arquivo quantas vezes quiser, e fazer commit independentes para cada uma.
Trabalho porco
Digamos que voc est trabalhando em alguma funo, e por alguma razo,
precisa voltar para uma antiga verso e temporariamente colocar algumas declaraes de controle para ver como algo funciona. Ento:
$ git commit -a
$ git checkout SHA1_HASH
Agora voc pode adicionar temporariamente cdigo feio em todo canto. Pode
at fazer commit destas mudanas. Quando estiver tudo pronto,
$ git checkout master
para voltar para o trabalho original. Observe que qualquer mudana sem
commit so temporrias.
E se voc desejasse salvar as mudanas temporrias depois de tudo? Fcil:
$ git checkout -b sujeira
e faa commit antes de voltar ao branch master. Sempre que quiser voltar
sujeira, simplesmente digite:
$ git checkout sujeira
Ns j falamos deste comando num captulo anterior, quando discutimos carregamento de antigos estados salvos. Finalmente podemos contar toda a histria:
os arquivos mudam para o estado requisitado, porm samos do branch master.
Cada commit realizado a partir deste ponto nos seus arquivos o levaro em outra
22
Correes rpidas
Voc esta fazendo algo quando mandam largar o que quer que seja e corrigir
um erro recm descoberto:
$ git commit -a
$ git checkout -b correes SHA1_HASH
Fluxo ininterrupto
Alguns projetos requerem que seu cdigo seja revisado antes que o envie. Para
tornar a vida fcil daqueles que forem revisar seu cdigo, se voc tem um a
grande mudana para fazer, voc pode quebra em dois ou mais partes, e ter cada
parte revisada separadamente.
E se a segunda parte no puder ser escrita at que a primeira seja aprovada e
revisada? Em muitos sistemas de controle de verses, voc teria que mandar a
primeira parte para os revisores, e aguardar at que seja aprovada para ento comear a segunda parte.
Atualmente isso no verdade, mas nestes sistemas de edio da segunda
parte antes da primeira ser aprovada envolve muito sofrimento e privaes. No
Git, os branch e merge so indolores (termo tcnico para rpido e local). Ento
aps fazer o commit da primeira parte e enviado para reviso:
$ git checkout -b parte2
Magia Git
23
Agora como anteriormente. Logo que a primeira parte for aprovada e enviada:
$ git checkout master
$ git merge parte2
$ git branch -d parte2
A seguir, trabalhe em alguma coisa: corrigindo erros, adicionando funes, adicionando cdigo temporrio, e assim por diante, faa commit muitas vezes ao
longo do caminho. Ento:
$ git checkout organizado
$ git cherry-pick SHA1_HASH
aplique um dado commit ao branch "organizado". Com os cherry-picks apropriados voc pode construir um branch que contm apenas cdigo permanente, e
tem commit relacionados agrupados juntos.
Gerenciando o Branch
Digite:
$ git branch
24
Branch Temporrios
Depois de um tempo voc perceber que est criando branch de curta durao, frequentemente e por motivos parecidos: cada novo branch serve apenas
para guardar o estado atual, assim voc pode rapidamente voltar para estados
antigos para corrigir um erro ou algo assim.
anlogo a mudar o canal da TV temporariamente para ver o que esta passando nos outros canais. Mas, ao invs de apertar dois botes, voc esta criando,
checando e apagando branch temporrios e seus commit. Felizmente, o Git tem
um atalho que to conveniente como um controle remoto de TV:
$ git stash
Isto salva o estado atual num local temporrio (um stash) e restaura o estado
anterior. Seu diretrio de trabalho parece ter voltado ao estado anteriormente
salvo, e voc pode corrigir erros, puxar as mudanas mais novas, e assim por
diante. Quando quiser retornar ao estado anterior ao uso do stash, digite:
$ git stash apply
Magia Git
25
Outro exemplo o utilitrio screen21. Esta preciosidade lhe permite criar, destruir e alternar entre mltiplas sesses de terminais no mesmo terminal. Ao invs de abrir novos terminais (clone), voc pode use o mesmo se usar o screen
(branch). Na realidade, voc pode fazer muito mais com o screen mas isso assunto para outro texto.
Clonagem, branch e merge so rpidos e locais no Git, encorajando-o a usar a
combinao que mais lhe convir. Git deixa voc trabalhar exatamente como quiser.
21 http://www.gnu.org/software/screen/
26
Lies De Historia
Lies De Historia
Uma consequncia da natureza distribuda do Git que o histrico pode ser
editado facilmente. Mas se voc adulterar o passado, tenha cuidado: apenas rescreva a parte do histrico que s voc possui. Assim como as naes sempre argumentam sobre quem comete atrocidades, se algum tiver um clone cuja verso do histrico seja diferente do seu, voc pode ter problemas para conciliar
suas rvores quando interagirem.
Claro, se voc controlar todas as outras rvores tambm, ento no h problema, uma vez que pode sobrepor-las.
Alguns desenvolvedores gostam de um histrico imutvel, com falhas ou no.
Outros, que suas rvores estejam apresentveis antes de libera-las ao pblico. O
Git contempl ambos pontos de vista. Tal como clonagem, branch e merge, rescrever o histrico simplesmente outro poder que o Git lhe concede. Cabe a
voc a us-lo sabiamente.
Estou correto
Acabou de fazer um commit, mas queria ter escrito uma mensagem diferente?
Ento execute:
$ git commit --amend
para mudar a ultima mensagem. Percebeu que esqueceu de adicionar um arquivo? Execute git add para adiciona-lo, e ento execute o comando acima.
Quer incluir mais algumas modificaes no ultimo commit? Faa-as e ento
execute:
$ git commit --amend -a
e tem mais
Suponha que o problema anterior dez vezes pior. Aps uma longa sesso
onde fez um monte de commit. E voc no est muito feliz com a organizao
deles, e algumas das mensagens dos commit poderiam ser reformuladas. Ento
execute:
$ git rebase -i HEAD~10
Magia Git
27
Ento:
Remova os commit deletando linhas;
Reorganize os commit reorganizando linhas;
Substitua pick por edit para modificar a mensagem do commit;
Substitua pick por squash para unir (merge) um commit com o anterior.
Se marcar um commit para edio, execute:
$ git commit --amend
Portanto, faa commit cedo e com freqncia: e arrume tudo facilmente mais
tarde com um rebase.
Reescrevendo o histrico
Eventualmente, ser necessrio que seu controle de cdigo tenha algo equivalente ao modo Stanlinesco de retirada de pessoas das fotos oficiais, apagando-os
da histria. Por exemplo, suponha que temos a inteno de lanar um projeto,
mas este envolve um arquivo que deve ser mantido privado por algum motivo.
Talvez eu deixe meu numero do carto de crdito num arquivo texto e acidentalmente adicione-o ao projeto. Apaga-lo insuficiente, pois, pode ser acessado pe-
28
Lies De Historia
Veja git help filter-branch, que discute este exemplo e mostra um mtodo
mias rpido. No geral, filter-branch permite que voc altere grandes sees do
histrico s com um comando.
Depois, voc deve substituir os clones do seu projeto pela verso revisada se
desejar interagir com eles depois.
Fazendo histria
Quer migrar um projeto para Git? Se ele for gerenciado por um algum dos sistemas mais conhecidos, ento possvel que algum j tenha escrito um script
para exportar todo o histrico para o Git.
Seno, de uma olhada em git fast-import, que l um texto num formato especifico para criar o histrico Git do zero. Normalmente um script usando este
comando feito as pressas sem muita frescura e executado uma vez, migrando
o projeto de uma s vez.
Por exemplo, cole a listagem a seguir num arquivo temporrio, como
/tmp/history:
commit refs/heads/master
committer Alice <alice@example.com> Thu, 01 Jan 1970 00:00:00 +0000
data <<EOT
Initial commit.
EOT
M 100644 inline hello.c
data <<EOT
#include <stdio.h>
int main() {
printf("Hello, world!\n");
return 0;
}
EOT
commit refs/heads/master
committer Bob <bob@example.com> Tue, 14 Mar 2000 01:59:26 -0800
data <<EOT
Replace printf() with write().
EOT
M 100644 inline hello.c
data <<EOT
#include <unistd.h>
int main() {
write(1, "Hello, world!\n", 14);
return 0;
}
EOT
Magia Git
29
Seno, substitua bad por good. O Git novamente o levar at um estado intermedirio entre as verses definidas como good e bad, diminuindo as possibilidades. Aps algumas iteraes, esta busca binria o guiar at o commit onde comeou o problema. Uma vez terminada sua investigao, volte ao estado original
digitando:
$ git bisect reset
30
Lies De Historia
que marca cada linha do arquivo indicado mostrando quem o modificou por ltimo e quando. Ao contrrio de outros sistemas de controle de verses, esta operao ocorre offline, lendo apenas do disco local.
Experincia pessoal
Em em sistema de controle de verses centralizado, modificaes no histrico
so operaes difceis, e disponveis apenas para administradores. Clonagem,
branch e merge so impossveis sem uma rede de comunicao. Restando as
operaes bsicas: navegar no histrico ou fazer commit das mudanas. Em alguns sistemas, exigido do usurio um conexo via rede, apenas para visualizar
suas prprias modificaes ou abrir um arquivo para edio.
Sistemas centralizados impedem o trabalho offline, e exigem um infraestrutura de rede mais cara, especialmente quando o numero de desenvolvedores aumenta. Mais importante, todas a operaes so mais lentas, at certo ponto, geralmente at o ponto onde os usurios evitam comandos mais avanados at serem absolutamente necessrios. Em casos extremos, esta a regra at para a
maioria dos comandos bsicos. Quando os usurios devem executar comandos
lento, a produtividade sofre por causa de uma interrupo no fluxo de trabalho.
J experimentei este fenmeno na pele. O Git foi o primeiro sistema de controle de verses que usei. E rapidamente cresci acostumado a ele, tomando muitas de suas caractersticas como garantia. Simplesmente assumi que os outros
sistemas eram semelhante: escolher um sistema de controle de verses deveria
ser igual a escolher um novo editor de texto ou navegador para internet.
Fiquei chocado quando, posteriormente, fui forado a usar um sistema centralizado. Minha, frequentemente ruim, conexo com a internet pouco importa com o
Git, mas torna o desenvolvimento insuportvel quando precisa ser to confivel
quanto o disco local. Alm disso, me condicionava a evitar determinados comandos devido a latncia envolvida, o que me impediu, em ultima instancia, de conti-
Magia Git
31
22 http://pt.wikipedia.org/wiki/Tragdia_dos_comuns
32
Gro-Mestre Git
Gro-Mestre Git
Este capitulo de nome pomposo minha lixeira para truques do Git no classificados.
Disponibilizao de Cdigo
Para meus projetos, o Git organiza exatamente os arquivos que quero guardar
e disponibilizar para os usurios. Para criar um tarball do cdigo fonte, executo:
$ git archive --format=tar --prefix=proj-1.2.3/ HEAD
Magia Git
33
e ento envia o bundle, nomdepacote, para outro lugar usando o que quiser:
email, pendrive, disquete, uma impresso xxd25 e um scanner com OCR, lendo
bits pelo telefone, sinais de fumaa, etc. O destinatrio recupera os commit do
bundle digitando:
$ git pull nomedopacote
O destinatrio pode fazer isto at num repositrio vazio. Apesar do seu tamanho, nomedopacote contm todo o repositrio Git original.
Em projetos grandes, diminua os resduos empacotando apenas as mudanas
que esto faltando no outro repositrio:
$ git bundle create nomedopacote HEAD ^COMMON_SHA1
O Git analisar os arquivos no diretrio atual e trabalhar nos detalhes, automa25 http://linux.die.net/man/1/xxd
34
Gro-Mestre Git
para fazer um commit, exato, com as modificaes aprovadas (staged). Lembre-se de retirar a opo -a, caso contrrio o commit conter todas as modificaes.
E se voc tiver editado vrios arquivos em vrios locais? Rever cada
modificao uma por uma ser frustante e enfadonho. Neste caso, use
git add -i, cuja interface menos simples, porm mais flexvel. Com algumas
poucas teclas, voc pode aprovar ou no vrios arquivos de uma vez, ou rever e
selecionar as modificaes em um arquivos especifico. Alternativamente, execute
git commit --interactive o que automaticamente efetuar seus commit assim
que terminar de aprovar.
Magia Git
35
ir mover o HEAD trs commit pra trs. Assim todos os comandos do Git passam a agir como se voc no tivesse realizados os ltimos trs commit, enquanto
seus arquivos permanecem no presente. Consulte a pagina do manual do comando git reset para mais aplicaes.
Mas como se faz para voltar para o futuro? Os ltimos commit no sabem do
futuro.
Se voc tem o SHA1 do HEAD original ento:
$ git reset SHA1
Explorando o HEAD
Talvez ORIG_HEAD no seja suficiente. Talvez voc s tenha percebido que
fez um erro descomunal e precisa voltar para um antigo commit de um branch
h muito esquecido.
Na configurao padro, o Git mantm um commit por pelo menos duas semanas, mesmo se voc mandou o Git destruir o branch que o contm. O problema achar o hash certo. Voc pode procurar por todos os volares de hash em
.git/objects e por tentativa e erro encontrar o que procura. Mas h um modo
mais fcil.
O Git guardar o hash de todos os commit que ele calcula em .git/logs. O
sub-diretrio refs contm o histrico de toda atividade em todos os branch, enquanto o arquivo HEAD mostra todos os valores de hash que teve. Este ltimo
pode ser usado para encontrar o hash de um commit num branch que tenha sido
acidentalmente apagado.
O comando reflog fornece uma interface amigvel para estes arquivos de log.
Experimente
36
Gro-Mestre Git
$ git reflog
Leia a seo Specifying Revisions da ajuda com git help rev-parse para
mais informaes.
Voc pode querer configurar um longo perodo de carncia para condenar um
commit. Por exemplo:
$ git config gc.pruneexpire "30 days"
Baseando se no Git
Seguindo o jeito UNIX26 de ser, o Git permite ser facilmente utilizado como um
componente de baixo nvel para outros programas. Existem interfaces GUI, interfaces web, interfaces alternativas para linha de comando e talvez em breve
voc crie um script ou dois para suas necessidades usando o Git.
Um truque simples criar alias, abreviaes, internos ao Git para reduzir os
comandos utilizados mais frequentemente:
$ git config --global alias.co checkout
$ git config --global --get-regexp alias
alias.co checkout
$ git co foo
37
Magia Git
Branch: Apagar um branch falha se isto levar a perda das modificaes. Para
forar, digite:
$ git branch -D BRANCH
# ao invs de usar -d
# ao invs de usar -m
38
gue-os sem misericrdia com:
$ git clean -f -d
Gro-Mestre Git
Magia Git
39
Segredos Revelados
Vamos dar uma espiada sob o capo e explicar como o Git realiza seus milagres.
Ser uma explicao superficial. Para detalhes mais aprofundados consultar o
manual do usurio27.
Invisibilidade
Como pode o Git ser to discreto? Fora ocasionais commit e merge, voc pode
trabalhar como se desconhecesse que existe um controle de verses. Isto , at
que precise dele, e quando voc ficar agradecido ao Git por estar vigiando o
que faz o tempo todo.
Outros sistemas de controle de verses no deixam voc esquece-los. As permisses dos arquivos so apenas de leitura, a menos que voc diga ao servidor
quais arquivos tem a inteno de editar. O servidor central estar monitorando
as aes de quem fez o checkout e quando. Quando a rede cair, voc ter um sofrimento repentino. Desenvolvedores constantemente brigam com a burocracia e
a burrocracia virtual.
O segredo o diretrio .git no seu diretrio de trabalho. O Git guarda o histrico do seu projeto nele. O . no inicio do nome esconde ele de uma listagem
ls normal. Exceto quando voc esta fazendo um push ou pull das modificaes,
todas as operaes de controle de verses so neste diretrio.
Voc tem controle total sobre o destino dos seus arquivos pois o Git no se importa com o que faz a eles. O Git pode facilmente recriar um estado salvo a partir do .git a qualquer hora.
Integridade
A maioria das pessoas associam criptografia com manter informaes secretas,
mas outra aplicao igualmente importante manter a integridade da informao. O uso correto das funes criptogrficas de hash podem prevenir o corrupo acidental ou intencional dos dados.
Um hash SHA1 pode ser entendido como um nmero identificador nico de
160 bits para cada sequncia de bytes que voc vai encontrar na vida. Na verdade mais que isso: para cada sequncia de bytes que qualquer ser humano jamais
usar durante vrias vidas. O hash de todo o contedo de um arquivo pode ser
visto como um identificador nico para o mesmo.
27 http://www.kernel.org/pub/software/scm/git/docs/user-manual.html
40
Segredos Revelados
Uma observao importante que um hash SHA1 , ele mesmo, uma sequncia de bytes, assim ns podemos gerar um hash de sequncias de bytes formada
por outros hash.
A grosso modo, todos os arquivos manipulados pelo Git so referenciados pelo
seu identificador nico, e no por seu nome. Todos os dados esto em arquivos
no subdiretrio .git/objects, onde no h nenhum arquivo com nomes normais. O contedo so sequncias de bytes chamados de blob e eles no tem relao com seus nomes.
Seus nomes so registrados em outro lugar. Eles esto nos objetos tree, que
so listas dos nomes dos arquivos formados com os identificadores de seus contedos. Uma vez que o tree uma sequncia de bytes, ele tambm tem um identificador nico, que como ele armazenado no subdiretrio .git/objects. Objetos Tree podem aparecer na lista de outro tree, logo, um diretrio tree e todos os
seus arquivos podem representados por objetos tree e blob.
Finalmente, um commit contm um mensagem, alguns identificadores tree e a
informao de como eles esto relacionados entre si. Um commit tambm um
sequncia de bytes, logo, possui um identificador nico.
Veja voc mesmo: pegue qualquer hash do diretrio .git/objects, digite
$ git cat-file -p SHA1_HASH
Inteligncia
Como o Git sabe que um arquivo foi renomeado, mesmo se voc nunca mencionou o fato explicitamente? Com certeza, voc executou git mv, mas isto
exatamente o mesmo que um git rm seguido por um git add.
A analise heurstica do Git verifica alm das aes de renomear e de copias sucessivas entre verses. De fato, ele pode detectar pedaos de cdigo sendo movidos ou copiados entre arquivos! Embora no cubra todos os casos, faz um traba-
Magia Git
41
lho decente, e esta caracterstica est sendo sempre aprimorada. Caso no funcione com voc, tente habilitar opes mais refinadas para deteco de cpias e
considere uma atualizao.
Indexando
Para cada arquivo monitorado, o Git armazena informaes como: tamanho,
hora de criao e ltima modificao, em um arquivo conhecido como index. Para
determinar se um arquivo foi modificado, o Git compara seus status atual com o
que tem no index. Se coincidem, ento ele pode ignorar o arquivo.
J que verificaes de status so imensamente mais baratas que ler o contedo do arquivo, se voc editar poucos arquivos, o Git vai atualizar seus status
quase que instantaneamente.
Repositrios Crus
Voc pode estar imaginando que formato o repositrio online do Git usa. Eles
so repositrios Git simples, iguais ao seu diretrio .git, exceto que eles tem nomes como proj.git, e no tem nenhum diretrio de trabalho associado a eles.
A maioria dos comandos do Git esperam que o index do Git esteja no .git, e
falharo nos repositrios crus. Corrija isto configurando a varivel de ambiente
GIT_DIR com o caminho do seu repositrio cru, ou executando o Git a partir deste
diretrio com a opo --bare.
Origem do Git
Esta mensagem na lista de discuo do Linux Kernel28 descreve a sequncia de
eventos que levaram ao Git. A discusso inteira um sitio arqueolgico fascinante para historiadores do Git.
28 http://lkml.org/lkml/2005/4/6/121
42
Atalhos Do Git
Atalhos Do Git
H algumas questes sobre o Git que joguei pra debaixo do tapete. Algumas
so facilmente tratadas com script e gambiarras, algumas requerem uma reorganizao ou redefinio do projeto, e para as poucas chateaes remanescentes, s
resta espera por uma soluo. Ou melhor ainda, solucione-as e ajude a todos!
Estive brincando com algumas ideias para sistemas de controle de verses, e
escrevi um sistema experimental baseado no Git29, que aborda algumas desses
questes.
Microsoft Windows
O Git no Microsoft Windows pode ser trabalhoso:
Cygwin30, um ambiente que deixa o Windows parecido com o Linux, tem
uma verso do Git para Windows31.
Git no MSys32 um alternativa que requer suporte minimo para execuo, embora alguns poucos comandos precisem ser mais trabalhados.
Arquivos Independentes
Se seu projeto muito grande e tem muitos arquivos independentes que esto
sendo constantemente modificados, o Git pode ser prejudicado mais do que outros sistemas, pois os arquivos no so monitorados isoladamente. O Git monitora modificaes no projeto como um todo, o que geralmente benfico.
Uma soluo dividir seu projeto em pedaos, cada um composto de arquivos
relacionados. Use git submodule se ainda quiser manter tudo num repositrio s.
Magia Git
43
Arquivo do Histrico
Assim que o Git armazena modificaes muito amplas no projeto, reconstruir o
histrico de um nico arquivo requer mais trabalho do que em sistemas de arquivos de monitoram arquivos individualmente.
A penalidade usualmente rpida, e vale a pena devido a eficincia que d s
outras operaes. Por exemplo, git checkout to rpido quanto cp -a, e os
deltas que abrangem grandes partes do projeto tem uma compresso melhor do
que os deltas de agrupamentos de arquivos.
Clone Inicial
A criao de um clone mais trabalhoso do que fazer checkout em outros sistemas de controle de verses quando h um histrico grande.
O custo inicial se paga a longo prazo, pois as futuras operaes sero mais rpidas e offline. Entretanto, em algumas situaes, prefervel criar um clone oco
com a opo --depth. Isto muito mais rpido, porm resulta em um clone com
funcionalidades reduzidas.
Projetos Volteis
O Git foi feito para ser rpido no que diz respeito ao tamanho das mudanas.
Humanos fazem poucas edies de verso pra verso. a correo de uma falha
numa linha, uma nova caracterstica do sistema, incluso de comentrio e assim
por diante. Mas se seus arquivos diferem muito de uma verso para outra, em
cada commit, seu histrico ir crescer acompanhando o tamanho do seu projeto
todo.
No h nada que qualquer sistema de controle de verses possa fazer pra ajudar, mas os usurios padres do Git devem sofrer mais quando estiverem clonando histricos.
As razes pelas quais as mudanas so to grandes, devem ser analisadas. Talvez os formatos dos arquivos possa ser trocado. Edies menores s devem causar pequenas modificaes em poucos arquivos.
44
Atalhos Do Git
Contador Global
Alguns sistemas centralizados de controle de verses mantm um nmero inteiro positivo que incrementado quando um novo commit aceito. O Git referencia as modificaes por seus hash, o que o melhor na maioria circunstncias.
Mas algumas pessoas gostariam de ter este nmero por perto. Felizmente,
fcil criar um script que faa isso a cada atualizao, o repositrio central do Git
incrementa o nmero, ou talvez uma marca, e associa a mesma com o hash do
ltimo commit.
Cada clone poderia gerenciar este contador, porm isto provavelmente seja
desnecessrio, j que apenas o contador do repositrio central que importar
para todos.
Subdiretrios Vazios
Subdiretrios vazios no so monitorados. Crie arquivos vazios para resolver
esse problema.
A atual implementao do Git, e no seu o design, a razo deste inconveniente. Com sorte, uma vez que o Git ganhe mais trao, mais usurios devem clamar por esse recurso e ele poder ser implementado.
Magia Git
45
Commit Inicial
Um cientista da computao tipico inicia uma contagem do 0, ao invs do 1.
Entretanto, no que diz respeito a commit, o Git no segue esta conveno. Muito
comandos so confusos antes do commit inicial. Alm disso existem algumas
arestas que precisam aparadas manualmente, seja com um rebase de um branch
com um commit inicial diferente.
H benefcios ao Git por definir o commit zero: assim que um repositrio
construdo, o HEAD ser definido para uma sequncia constituda de 20 bytes
zero. Este commit especial representa um tree vazio, sem predecessor, num momento anterior a todos os repositrios Git.
Se em seguida for executado por exemplo, o git log, ser informado ao usurio que ainda no foi realizado nenhum commit, ao invs de terminar devido um
erro fatal. Similar a outras ferramentas.
Todos commit inicial implicitamente um descendente deste commit zero. Por
exemplo, fazendo um rebase num branch no monitorado pode ocasionar um enxerto de todo o branch no destino. Atualmente, todos, inclusive o commit inicial,
sero enxertados, resultando num conflito de merge. Uma soluo usar
git checkout seguido de git commit -C no commit inicial, e um rebase no restante.
Infelizmente h casos piores. Se vrios branch com diferentes commit iniciais
forem mesclados (merge), ento um rebase do resultado vai requer uma substancial interveno manual.