Pular para o conteúdo principal

Comparação entre Subversion, Mercurial e Git - Parte 2

Na primeira parte da comparação, foram apresentadas as análises dos critérios de desempenho e funcionalidade, que mostraram que o Subverion, Mercurial e Git são equivalentes em termos de desempenho (svn com acesso a um repositório local), e que o Mercurial e o Git são equivalentes em termos de funcionalidades.

Nesta segunda parte, o próximo critério analisado será o de complexidade.

Complexidade

A complexidade da ferramenta tem impacto direto na produtividade dos desenvolvedores e é o fator decisivo para o aprendizado e operação correto da ferramenta. Os critérios usados para medi-la foram o número de comandos e o número de linhas dos textos de ajuda. Embora não sejam perfeitos, são adequados para apontar indícios a respeito da complexidade da ferramenta, além de serem imparciais e de fácil medição. Outras dimensões de complexidade das ferramentas serão abordadas em análises posteriores.

O detalhamento dos critérios e das premissas de comparação são apresentados a seguir:

  1. Número de comandos. Todas as ferramentas possuem dezenas comandos e conhecê-los é um desafio para qualquer usuário.

    Premissa: Quanto menor o número de comandos, mais fácil de conhecê-los.

    Contra-argumento: Poderia haver um comando só com dezenas de opções e parâmetros, e isso não o tornaria mais simples. No entanto, o texto de ajuda deste comando ficaria mais extenso. Portanto, só o número de comandos não é suficiente, mas se combinado com a análise do número de linhas de ajuda dos comandos, volta a ficar relevante.

  2. Números de linhas dos textos de ajuda. Todas as ferramentas têm textos de ajuda para seus comandos com objetivo de apresentar o funcionamento do comando e as opções disponíveis.

    Premissas:

    1. O formato e a qualidade dos textos de ajuda das diferentes ferramentas sendo analisadas são equivalentes.
    2. Os textos de ajuda contêm apenas o mínimo de contéudo necessário para descrever adequadamente os comandos.
    3. Comandos mais complexos precisam de textos mais longos para serem descritos. Portanto, quanto menor o número de linhas do texto de ajuda necessário para explicar um comando, mais simples ele é.

Número de Comandos

O Subversion possui ao todo 68 comandos diferentes, agrupados em categorias: svn para tarefas de controle de versão, svnadmin para manipulação e manutenção de repositórios, svnlook para exames do repositório em scripts de hook etc.:

Subversion: 68 comandos diferentes (Alguns se repetem. Por exemplo, help)

svn: 36 comandos
add, blame, cat, changelist, checkout, cleanup, commit, copy, delete, diff, export, help, import, info, list, lock, log, merge, mergeinfo, mkdir, move, patch, propdel, propedit, propget, proplist, propset, relocate, resolve, resolved, revert, status, switch, unlock, update, upgrade
svnadmin: 20 comandos
crashtest, create, deltify, dump, help, hotcopy, list-dblogs, list-unused-dblogs, load, lslocks, lstxns, pack, recover, rmlocks, rmtxns, setlog, setrevprop, setuuid, upgrade, verify
svnlook: 17 comandos
author, cat, changed, date, diff, dirs-changed, filesize, help, history, info, lock, log, propget, proplist, tree, uuid, youngest
svnrdump: 3 comandos
dump, load, help
svndumpfilter: 3 comandos
exclude, include, help
svnsync: 5 comandos
initialize, synchronize, copy-revprops, info, help

O Mercurial possui 55 comandos no total (com fetch e rebase habilitados), podendo aumentar de acordo com o número de extensões habilitadas. Dezoito desses comandos são considerados básicos, apresentados ao se executar o comando hg sem nenhum subcomando ou parâmetro adicional. Não há uma subdivisão adicional dos comandos em uma classe administrativa ou para scripts como no Subversion, embora haja comandos claramente voltado exatamente estes fins, como é o caso dos comandos verify e identify por exemplo.

Mercurial: 55 comandos

Básicos (18 comandos) - listados pelo comando hg:
add, annotate, clone, commit, diff, export, forget, init, log, merge, phase, pull, push, remove, serve, status, summary, update
Avançados (37 comandos) - comandos adicionais listados pelo comando hg help:
addremove, archive, backout, bisect, bookmarks, branch, branches, bundle, cat, copy, fetch, graft, grep, heads, help, identify, import, incoming, locate, manifest, outgoing, parents, paths, rebase, recover, rename, resolve, revert, rollback, root, showconfig, tag, tags, tip, unbundle, verify, version

O Git possui 144 comandos no total. Vinte um desses são os mais comumente usados segundo a lista fornecida pelo comando git sem paràmetros ou chaves adicionais. A lista completa dos comandos é fornecida pelo comando git help --all:

git: 144 comandos

Comuns (21 comandos) - listados pelo comando git:
add, bisect, branch, checkout, clone, commit, diff, fetch, grep, init, log, merge, mv, pull, push, rebase, reset, rm, show, status, tag
Avançados (123 comandos) - comandos adicionais listados pelo comando git help --all:
add--interactive, am, annotate, apply, archive, bisect--helper, blame, bundle, cat-file, check-attr, check-ref-format, checkout-index, cherry, cherry-pick, clean, commit-tree, config, count-objects, credential-cache, credential-cache--daemon, credential-store, daemon, describe, diff-files, diff-index, diff-tree, difftool, difftool--helper, fast-export, fast-import, fetch-pack, filter-branch, fmt-merge-msg, for-each-ref, format-patch, fsck, fsck-objects, gc, get-tar-commit-id, hash-object, help, http-backend, http-fetch, http-push, imap-send, index-pack, init-db, instaweb, lost-found, ls-files, ls-remote, ls-tree, mailinfo, mailsplit, merge-base, merge-file, merge-index, merge-octopus, merge-one-file, merge-ours, merge-recursive, merge-resolve, merge-subtree, merge-tree, mergetool, mktag, mktree, name-rev, notes, pack-objects, pack-redundant, pack-refs, patch-id, peek-remote, prune, prune-packed, quiltimport, read-tree, receive-pack, reflog, relink, remote, remote-ext, remote-fd, remote-ftp, remote-ftps, remote-http, remote-https, remote-testgit, repack, replace, repo-config, request-pull, rerere, rev-list, rev-parse, revert, send-pack, sh-i18n--envsubst, shell, shortlog, show-branch, show-index, show-ref, stage, stash, stripspace, submodule, symbolic-ref, tar-tree, unpack-file, unpack-objects, update-index, update-ref, update-server-info, upload-archive, upload-pack, var, verify-pack, verify-tag, web--browse, whatchanged, write-tree

O Git possui uma quantidade maior de comandos do que o Subversion e o Mercurial juntos! Isto não se deve a um maior número de funcionalidades. É apenas uma indicação de falha na integridade conceitual do projeto, que pode ser explicada em parte por razões históricas do desenvolvimento 1:

Git foi originalmente projetado como um mecanismo de controle de versão de baixo nível (de abstração) a partir do qual outros poderiam escrever aplicativos... No entanto, o projeto do núcleo do Git se tornou um sistema de controle de versão completo que é usado diretamente.

Melhor seria se os comandos de baixo nível tivessem sido movidos para alguma biblioteca, onde ficariam visíveis apenas aos desenvolvedores do Git, longe dos usuários finais da ferramenta.

Não só o número de comandos influencia no aprendizado e na operação, mas também a forma como estão organizados. O Subversion não possui o menor número de comandos, mas os organiza em categorias que facilitam muito a vida do usuário. Um desenvolvedor, por exemplo, precisaria apenas dos subcomandos do svn para operações de controle de versão, um administrador dos subcomandos do svnadmin e assim por diante.

No DVCS, o repositório é local e, por isso, todos os tipos de operação são responsabilidade do próprio desenvolvedor. Como nem sempre o nome do comando deixa clara a sua finalidade e a divisão dos comandos apenas em básicos e avançados também não acrescenta muita informação, o Mercurial e o Git deveriam usar mais categorias para classificar os comandos.

Melhor: Mercurial (menor número de comandos) e Subversion (melhor organização dos comandos)

Números de Linhas por Comando

A contagem das linhas do texto de ajuda será feita através dos seguintes comandos:

$ svn help <comando> | wc -l
$ hg help <comando> | wc -l
$ git help <comando> | wc -l
Observações:
  1. Uma vez que o Git não possui tradução para o pt_BR, a comparação será feita com todos os textos em inglês. Para garantir que isto aconteça, é necessário ajustar a variável de ambiente LANGUAGE:
    $ export LANGUAGE=en_US.UTF-8
    
  2. Como alguns comandos do Git executam várias funcionalidades diferentes, alguns textos de ajuda serão agregados para manter o equilíbrio da comparação. Por exemplo, o texto de ajuda do comando git checkout será comparado com o agrupamento dos textos de ajuda dos comandos update, branch e revert do Mercurial:
    $ (hg help update && hg help branch && hg help revert) | wc -l
    
  3. Alguns comandos do Subversion, Mercurial e Git possuem o mesmo nome mas executam operações total ou parcialmente diferentes como, por exemplo, o comando add e o comando revert. Apesar disto, serão tratados como equivalentes.
  4. Comandos tais como push e pull não existem no Subversion. Nestes casos, o número contabilizado de linhas é zero.
  5. O número de linhas do texto de ajuda do Git varia conforme a largura do terminal. A análise apresentada usou uma largura de 80 colunas para as medições.

A tabela a seguir mostra os dados coletados a partir da execução do script comparativo_help_svn_hg_git.py <link://listing/comparativo_help_svn_hg_git.py>:

Comando Subversion Mercurial Git
add 30 23 333
mv 48 30 47
rm 41 24 135
status 118 61 197
diff 81 51 903
hg log glog | git log 98 73 1639
hg cat | git show 30 29 416
blame 53 36 386
rebase 0 71 752
bisect 0 34 332
clone 0 47 320
commit 39 55 433
hg pull | git fetch 0 39 399
hg fetch | git pull 0 36 655
hg update revert branch | git checkout 115 121 390
push 0 44 550
merge 382 35 557
hg graft | git cherry-pick 0 34 173
hg backout | git revert 0 33 120
TOTAL 1035 876 8737

A representação gráfica dos resultados é mostrada a seguir:

comparativo texto ajuda

O Git possui textos mais longos em todos os casos, o que indica seus comandos são mais difíceis de serem explicados.

O Subversion teve um total de linhas de texto maior que o Mercurial, mesmo com menos comandos sendo analisados. O responsável foi o comando svn merge, que é reconhecidamente complexo no Subversion e cujo texto de ajuda corresponde sozinho a mais de um terço do total. Isto reforça a premissa de que quanto mais complexo o comando, maior o número de linhas de texto de ajuda correspondente.

O Mecurial se saiu melhor tanto no quadro geral quanto em todos os comandos equivalentes ao Subversion. Pela lógica utilizada, os comandos do Mercurial são mais simples dos que os do Git e até mesmo do que os comandos do Subversion.

Melhor: Mercurial

Conclusão da Parte 2

Os números coletados indicam que o Git é mais complexo que o Subversion e o Mercurial, o que era esperado conforme já relatado em várias análises disponíveis na internet 2 3 4 5. O Subversion ficou em segundo lugar e o Mercurial em primeiro, o que foi surpreendente de certa forma porque esperava-se que o Subversion fosse o mais simples.

Em vista dos resultados obtidos até o momento, o Mercurial é a melhor escolha de migração de um projeto comercial usando Subversion. A próxima parte da comparação entre o Subversion, Mercurial e Git analisará a ramificação e a mesclagem.

1 http://en.wikipedia.org/wiki/Git_(software)
2 http://programmers.stackexchange.com/questions/87217/why-is-mercurial-considered-to-be-easier-than-git
3 http://programmers.stackexchange.com/questions/940/what-are-your-favorite-version-control-systems#comment9240_950
4 http://utcc.utoronto.ca/~cks/space/blog/sysadmin/MercurialVsGit
5 http://blog.nelhage.com/2010/01/on-git-and-usability/

Comentários

Comments powered by Disqus