Micro Tutorial de Bazaar Conforme Prometido, vou reproduzir um tutorial idêntico ou pelo menos similar ao tutorial do Akita, só que utilizando o Bazaar ao invés do Git. Recomendo altamente que leia o Artigo Original antes de prosseguir com a leitura, pois vou referenciar ele com bastante freqüência. Pra deixar o ciclo completo eu vou baixar um projeto a partir do Launchpad que seria o “Equivalente” digamos assim do Github. o Akita utilizou com exemplo o Código do Merb Core, eu vou utilizar um branch do próprio Rails, que está disponível no Launchpad, não sei porquê alguém resolveu manter um branch bazaar dele lá no launchpad, mas, o branch existe e vou usá-lo como exemplo. Para poder realizar operações de escrita em um projeto do lanuchpad obviamente você deve se cadastrar lá, e vai ter um ambiente bem similar ao do Github, com chaves publicas etc etc. Para clarear uma das maiores diferenças entre o Bazaar e o Git é que, no Bazaar cada diretório é um branch, ou seja, se eu clonar o branch do rails por exemplo eu terei um diretório rails que é o meu branch, já o Git, o diretório é uma espécie de placeholder(Projeto) e você pode ter quantos branches quiser dentro do mesmo diretório. Também não vou mostrar como instala o Bazaar, visto que há diferenças em cada sistema operacional, e nada que uns 5 minutos de Google não devam resolver, só para constar estou usando a versão 1.9 liberada em 07/11/2008. O projeto rails no Launchpad fica na seguinte url: https://launchpad.net/rails
Para obter o código fonte de um projeto no launchpad o Bazzar possui um recurso que já vem instalado por padrão (como um plugin), logo para baixar o projeto rails via Bazaar faça: bzr clone lp:rails You have not informed bzr of your launchpad login. If you are attempting a write operation and it fails, run "bzr launchpad-login YOUR_ID" and try again. Branched 6711 revision(s).
ele reclamou ali que eu ainda não configurei minha identificação no launchpad,e eu não configurei mesmo . ps: o processo acima vai demorar um pouco, assim como você fazer um clone do edge_rails do github também vai demorar, visto que ele baixa cerca de 41 megabytes.
Pronto, ao final do download você terá um branch contendo todo o histórico de revisões, assim como no git. no Bazaar o comando clone é um alias para o comando branch que tem por finalidade criar um novo branch a partir de outro, portanto clone, branch ou get fazem o mesmo efeito. Agora entre no diretório rails e digite: bzr info Standalone tree (format: pack-0.92) Location: branch root: . Related branches: parent branch: http://bazaar.launchpad.net/%7Evcs-imports/rails/trunk/
Aqui são exibidas a formato atual do sistema de armazenamento, indica que estamos em uma arvore standalone, que estamos trabalhando no branch “root .” e mostra a referência do branch master que é de onde nós pegamos a nossa cópia, e para onde podemos depois enviar nossas alterações. Bem, aqui temos um conceito diferente que, no Bazaar você pode criar repositórios compartilhados e não compartilhados. Nos compartilhados você inicializa um repositório, e cria um branch dentro dele, a partir dai você pode criar tantos branches quanto forem necessários dentro do repositório e todos os recursos serão compartilhados, ou seja vai ficar similar ao Git, já nos repositórios não compartilhados cada branch mantém todo o seu próprio histórico independente. Note que é possível converter de um para outro.
Manipulando branches locais. Bom agora eu tenho uma cópia(branch) do branch remoto em meu computador, eu poderia sair alterando os arquivos direto dentro deste branch e no final mandar as alterações de volta, não há nada de errado com este modelo, mas seguindo o modelo do artigo do Akita, vamos criar um branch para de trabalho e vamos chamar de working, mas primeiro para ficar o mais similar possível vamos renomear o nosso branch que no momento se chama rails para master, assim os comandos vão ficar mais parecidos e em seguida criaremos o nosso novo branch. mv rails master bzr branch master working Branched 6711 revision(s).
E primeiro comando é do Sistema Operacional estou movendo o diretório rails para o diretório master (renomeando) Em seguida crio um novo branch a partir do meu master, note que como ele irá copiar TODAS as revisões para o novo branch vai demorar um pouquinho mais do que no git que é instantânea a criação de um branch, para que tenha um comportamento similar teríamos que usar um repositório compartilhado ao invés de standalone, mas acho que isso é uma preferência pessoal.
Eu poderia agora entrar no novo branch working e fazer minhas alterações lá, mas para ficar mais similar ao Git vou criar primeiro uma cópia de trabalho: bzr checkout working copia cd copia bzr info Checkout (format: pack-0.92) Location: checkout root: . checkout of branch: /home/alexandre/tmp/bazaar/working
podemos perceber que agora estamos dentro de um checkout do branch working. Agora vamos fazer algumas alterações, aqui você pode fazer o que quiser que não vai estragar nada nem no repositório “principal” e nem no seu branch master, em seguida vamos ver o que foi alterado. bzr status modified: Rakefile unknown: alexandre.txt
Bem os arquivos que já estavam no repositório aparecem na sessão modified ou removed, os arquivos que o ainda não estão lá, aparecem na sessão unknown (desconhecidos). Para adicionar o arquivo novo que acabamos de criar, vamos usar o comando add assim como no svn ou git bzr add alexandre.txt added alexandre.txt
caso varios arquivos tenham sido adicionados e você quer adicionar todos ao mesmo tempo (que seria o equivalente do git: git add . ) basta digitar: bzr add
Aqui podemos notar outra diferença bastante grande entre o Bazaar e o Git, no Bazaar diretórios também são “versionados”, como se fossem arquivos regulares, então se criarmos um diretório vazio ele também será adicionado na árvore de versão, o que em muitos casos é util, para não termos que criar um arquivo .bzrignore dentro de uma pasta apenas para que a pasta seja “versionada”. Outra diferença é que o Bazaar ainda não possui uma opção interativa para o add (pelo menos eu desconheço), entretanto eu particularmente nunca senti a necessidade, pois mesmo utilizando o Git eu acabo dando normalmente um add . e um commit -a. Agora com os novos arquivos adicionados podemos dar um commit, bem padrão igual ao svn e bastante similar ao git: bzr commit -m "meu primeiro commit" Committing to: /home/alexandre/tmp/bazaar/working/
modified Rakefile added alexandre.txt Committed revision 6712.
No Bazaar não é necessário a opção -a para “adicionar” as alterações. Observando visualmente:
Bom no nosso caso como estamos em no branch working e ele poderia continuar sosinho parece apenas uma alteracao linear. outra coisa que podemos perceber aqui, é que o Bazaar possui uns nomes de revisão legíveis, o que facilita em alguns procedimentos, procedimentos, internamente o Bazaar controla por um sha1 único para cada revisão tal como no Git ou Mercurial. Bom seguindo o artigo original agora acabamos de descobrir um bug no branch master, então teremos que mudar (switch) para o branch master, então fazemos: bzr switch master Updated to revision 6711. Switched to branch: /home/alexandre/tmp/bazaar/master/ ls alexandre.txt ls: impossível acessar alexandre.txt: Arquivo ou diretório inexistente
bem, primeiro mudamos (switch) para o branch master, master, ou seja agora estamos em uma cópia de trabalho do branch master. agora vamos criar um branch chamado meufix para fazer nossas alterações. bzr branch . ../meufix Branched 6711 revision(s).
Bem, o que fizemos? estávamos em uma copia de trabalho do branch master (igual) entao vamos criar um branch novo “../meufix” baseado no branch (copia de trabalho) atual “.”, note que apenas o comando switch pode ser usado para trocar de branches sem precisar referenciar o diretório, mas agora estamos criando o branch “meufix” no diretório anterior ao atual da copia de trabalho. agora ainda estamos no branch master, vamos mudar para o branch meu fix bzr switch meufix Tree is up to date at revision 6711. Switched to branch: /home/alexandre/tmp/bazaar/meufix/
Não é possível criar um branch e trocar para ele em um comando só, a não ser que usássemos trapassa do Sistema Operacional, que seria mais ou menos assim. bzr branch . ../meufix && bzr switch meufix
Bem, fizemos a nossa correção de bug e vamos dar o commit nas alterações: bzr commit -m "minha correcao" Committing to: /home/alexandre/tmp/bazaar/meufix/ modified Rakefile Committed revision 6712.
Pronto, correçao feita em cima do branch master.
Merges Bom, agora temos o branch master que não chegamos a tocar, temos o branch working onde estávamos trabalhando e fizemos um bugfix em um branch a partir do master. Que zona! mas agora temos que juntar tudo isso. Basicamente os branches working e meufix tem o mesmo ancestral, o master. bem, vamos primeiro pegar o que foi feito no branch meufix e dar um merge. bzr switch master Updated to revision 6711. Switched to branch: /home/alexandre/tmp/bazaar/master/ bzr merge ../meufix M Rakefile All changes applied successfully.
basicamente voltamos para o branch master e demos um merge nele com as informações do branch meufix, agora está tudo junto, podemos dar o commit para aplicar as alterações: bzr commit -m "merge do meufix" Committing to: /home/alexandre/tmp/bazaar/master/ modified Rakefile Committed revision 6712.
vamos ver vizualmente o que aconteceu:
O master estava na revisão 6711, quando eu fiz o branch ele também estava nesta revisao entao fiz as alterações lá o branch meufix, e quando dei o merge novamente o número de versão ficou desta forma: [revisao pai][numero do branch][numero do commit], ou seja 6711.1.1. O numero do branch é gerado incrementalmente a medida que você executa o merge e deve ser lido da seguinte forma, Revisão 6711 branch 1 commit 1. bom agora fizemos tudo que tinhamos que fazer e podemos apagar o branch meufix e voltar a trabalhar na nossa copia de trabalho do branch working. bzr switch working Updated to revision 6712. Switched to branch: /home/alexandre/tmp/bazaar/working/ rm -rf ../meufix
Agora vamos trabalhar, mas, espere, fizemos uma correção no master e precisamos incorporar agora no nosso trabalho, mas, eu já estava no meio de uma alteração que ainda não está acabada, o que fazer?, a resposta é, guarda na prateleira e pega depois . bzr shelve --- alexandre.txt 2008-11-14 16:57:16 +0000 +++ alexandre.txt 2008-11-14 19:18:20 +0000 @@ -0,0 +1 @@ +# Alexandre da Silva Shelve this change? (1 of 1) [yndisq?] (y): y Status: alexandre.txt 2008-11-14 16:57:16 +0000 1 hunks to be shelved
0 hunks to be kept Shelve these changes? [yrsiq?] (y): y Shelving to default/00: "Changes shelved on 2008-11-14 17:18:29"
shelf em Inglês significa prateleira, ou pilha, então empilhamos as nossas alterações em um lugar temporário para usar depois, agora vamos pegar o que estava no master e incorporar aqui. bzr merge ../master M Rakefile All changes applied successfully.
pegas as alterações do master podemos agora pegar o que estávamos fazendo da prateleira e continuar nosso trabalho bzr unshelve --- alexandre.txt 2008-11-14 16:57:16 +0000 +++ alexandre.txt 2008-11-14 19:18:20 +0000 @@ -0,0 +1 @@ +# Alexandre da Silva Unshelve this change? (1 of 1) [yndisq?] (y): y Status: alexandre.txt 2008-11-14 16:57:16 +0000 1 hunks to be unshelved 0 hunks left on shelf Unshelve these changes? [yrsiq?] (y): y Unshelving from default/00: "Changes shelved on 2008-11-14 17:18:29"
pronto, agora podemos continuar nosso trabalho e por fim dar um commit para aplicar as alterações. commit -m "trabalho completo" Committing to: /home/alexandre/tmp/bazaar/working/ modified Rakefile modified alexandre.txt Committed revision 6713.
e Vizualmente o que aconteceu:
agora temos a revisao 6711.2.1 que é do nosso segundo branch a dar merge logo apos o merge do primeiro branch. Bem, no artigo do Akita ele usiliza o comando rebase, que é basicamente similar ao merge só que as alterações são desfeitas e refeitas refeitas uma a uma, e o merge aplica as alterações sobre a copia de trabalho atual, o Bazaar possui o comando rebase também, que pode ser adicionado via plugin, mas como eu nunca utilizei, não sei se ele é estável ou mesmo se vai funcionar com minha versão do do Bazaar que acabou de sair do forno, além do mais na prática o resultado final é o mesmo então aqui ele se torna desnecessário. Para finalizar vamos agora dar o merge no nosso branch master que é de onde veio o código original, e por fim poderíamos enviar todas as alterações devolta para o projeto original. bzr switch master Updated to revision 6712. Switched to branch: /home/alexandre/tmp/bazaar/master/ bzr merge ../working +N alexandre.txt M Rakefile All changes applied successfully. bzr commit -m m "merge com working" Committing to: /home/alexandre/tmp/bazaar/master/ modified Rakefile added alexandre.txt Committed revision 6713.
e visualmente temos o resultado de todo o nosso trabalho:
pode parecer estranho que a versão 6711.2.1 veio depois da 6712, porém ele está mostrando a ordem temporal dos acontecimentos, além do mais fica fácil na visualização saber de onde cada revisão partiu. lembre-se lembre se que internamente as revisões são controladas igual ao git com hashes sha1. Levando em consideração que cada um dos branches que eu criei funciona sozinho, eu posso manter cada um deles e criar outros a partir deles sem nenhuma restrição, inclusive se eu fizer um branch da minha cópia de trabalho, ele ele fará um branch do branch a que ela se refere no momento atual. Para excluir um branch é só excluir o diretório que ele se encontra. o Bazaar traz algumas funcionalidades interessantes que no Git é feito de forma diferente, vejamos:
Rename bzr rename alexandre.txt andre.txt alexandre2.txt alexandre.txt => alexandre2.txt
Sim, no Bazaar eu posso renomear um arquivo explicitamente e ele mantém a referência disso. no Git seria mais ou menos como criar um arquivo novo com o mesmo conteúdo e excluir o anterior, ou realizar aquele processo mágico de comparação de conteúdo que o Akita mostra no artigo dele.
Uncommit bzr commit -m "renomeado" Committing to: /home/alexandre/tmp /home/alexandre/tmp/bazaar/master/
renamed alexandre.txt => alexandre2.txt Committed revision 6714. bzr uncommit 6714 Alexandre da Silva 2008-11-14 renomeado The above revision(s) will be removed. Are you sure [y/N]? y You can restore the old tip by running: bzr pull . -r revid:
[email protected] bzr status renamed: alexandre.txt => alexandre2.txt
Yes!, fiz uma coisa que não devia e dei um commit…. posso dar um uncommit e tudo volta como estava antes do commit. no Git você pode dar um hard reset no HEAD^1, mas o resultado não é exatamente o mesmo.
Conclusão 1. Tudo foi feito offline com exceção do primeiro clone. 2. Assim como no git eu tenho apenas 1 pasta .bzr no diretório principal do branch que controla tudo. 3. Assim como no git podemos criar quantos branches quisermos para fazer nosso trabalho. 4. Assim como no git o tamanho do diretório onde ficam guardados os arquivos com todas as revisões é praticamente do mesmo tamanho da própria cópia de trabalho. 5. Assim como no git podemos trabalhar com um repositório svn remoto usando o bzr-svn e localmente usar todos os recursos do bazaar. 6. E, por fim assim como no git eu escrevi este artigo enquanto digitava os comandos e dava uma olhada no blog do Akita para seguir mais ou menos o mesmo fluxo . E a conclusão final é, seja qual for a ferramenta que você goste mais, Git, Bazaar ou Mercurial, use-a e aprenda a usar bem, pois elas podem economizar um monte de trabalho extra. Este artigo não tem o propósito de dizer que o Bazaar é melhor que o Git ou que o Mercurial, Apenas mostra que oferece os mesmos recursos. para aprender mais sobre o Bazaar visite o site, é a documentação da última versão em desenvolvimento, para outras versões olhe em um diretório acima e escolha a versão que você está usando.