Controle de versão distribuído é diferente, mas nem tanto

Não há dúvidas de que o controle de versão distribuído (Distributed Version Control System – DVCS) veio não só pra ficar, mas também para tomar o lugar das ferramentas de controle de versão centralizado. As etapas têm sido as mesmas de quando apareceu o Subversion com a proposta de substituir o CVS: 1. desconfiança, 2. curiosidade, 3. interesse, 4. aceitação.

Quem está tendo o primeiro contato com o DVCS geralmente cai na fase 1 (desconfiança). Não conhece como funciona e, por isso, desconfia. Afinal, se funciona do jeito que está (mesmo que não muito bem), pra que mudar?

O pessoal da fase 2 (curiosidade) já leu algo a respeito e está intrigado com as vantagens que “dizem” que o DVCS tem. Mas ainda falta um empurrãozinho para pelo menos tentar experimentar um DVCS pra ver como é.

O objetivo deste artigo é apresentar um experimento simples e rápido mostrando que o modo de trabalho de um DVCS, especificamente o Mercurial, não muda tanto assim do usado no Subversion. Espera-se com isso, levar o leitor mais perto da fase 3: interesse.

O experimento simulará dois usuários trabalhando no mesmo projeto, executando algumas operações bem comuns e básicas de controle de versão através do Mercurial, comparando sempre com o mesmo passo feito pelo Subversion.

Para aproveitar melhor o experimento, é necessário:

  1. saber os conceitos básicos do controle de versão distribuído;
  2. instalar o Mercurial ou o TortoiseHg na sua máquina;
  3. já ter usado o Subversion e ter ele ou o TortoiseSvn instalado na máquina;

Observação: O experimento será apresentado com operações pela linha de comando por questão de espaço e comodidade. O experimento pode ser feito também através das interfaces gráficas TortoiseHg e TortoiseSVN, que possuem os mesmos comandos usados no roteiro.

1. Preparando os Repositórios

Quando se sabe que no DVCS cada desenvolvedor tem um repositório e que um repositório pode se conectar com qualquer outro, logo se imagina que o modelo distribuído é uma anarquia. Na verdade, qualquer desenvolvimento sem regras vira uma bagunça. No modelo distribuído, os repositórios podem ser arranjados em várias topologias e a topologia cliente-servidor é uma delas.

Vamos criar 3 repositórios: um oficial, um para um user 1, e outro para o user 2, sendo esses dois últimos para simular os dois desenvolvedores. A convenção estabelece que não haverá comunicação direta entre o repositório dos desenvolvedores 1 e 2. Apenas através do repositório oficial, exatamente como acontece no modelo centralizado.

O acesso ao repositório oficial, tanto do Mercurial, quanto do Subversion, será feito por acesso local para manter o roteiro simples. No exemplo, será usado o diretório /tmp (que é o diretório temporário do linux) para manter todos os repositórios. Escolha um diretório que melhor lhe convier.

Mercurial Subversion
hg init /tmp/oficial svnadmin create /tmp/oficial
hg clone /tmp/oficial /tmp/user1
hg clone /tmp/oficial /tmp/user2
svn checkout file:///tmp/oficial /tmp/user1
svn checkout file:///tmp/oficial /tmp/user2

2. Publicação Inicial

O próximo passo é fazer uma primeira publicação no repositório. Use um arquivo chamado numeros.txt que deverá ser criado no diretório do repositório/cópia de trabalho com o seguinte conteúdo:

um
dois
três
Mercurial Subversion
user1 hg add numeros.txt svn add numeros.txt
hg status svn status
hg commit -m “primeiro commit” -u user1 svn commit -m “primeiro commit” –username user1
hg push

O Mercurial teve um passo adicional para enviar ao repositório oficial o que foi feito no repositório local.

3. Vendo o histórico do projeto?

Mercurial Subversion
user1 # é necessário atualizar a cópia de trabalho antes para ficar na última revisão
svn update
hg log

changeset: 0:aa3f592139e5
tag: tip
user: user1
date: Sun Apr 18 15:31:40 2010 -0300
summary: primeiro commit

svn log

—————————————————————
r1 | user1 | 2010-04-18 15:30:13 -0300 (Dom, 18 Abr 2010) | 1 line
primeiro commit
—————————————————————

Note que o Mercurial também fornece uma numeração sequencial além da identificação da revisão por hash. Esta numeração é válida apenas para o repositório local e foi criada por comodidade, para facilitar a referência a uma revisão em comandos locais, ao invés de se usar o identificador hash.

4. Atualização do Repositório do Usuário 2

O usuário 2 está com seu repositório desatualizado em relação ao repositório oficial. A sincronização se dá pelo comando hg pull -u que já atualiza a área de trabalho acoplada com a última revisão.

Mercurial Subversion
user2 hg pull -u svn update

5. Edição Concorrente

Usuários 1 e 2 executarão mudanças concorrentes no mesmo arquivo. user 1 acrescentará a palavra “zero” na primeira linha enquanto usuário 2 acrescentará “quatro” na última linha. Como as mudanças acontecerão em partes diferentes do mesmo arquivo, a mesclagem ocorrerá sem conflitos.

Mercurial Subversion
user1 # edita números.txt # edita números.txt
hg diff svn diff
hg commit -m “zero” -u user1 svn commit -m “zero” –username user1
hg push
user2 # edita números.txt # edita números.txt
hg diff svn diff
hg commit -m “quatro” -u user2 svn commit -m “quatro” –username user2
# falha 1. Veja obs.
hg push
# falha 2. Veja obs.
hg pull
hg merge
svn update
hg commit -m “merge” -u user1 svn commit -m “quatro” –username user2
hg push

Descrição das falhas nas operações:

  1. O arquivo numeros.txt está desatualizado em relação à última revisão do repositório. É necessário atualizar/mesclar para que seja aceito.
  2. Por padrão, a operação de push não permite que um ramo fique com mais de uma ponta, isto é, tenha bifurcações após a combinação dos grafos de revisões. Qualquer linha individual de desenvolvimento deve ser antes unificada localmente com a linha presente no repositório-oficial antes de ser enviada.

6. Visualização do Grafo de Revisões

O histórico de revisões do DVCS é um grafo acíclico direcionado (Directed Acyclic Graph – DAG). Na interface gráfica, é possível ver os caminhos sendo bifurcados e reunificados. Pela linha de comando, é necessário antes habilitar o plugin do Mercurial que conseguir ver o grafo textualmente.

Edite o arquivo de configuração do repositório do usuário 2, cujo caminho é /tmp/user2/.hg/hgrc e adicione as seguintes linhas ao final

[extensions]
hgext.graphlog =
Mercurial Subversion
user2 hg glog svn log
@ changeset: 3:3eddeb3252ea
|\ tag: tip
| | parent: 1:f01fe74e7279
| | parent: 2:c3664eb01670
| | user: user2
| | date: Sun Apr 18 22:06:03 2010 -0300
| | summary: merge
| |
| o changeset: 2:c3664eb01670
| | parent: 0:b353a0bdea31
| | user: user2
| | date: Sun Apr 18 22:05:21 2010 -0300
| | summary: quatro
| |
o | changeset: 1:f01fe74e7279
|/ user: user1
| date: Sun Apr 18 22:05:43 2010 -0300
| summary: zero
|
o changeset: 0:b353a0bdea31
user: user1
date: Sun Apr 18 22:04:40 2010 -0300
summary: primeiro commit

O grafo apresentado mostra que as revisões produzidas pelos usuários 1 e 2 formaram linhas independentes de desenvolvimento que depois foram reunificadas.

Conclusões

Usando o Mercurial na topologia cliente-servidor, com um repositório oficial equivalente ao repositório central do Subversion, nota-se que não há nenhuma grande mudança na forma do trabalho, nem nos comandos, que são idênticos para a maioria das operações. A impressão que se tem é de que o Mercurial é um Subversion com pushpull.

À primeira vista, parece que o Mercurial precisa de mais comandos para fazer a mesma coisa que se faz no Subversion. A razão disso, e que só é mostrado quando se vê o grafo de revisões, é que cada desenvolvedor trabalha em uma linha independente, equivalente a um ramo privativo, no qual pode publicar suas revisões sem a obrigatoriedade de mesclar com outra revisão a cada etapa, que é o que acontece no Subversion. O resultado é um fluxo de trabalho ainda melhor que no modelo centralizado.

No Mercurial, e em DVCS em geral, todo desenvolvedor trabalha naturalmente em um ramo privativo. O mesmo resultado poderia ser obtido no Subversion definindo-se ramos privativos para cada desenvolvedor a cada tarefa, bug etc. a ser implementado. Quem já usou ou tentou usar uma solução assim no Subversion, sabe quanto é trabalhoso e complicado fazer isso.


  1. Marcus says:

    Olá, Felipe!

    Estou pesquisando sobre ferramentas de controle de versão, fiquei bastante inclinado a utilizar o Mercurial. Para facilitar a implantação, gostaria de alterar a tradução do TortoiseHg 1.5 para o português… pode me dar uma ajuda?

  2. André Felipe Dias says:

    Oi, Marcus

    O TortoiseHg já tem tradução para o Português-Brasileiro. O processo de habilitar essa tradução no menu de contexto é que não é tão acessível. Mas achei as instruções no próprio manual do TortoiseHg, na seção FAQ:

    *How can I get translations for the Explorer context menu?*

    The available translations were stored by the installer under
    :file:`C:\\Program Files\\TortoiseHg\\i18n\\cmenu`. Select the
    locale you would like to use, double-click on it, and confirm all
    requests.

    Basicamente é ir no diretório de instalação do Windows, C:\Program Files\TortoiseHg\i18n\cmenu, escolher o arquivo de registro da linguagem que se quer, no nosso caso é o thg-cmenu-pt_BR.reg e clicar duas vezes pra instalar.

    Se você quiser participar da tradução, as instruções de como contribuir neste tópico estão em http://bitbucket.org/tortoisehg/stable/wiki/developers/Translation

  3. Marcus says:

    Valeu a dica… mas este eu já habilitei. Refiro-me às informações do sistema.

  4. André Felipe Dias says:

    Oi, Marcus

    O resto do TortoiseHg também está traduzido, mas pra habilitar, é necessário definir uma variável de ambiente LANGUAGE=pt_BR e depois reiniciar o computador. No windows XP a definição da variável de ambiente é feita em Control Panel > System > Advanced > Environment Variables.

    Esta questão da escolha da linguagem não está mesmo bem definida no TortoiseHg, mas pelo menos já há uma discussão a respeito em http://bitbucket.org/tortoisehg/stable/issue/320/select-tortoisehg-language-through-the-options. No último comentário, a pessoa já aponta que existem chamadas que poderiam ser feitas ao sistema operacional para saber qual a linguagem escolhida, o que evitaria ter de configurar a variável de ambiente manualmente. Espero que a sugestão seja aceita logo.

  5. Olá André Felipe,

    Muito bom os artigos que você tem publicado, isso ajuda muito a entender a diferença entre controle de versões distribuído e centralizado.

    Eu particularmente estou usando o Subversion a mais de dois anos, vejo a dificuldade que muitos desenvolvedores têm em entender e aceitar, mesmo sendo um modelo centralizado, partir para um modelo descentralizado como é a proposta dos sistemas distribuídos deve ser igualmente traumático.

    Outro ponto é que muitos desenvolvedores não estão preocupados em manter um controle de versão, isso é muito frustrante, nós só estamos conseguindo porque desenhamos um processo, no modelo BPM, que foi aprovado pelo chefe do CPD e formalmente implementado.

  6. André Felipe Dias says:

    Oi, Mandrado

    Fico contente em saber que os artigos estão sendo úteis.

    Acho que o problema de aceitação do controle de versão acontece por falta de conhecimento do processo e da ferramenta. Afinal, é muito frustrante ter de trabalhar com algo que não se domina e que parece ser apenas uma etapa burocrática no desenvolvimento.

    O investimento em treinamento para os desenvolvedores ajuda muito a melhorar essa situação. Mesmo que os desenvolvedores fiquem “parados” por dois ou três dias, ou algumas horas por dia no curso, há um ótimo retorno em produtividade e melhoria do processo depois.

  7. Caro André,

    A questão não é o treinamento pois isso eles tiveram, tanto em sala de aula como “por demanda”, a questão talvez seja a pressão para entregar e instalar em homologação e produção grande quantidade de software e a resistência natural a mudanças, outro fator que também julgo ser um fator é que com o controle de versão os lideres de projeto, alta direção e demais stakeholders podem ter uma visão clara de como anda o desenvolvimento, e isso para o desenvolvedor parece ser uma barreira.

    Aqui temos cerca de 50 colaboradores para o desenvolvimento de diversos software em diversas liguagens, eles não falam, mas agem de forma que me faz entender desta forma.

Leave a Reply