Pular para o conteúdo principal

Qual a melhor ferramenta de controle de versão: Subversion, Git ou Mercurial?

As ferramentas mais interessantes atualmente de controle de versão são o Subversion, Git e Mercurial. Se você ainda não escolheu uma, ficará feliz em saber que existe sim uma solução simples e eficaz dependendo do perfil da equipe e das necessidades do projeto. A surpresa está em saber que a melhor opção certamente será o Subversion ou o Mercurial, mas dificilmente o Git. Vamos analisar os porquês neste artigo.

Introdução

Todos nós que desenvolvemos software sabemos que o controle de versão é importante . Se sua equipe ainda não usa nenhum, o dilema está em qual escolher: Subversion, Git ou Mercurial?

Há vários critérios para escolher uma ferramenta de controle de versão. Os mais comuns são:

  • Popularidade
  • Eficácia
  • Desempenho
  • Adequação
  • Simplicidade

Vamos analisar todos eles.

Popularidade

Os critérios para a escolha de uma ferramenta para um projeto pessoal são diferentes dos critérios para escolha de uma equipe ou organização. Para um projeto pessoal, pode ser muito interessante aprender e usar a ferramenta/linguagem/biblioteca/framework/arquitetura da moda. Para uma equipe ou organização, a escolha baseada apenas na popularidade pode levar a uma solução inadequada.

No caso específico do Git, é bom ressaltar que sua popularidade é graças ao GitHub.

O GitHub é uma plataforma de hospedagem de código para controle de versão e colaboração. Conseguiu uma enorme vantagem competitiva por ter sido o primeiro a identificar e atender as necessidades particulares do nicho de mercado de desenvolvedores de software, particularmente de projetos open source. Ao invés de páginas estáticas e interfaces feias que existiam na época (por volta de 2008), o GitHub inovou ao criar uma aplicação web dinâmica, com uma interface agradável e que conseguiu tornar a contribuição de software através de pull requests um processo fácil e sociável.

Não há nada no GitHub que só possa ser feito pelo Git. É possível, por exemplo, usar normalmente o GitHub com o Mercurial através da extensão hg-git e o mesmo procedimento de pull request é oferecido pelo BitBucket para o Mercurial e para o Git. Dessa forma, se outro controle de versão distribuído tivesse sido escolhido, o sucesso do GitHub teria sido o mesmo 1:

Grande parte da popularidade do Git se deve ao GitHub, mas muito pouco do sucesso do GitHub se deve ao Git.

É importante investigar se os motivos da popularidade de uma opção são relevantes para sua escolha. O fato de o Git ser o mais popular, não quer dizer que o Subversion e o Mercurial também não sejam. O Subversion continua sendo bastante popular no meio corporativo e o Mercurial também é bastante usado, principalmente por empresas grandes como Facebook, Mozilla e Google.

Eficácia

O controle de versão serve para resolver três problemas:

  1. Registrar a evolução do projeto
  2. Possibilitar o trabalho em equipe
  3. Criar e manter variações do projeto

Tanto o Subversion, quanto o Git e o Mercurial atendem a todas as necessidades de controle de versão.

Desempenho

A comparação entre o desempenho do Subversion, Git e Mercurial mostrou que as operações de controle de versão são muito rápidas. Mesmo as operações mais demoradas tiveram um tempo muito baixo para ter qualquer impacto na produtividade.

As diferenças no desempenho entre Subversion, Git e Mercurial não são relevantes do ponto de vista da operação da ferramenta por um desenvolvedor.

Adequação

O controle de versão centralizado (Subversion) é adequado para equipes de desenvolvimento com até algumas dezenas de desenvolvedores, em que todos estão na mesma rede. Esse é o caso mais comum de projetos corporativos.

Para os outros casos em que há centenas de desenvolvedores, equipes distribuídas geograficamente, colaborações externas ou fluxos de trabalhos complexos, então o controle de versão distribuído (Mercurial e Git) é mais indicado.

Controle de versão distribuído são particularmente interessantes para projetos open source pois facilitam muito a participação externa.

Mas você pode se perguntar: "o controle de versão distribuído também não resolve os casos indicados para o centralizado?" A resposta é sim! No entanto, o controle de versão centralizado é mais simples de aprender e usar, e a grande maioria dos projetos não precisa arcar com a complexidade adicional para fazer os mesmos serviços básicos. O que nos leva ao próximo quesito: simplicidade.

Simplicidade

A simplicidade de uma ferramenta tem relação direta com a produtividade. Uma ferramenta simples é mais fácil de aprender, de usar e leva a menos erros de operação.

Subversion

Para usar o Subversion, você precisa entender os conceitos básicos de controle de versão: arquivo, diretório de trabalho, revisão, changeset, ramos e etiquetas (tags). Também é necessário conhecer as particularidades de implementação do Subversion em relação à ramificação através de diretórios, e à convenção da estrutura de diretórios trunk/branches/tags.

O modelo de comandos de transporte é apresentado a seguir:

Há apenas dois lugares onde o fontes podem estar: no diretório de trabalho ou no repositório. Os comandos mais usados são poucos, coerentes e fáceis de lembrar.

O Subversion é simples e direto. Seu tempo de aprendizado é curto, e a chance de desastres causados por imperícia é pequeno.

Mercurial

O Mercurial é um pouco mais complicado que o Subversion porque além dos conceitos de controle de versão centralizado, também é necessário entender conceitos básicos do controle de versão distribuído, tais como sincronização de repositórios e o registro do histórico em um grafo acíclico direcionado.

O Mercurial não possui nenhuma particularidade de implementação que fique exposta na estrutura do projeto ou nos comandos. Mesmo operações avançadas como rebase, por exemplo, exigem apenas conceitos básicos de controle de versão distribuído.

O modelo de comandos de transporte é apenas um pouco mais complexo que o do Subversion:

Os comandos do Mercurial são iguais ou muito parecidos com o do Subversion. O novo nível do repositório remoto traz também novas operações adicionais como pull, push e rebase. Mesmo assim, os comandos mais usados ainda são poucos, coerentes e fáceis de lembrar.

A simplicidade de operação do Mercurial não impede que seja capaz de fazer operações complexas e ter funcionalidades adicionais 2:

Mercurial é projetado para oferecer um conjunto de comandos pequeno, seguro e fácil de usar que é suficientemente poderoso para a maioria dos usuários. Operações avançadas estão disponíveis através de extensões, que permitem a integração desses recursos diretamente no núcleo Mercurial.

Assim, o conjunto de operações e funcionalidades do Mercurial pode ser incrementado à medida que aumenta o nível de conhecimento e necessidade do usuário.

O Mercurial ainda possui medidas internas de segurança que evitam estragos por imperícia mesmo em operações avançadas de manipulação de histórico. O conceito de Phases (fases), por exemplo, é transparente ao usuário e evita que histórico já compartilhado seja reescrito por acidente.

O Mercurial é um pouco mais complexo que o Subversion, mas também é bastante simples de aprender e usar. Possui medidas de segurança que evitam desastres por imperícia.

Git

Git tem várias qualidades: é popular principalmente entre projetos open source, é rápido (até um certo tamanho de projeto) e tem um bom design interno. Porém, simplicidade não está entre essas qualidades. Pelo contrário, o Git é bastante complexo e sua interface é inconsistente e pouco intuitiva.

A complexidade do Git aparece de várias formas, uma delas é no seu modelo de comandos transporte 3:

Há vários lugares onde os arquivos podem estar: stash, diretório de trabalho (working tree na terminologia do Git), index (também chamado de stage area ou cache), repositório local e remoto. A área stash é opcional, mas o index não pode ser evitado completamente. Trata-se de uma área intermediária de preparação para a geração da revisão.

O index é um elemento da infraestrutura. Toda ferramenta de controle de versão tem um elemento equivalente, mas enquanto o Subversion, Mercurial, Bazaar, Darcs etc. coordenam isso automaticamente 4, no Git, o index precisa ser gerenciado diretamente pelo usuário. Principalmente para usuários iniciantes e intermediários, os poucos casos em que o gerenciamento direto do index é útil não compensam todo o esforço e complexidade adicionais, nem os riscos de se consolidar uma configuração diferente da que foi analisada e testada no diretório de trabalho.

A exposição do index é um exemplo na falha da abstração do Git, mas não é o único. O microgerenciamento de outros elementos da infraestrutura para execução de operações de controle de versão é bastante comum no Git. Ao invés de executar uma operação de alto nível de abstração, o usuário precisa manipular conceitos e estruturas de implementação como bare repos, blob, fast-forward, detached HEAD, refs, reflog, refspecs, remote, hard reset, tree, working tree e upstream.

Se o Git fosse um carro, para aprender a dirigi-lo você precisaria antes entender como funciona o motor de combustão interna. Para acelerar, não bastaria apenas pisar no pedal do acelerador; no carro Git seria necessário entender o funcionamento da sonda lambda e acionar diretamente a válvula-borboleta para liberar mais ar para a mistura ar-combustível e, assim, dar mais potência ao motor.

Grande parte dessa complexidade se deve às origens do Git 5:

O Git é fundamentalmente um sistema de arquivos de conteúdo endereçável com uma interface de usuário para controle de versão de software escrita em cima.

Inicialmente, o Git era um conjunto de ferramentas para um controle de versão ao invés de um controle de versão completo, tem um monte de verbos que fazem trabalho de baixo nível que foram projetados para serem encadeados no estilo UNIX ou chamados de scripts. Esses comandos são geralmente referidos como comandos de "encanamento" (plumbing), e os comandos mais fáceis de usar são chamados comandos de "porcelana" (porcelain).

A versão 2.13 do Git (de maio de 2017) possui 148 comandos. Desses, 21 são considerados "porcelana" (listados pelo comando git help): add, bisect, branch, checkout, clone, commit, diff, fetch, grep, init, log, merge, mv, pull, push, rebase, reset, rm, show, status e tag.

Mesmos esses comandos sofrem de baixa usabilidade. Vários deles não funcionam como se espera se comparados com os conceitos clássicos de controle de versão. O comando git clone, por exemplo, não cria realmente um clone de um repositório. O comando para isso seria git clone --mirror. Ainda assim, o repositório criado não é usável diretamente porque não possui um diretório de trabalho associado.

Outro exemplo é comando git pull, que deveria somente trazer as revisões do repositório remoto para o repositório local, mas faz também a mesclagem automática. A operação do Git que faz o pull clássico é git fetch.

A interface do Git também apresenta muitos problemas de inconsistência. Exemplos 6:

Operação Comando
Listar todas as tags git tag
Listar todos os remotes git remote -v
Listar todos os ramos git branch -a
Ver o ramo atual git rev-parse --abbrev-ref HEAD
Deletar um remote git remote rm
Deletar um ramo git branch -d

A tirinha do xkcd ilustra bem a situação da usabilidade do Git:

- Este é o Git. Ele registra o trabalho colaborativo em projetos
através de um belo modelo distribuído de árvore de teoria de grafos.
- Legal. E como se usa?
- Não faço ideia. Apenas decore esses comandos e digite-os para sincronizar.
Se aparecer erros, salve seu trabalho em outro lugar,
apague o projeto e faça o download de uma nova cópia.

Toda essa complexidade e excessiva exposição de detalhes torna o Git difícil de aprender e usar 7:

Uma das diferenças mais proeminentes entre o Git vs Mercurial é o nível de conhecimento necessário para usar os sistemas. Em resumo, o Git é mais complexo e exige que você e sua equipe o conheçam dentro e fora antes que você possa esperar usá-lo de forma eficaz e segura. Com o Git, um desenvolvedor descuidado pode causar grandes danos para toda a equipe. Além disso, sua documentação é considerada mais difícil de entender.

Outra consequência da complexidade do Git é a facilidade com que erros de operação acontecem. Um comando errado executado por um desenvolvedor descuidado ou despreparado pode facilmente levar a situações muito difíceis de sair. Casos bastante comuns incluem o git rebase de um ramo compartilhado e o mal uso de operações como git push --force e git push --mirror. Embora a perda de código seja rara, é necessário bastante conhecimento técnico para desfazer a bagunça, principalmente depois se o estrago tiver sido compartilhado com outros desenvolvedores.

É importante ressaltar que o excesso de complexidade e exposição de detalhes não trazem nenhuma melhoria na produtividade nem tampouco torna o controle de versão mais efetivo. As mesmas operações de controle de versão são muito mais facilmente executadas pelo Mercurial ou pelo Subversion, sem a necessidade de recorrer frequentemente ao Google ou StackOverflow para descobrir qual o comando e a sintaxe corretas para uma operação como ocorre no Git.

O Git é bastante difícil de aprender e usar. Desastres por imperícia são comuns, principalmente com desenvolvedores despreparados.

Conclusão

O critério mais importante na escolha da ferramenta de controle de versão é a simplicidade uma vez que outros critérios são irrelevantes ou equivalentes. Uma ferramenta simples é que tornará o controle de versão rápido e transparente.

Se sua equipe ainda não adotou uma ferramenta de controle de versão, comece com a solução mais simples que resolverá o problema. Depois, se realmente for necessário, é possível migrar de uma ferramenta para outra reaproveitando o histórico.

O Subversion deve ser sua primeira alternativa. Se você precisar ou preferir começar com o controle de versão distribuído, considere o Mercurial porque é apenas um pouco mais complexo que o Subversion. O Git, apesar da popularidade, não é recomendado devido a sua baixa usabilidade e alta complexidade.

Seja qual for a sua escolha, a Pronus possui o melhor treinamento em Subversion, Git ou Mercurial. São mais de 20 horas de treinamento e mais de 100 exercícios práticos que cobrem operações cotidianas e avançadas de controle de versão no desenvolvimento de software. Inscreva sua equipe já!

Referências

1 Code First and the Rise of the DVCS and GitHub
2 Using Mercurial Extensions
3 Git CheatSheet
4 On Gitology
5 Git Internals - Plumbing and Porcelain
6 Git Koans
7 Why is Git better than Mercurial?

Comentários

Comments powered by Disqus