Qual é a diferença entre Mercurial e Git?

Eu tenho usado o git há algum tempo no Windows (com o msysGit) e gosto da idéia de controle de fonte distribuída. Recentemente eu estive olhando para o Mercurial (hg) e parece interessante. No entanto, eu não posso envolver minha cabeça em torno das diferenças entre hg e git.

Alguém fez uma comparação lado-a-lado entre git e hg? Estou interessado em saber o que difere hg e git sem ter que pular em uma discussão fanboy.

Estes artigos podem ajudar:

  • Git vs. Mercurial: Por favor, relaxe (Git é MacGyver e Mercurial é James Bond)
  • As diferenças entre o Mercurial e o Git

Edit : Comparando Git e Mercurial para celebridades parece ser uma tendência. Aqui está mais um:

  • Git é Wesley Snipes, Mercurial é Denzel Washington

Eu trabalho no Mercurial, mas fundamentalmente acredito que ambos os sistemas são equivalentes. Ambos trabalham com as mesmas abstrações: uma série de instantâneos (changesets) que compõem a história. Cada changeset sabe de onde veio (o changeset pai) e pode ter muitos changesets filhos. A recente extensão hg-git fornece uma ponte bidirecional entre o Mercurial e o Git e mostra esse ponto.

Git tem um forte foco em transformar este gráfico histórico (com todas as consequências que isso acarreta), enquanto o Mercurial não encoraja a reescrita da história, mas é fácil fazê-lo e as conseqüências disso são exatamente o que você deve esperar que seja (isto é , se eu modificar um changeset que você já tem, o seu cliente o verá como novo se você retirar de mim). Então, o Mercurial tem uma tendência para comandos não destrutivos.

Quanto a ramos leves, então o Mercurial tem suportado repositorys com múltiplos ramos desde …, sempre penso. Repositórios Git com múltiplas ramificações são exatamente isso: várias vertentes divergentes de desenvolvimento em um único repository. O Git então adiciona nomes a essas cadeias e permite que você consulte esses nomes remotamente. A extensão Bookmarks para o Mercurial adiciona nomes locais e, com o Mercurial 1.6, você pode mover esses marcadores ao apertar / puxar.

Eu uso o Linux, mas aparentemente o TortoiseHg é mais rápido e melhor que o equivalente do Git no Windows (devido ao melhor uso do pobre sistema de arquivos do Windows). Ambos http://github.com e http://bitbucket.org fornecem hospedagem online, o serviço no Bitbucket é ótimo e responsivo (eu não tentei github).

Eu escolhi o Mercurial, já que parece limpo e elegante – eu fiquei com os scripts shell / Perl / Ruby que eu tenho com o Git. Tente dar uma olhada no arquivo git-instaweb.sh se você quer saber o que quero dizer: é um script de shell que gera um script Ruby , que acho que roda um servidor web. O shell script gera outro script de shell para iniciar o primeiro script Ruby. Há também um pouco de Perl , para uma boa medida.

Eu gosto do post do blog que compara Mercurial e Git com James Bond e MacGyver – Mercurial é mais discreto que o Git. Parece-me que as pessoas que usam o Mercurial não são tão facilmente impressionadas. Isso se reflete em como cada sistema faz o que Linus descreveu como “a fusão mais legal EVER!” . No Git você pode se fundir com um repository não relacionado ao fazer:

 git fetch  GIT_INDEX_FILE=.git/tmp-index git-read-tree FETCH_HEAD GIT_INDEX_FILE=.git/tmp-index git-checkout-cache -a -u git-update-cache --add -- (GIT_INDEX_FILE=.git/tmp-index git-ls-files) cp .git/FETCH_HEAD .git/MERGE_HEAD git commit 

Esses comandos parecem bem misteriosos para o meu olho. No Mercurial nós fazemos:

 hg pull --force  hg merge hg commit 

Observe como os comandos do Mercurial são simples e nada especiais – a única coisa incomum é o sinalizador --force para hg pull , que é necessário, já que o Mercurial irá abortar de outra forma quando você extrair de um repository não relacionado. São diferenças como essa que fazem o Mercurial parecer mais elegante para mim.

O Git é uma plataforma, o Mercurial é “apenas” uma aplicação. O Git é uma plataforma de sistema de arquivos com versão que é fornecida com um aplicativo DVCS na checkbox, mas, como é normal em aplicativos de plataforma, é mais complexa e tem bordas mais ásperas do que os aplicativos focados. Mas isso também significa que o VCS do git é imensamente flexível, e há uma enorme profundidade de coisas que você pode fazer com o git.

Essa é a essência da diferença.

O Git é melhor compreendido desde o início – desde o formato do repository. O Git Talk de Scott Chacon é um excelente primer para isso. Se você tentar usar o git sem saber o que está acontecendo sob o capô, você acabará confuso em algum ponto (a menos que você se atenha apenas à funcionalidade básica). Isto pode soar estúpido quando tudo que você quer é um DVCS para sua rotina de programação diária, mas o gênio do git é que o formato do repository é realmente muito simples e você pode entender toda a operação do git com bastante facilidade.

Para algumas comparações mais voltadas para o tecnicismo, os melhores artigos que vi pessoalmente são os de Dustin Sallings:

  • As diferenças entre o Mercurial e o Git
  • Tópico do Reddit, onde Dustin, experiente em git, responde às suas próprias perguntas de neófito

Ele realmente usou os dois DVCSs extensivamente e os entende bem – e acabou preferindo o git.

A grande diferença está no Windows. O Mercurial é suportado nativamente, o Git não é. Você pode obter uma hospedagem muito semelhante ao github.com com o bitbucket.org (na verdade, é ainda melhor quando você obtém um repository privado gratuito). Eu estava usando o msysGit por um tempo, mas mudei para o Mercurial e fiquei muito feliz com isso.

Se você é um desenvolvedor do Windows procurando por um controle de revisão desconectado básico, vá com Hg. Eu achei o Git incompreensível enquanto o Hg era simples e bem integrado com o shell do Windows. Eu baixei o Hg e segui este tutorial (hginit.com) – dez minutos depois eu tinha um repository local e estava de volta ao trabalho no meu projeto.

Eu acho que a melhor descrição sobre “Mercurial vs. Git” é:

“Git é Wesley Snipes. Mercurial é Denzel Washington”

Eles são quase idênticos. A diferença mais importante, do meu ponto de vista (quero dizer, a razão que me levou a escolher um DVCS sobre o outro) é como os dois programas gerenciam filiais.

Para iniciar uma nova ramificação, com o Mercurial, basta clonar o repository em outro diretório e começar a desenvolver. Então você puxa e se funde. Com o git, você precisa fornecer explicitamente um nome para o novo ramo de tópicos que deseja usar e, em seguida, iniciar a codificação usando o mesmo diretório .

Em suma, cada ramo no Mercurial precisa de seu próprio diretório; no git você costuma trabalhar em um único diretório. Mudar de ramificações no Mercurial significa alterar diretórios; no git, isso significa pedir ao git para alterar o conteúdo do diretório com git checkout.

Eu sou honesto: não sei se é possível fazer o mesmo com o Mercurial, mas como costumo trabalhar em projetos web, usar sempre o mesmo diretório com o git parece muito confortável pra mim, já que não tenho que re -configure o Apache e reinicie-o e não danifico meu sistema de arquivos toda vez que eu ramifico.

Edit: Como Deestan observou, Hg nomeou branches , que podem ser armazenados em um único repository e permitem que o desenvolvedor alterne branches dentro da mesma cópia de trabalho. Os ramos git não são exatamente os mesmos que os ramos do Mercurial, de qualquer maneira: eles são permanentes e não jogam fora ramos, como no git. Isso significa que, se você usar um branch nomeado para tarefas experimentais, mesmo que você decida nunca mesclá-lo, ele será armazenado no repository. Essa é a razão pela qual Hg incentiva o uso de clones para tarefas experimentais de curta duração e ramificações nomeadas para tarefas de longa duração, como para as ramificações de release.

A razão pela qual muitos usuários de Hg preferem clones sobre o ramo nomeado é muito mais social ou cultural do que técnico. Por exemplo, com as últimas versões do Hg, é possível fechar uma ramificação nomeada e remover recursivamente os metadados dos conjuntos de alterações.

Por outro lado, o git convida para usar “branches nomeados” que não são permanentes e não são armazenados como metadados em cada changeset.

Do meu ponto de vista pessoal, o modelo do git está profundamente ligado ao conceito de ramificações nomeadas e alterna entre uma ramificação e outra no mesmo diretório; O hg pode fazer o mesmo com ramificações nomeadas, mas ainda assim encoraja o uso de clones, o que eu pessoalmente não gosto muito.

Existe uma enorme diferença entre o git e o mercurial ; a maneira como representam cada commit. git representa commits como snapshots, enquanto mercurial os representa como diffs.

O que isso significa na prática? Bem, muitas operações são mais rápidas no git, como trocar para outro commit, comparar commits, etc. Especialmente se esses commits estiverem distantes.

AFAIK não há vantagem da abordagem mercurial.

Nada. Ambos fazem o mesmo, ambos se desempenham igualmente. A única razão pela qual você deve escolher um sobre o outro é se você ajudar com um projeto que já usa um ..

O outro motivo possível para escolher um é um aplicativo ou serviço que suporta apenas um sistema. Por exemplo, eu praticamente escolhi aprender git por causa do github .

Também a comparação do google (embora seja um pouco antiga, feita em 2008)

http://code.google.com/p/support/wiki/DVCSAnalysis

Se eu os entendi corretamente (e estou longe de ser um especialista em cada um deles), eles fundamentalmente têm uma filosofia diferente. Eu usei pela primeira vez mercurial por 9 meses. Agora eu usei o git para 6.

hg é um software de version control. Seu objective principal é rastrear versões de um software.

git é um sistema de arquivos baseado em tempo. Seu objective é adicionar outra dimensão a um sistema de arquivos. A maioria tem arquivos e pastas, o git adiciona tempo. Que isso funcione muito bem, já que um VCS é um subproduto de seu design.

Em hg, há um histórico de todo o projeto que ele está sempre tentando manter. Por padrão, eu acredito que hg quer todas as mudanças em todos os objects de todos os usuários ao empurrar e puxar.

No git há apenas um conjunto de objects e esses arquivos de rastreamento (branches / heads) que determinam qual conjunto desses objects representa a tree de arquivos em um estado particular. Ao empurrar ou puxar o git, apenas envia os objects necessários para os ramos específicos que você está empurrando ou puxando, o que é um pequeno subconjunto de todos os objects.

No que diz respeito ao git, não há “1 projeto”. Você poderia ter 50 projetos no mesmo repository e o git não se importaria. Cada um pode ser gerenciado separadamente no mesmo repository e ao vivo.

O conceito de sucursais de Hg é derivado do projeto principal ou sucursais de filiais etc. O Git não tem esse conceito. Um branch no git é apenas um estado da tree, tudo é um branch no git. Qual ramificação é oficial, atual ou mais recente não tem significado no git.

Não sei se isso fazia algum sentido. Se eu pudesse desenhar fotos hg pode ser assim onde cada commit é um o

  o---o---o / o---o---o---o---o---o---o---o \ / o---o---o 

Uma tree com uma única raiz e twigs saindo dela. Enquanto git pode fazer isso e muitas vezes as pessoas usam dessa forma que não é aplicada. Uma imagem git, se é que existe tal coisa, poderia facilmente se parecer com isso

 o---o---o---o---o o---o---o---o \ o---o o---o---o---o 

De fato, de certa forma, não faz sentido mostrar ramificações no git.

Uma coisa que é muito confusa para a discussão, git e mercurial, ambos têm algo chamado de “branch”, mas eles não são remotamente as mesmas coisas. Um ramo no mercurial acontece quando há conflitos entre diferentes recompras. Um ramo no git é aparentemente semelhante a um clone em hg. Mas um clone, embora possa dar um comportamento semelhante, definitivamente não é o mesmo. Considere-me tentar estes em git vs hg usando o repository chromium que é bastante grande.

 $ time git checkout -b some-new-branch Switched to new branch 'some-new-branch' real 0m1.759s user 0m1.596s sys 0m0.144s 

E agora em hg usando clone

 $ time hg clone project/ some-clone/ updating to branch default 29387 files updated, 0 files merged, 0 files removed, 0 files unresolved. real 0m58.196s user 0m19.901s sys 0m8.957 

Ambos são quentes. Ou seja, eu os corri duas vezes e esta é a segunda corrida. hg clone é o mesmo que git-new-workdir. Ambos fazem um diretório de trabalho inteiramente novo, quase como se você tivesse typescript cp -r project project-clone . Isso não é o mesmo que fazer uma nova ramificação no git. É muito mais pesado. Se houver um equivalente verdadeiro da ramificação do git em hg, não sei o que é.

Eu entendo em algum nível hg e git pode ser capaz de fazer coisas semelhantes. Se sim, então ainda há uma enorme diferença no stream de trabalho que eles levam. No git, o stream de trabalho típico é criar uma ramificação para cada recurso.

 git checkout master git checkout -b add-2nd-joypad-support git checkout master git checkout -b fix-game-save-bug git checkout master git checkout -b add-a-star-support 

Isso criou apenas 3 ramificações, cada uma baseada em um ramo chamado mestre. (Tenho certeza de que há alguma maneira no git para fazer com que essas linhas sejam 1 em vez de 2)

Agora, para trabalhar em um que acabei de fazer

 git checkout fix-game-save-bug 

e comece a trabalhar. Comprometer-se, etc. Alternar entre filiais, mesmo em um projeto tão grande quanto o cromo, é quase instantâneo. Eu realmente não sei como fazer isso em hg. Não faz parte de nenhum tutorial que li.

Uma outra grande diferença. Palco do Git.

Git tem essa ideia de um palco. Você pode pensar nisso como uma pasta oculta. Quando você se compromete, você apenas compromete o que está no palco, não as mudanças na sua tree de trabalho. Isso pode parecer estranho. Se você quer cometer todas as mudanças em sua tree de trabalho, você git commit -a que adiciona todos os arquivos modificados ao estágio e os submete.

Qual é o ponto do palco então? Você pode facilmente separar seus commits. Imagine que você editou o joypad.cpp e o gamesave.cpp e quer enviá-los separadamente

 git add joypad.cpp // copies to stage git commit -m "added 2nd joypad support" git add gamesave.cpp // copies to stage git commit -m "fixed game save bug" 

O Git ainda tem comandos para decidir quais linhas específicas no mesmo arquivo você deseja copiar para o palco, assim você pode dividir os commits separadamente também. Por que você gostaria de fazer isso? Porque, como os commits separados, outros podem puxar apenas os que eles querem, ou se houvesse um problema, eles poderiam reverter apenas o commit que tinha o problema.

Existe um gráfico de comparação dinâmica no versioncontrolblog, no qual você pode comparar vários sistemas de version control diferentes.

Aqui está uma tabela de comparação entre git, hg e bzr.

Existem diferenças bastante significativas quando se trata de trabalhar com filiais (especialmente as de curto prazo).

É explicado neste artigo (BranchingExplained), que compara o Mercurial com o Git.

Existe algum colaborador baseado em Windows em seu projeto?

Porque se houver, a GUI do Git-for-Windows parece estranha, difícil, hostil.

Mercurial-on-Windows, pelo contrário, é um acéfalo.

Uma coisa a notar entre o mercurial do bitbucket.org e o git of github é que o mercurial pode ter quantos repositorys privados você quiser, mas o github você tem que atualizar para uma conta paga. Então, é por isso que eu uso o bitbucket, que usa o mercurial.

Em algum momento do ano passado eu avaliei tanto git quanto hg para meu próprio uso, e decidi ir com hg. Eu senti que parecia uma solução mais limpa e trabalhei melhor em mais plataformas na época. Foi principalmente um lance-up, no entanto.

Mais recentemente, comecei a usar o git por causa do git-svn e a capacidade de agir como um cliente do Subversion. Isso me conquistou e agora mudei completamente para o git. Eu acho que tem uma curva de aprendizado um pouco maior (especialmente se você precisar bisbilhotar), mas é realmente um ótimo sistema. Eu vou ler esses dois artigos de comparação que John postou agora.

Eu estou atualmente no processo de migration do SVN para um DVCS (enquanto blogando sobre minhas descobertas, meu primeiro esforço real de blogar …), e eu fiz um pouco de pesquisa (= googling). Tanto quanto eu posso ver, você pode fazer a maioria das coisas com ambos os pacotes. Parece que o git tem alguns resources avançados implementados mais ou melhor, eu sinto que a integração com o windows é um pouco melhor para o mercurial, com o TortoiseHg. Eu sei que há o Git Cheetah também (eu tentei os dois), mas a solução mercurial parece mais robusta.

Vendo como eles são ambos open-source (certo?) Eu não acho que ambos serão carentes de resources importantes. Se algo é importante, as pessoas vão pedir, as pessoas irão codificá-lo.

Eu acho que para práticas comuns, o Git e o Mercurial são mais que suficientes. Ambos têm grandes projetos que os usam (Git -> kernel linux, Mercurial -> projetos de fundação da Mozilla, ambos entre outros, é claro), então eu não acho que eles realmente estão faltando alguma coisa.

Dito isso, estou interessado no que as outras pessoas dizem sobre isso, já que seria uma ótima fonte para meus esforços de blogar 😉

Há uma grande e exaustiva tabela de comparação e charts no git, Mercurial e Bazaar no guia da InfoQ sobre o DVCS .

Eu percebo que isso não faz parte da resposta, mas, nessa nota, eu também acho que a disponibilidade de plugins estáveis ​​para plataformas como NetBeans e Eclipse desempenham um papel em que a ferramenta é mais adequada para a tarefa, ou melhor, que ferramenta é o melhor ajuste para “você”. Isto é, a menos que você realmente queira fazer o caminho do CLI.

Tanto o Eclipse (e tudo baseado nele) quanto o NetBeans às vezes têm problemas com filesystems remotos (como o SSH) e atualizações externas de arquivos; que é mais uma razão pela qual você quer que o que você escolher funcione “perfeitamente”.

Eu estou tentando responder a esta pergunta por mim mesmo agora também .. e eu derramei os candidatos para Git ou Mercurial .. obrigado a todos por fornecer informações úteis sobre este tema sem se tornar religioso.

Ainda outra comparação interessante de mercurial e git: Mercurial vs Git . O foco principal está nos internos e sua influência no processo de ramificação.

Se você está interessado em uma comparação de desempenho do Mercurial e do Git, dê uma olhada neste artigo . A conclusão é:

Tanto o Git quanto o Mercurial apresentam bons números, mas fazem um trade-off interessante entre velocidade e tamanho do repository. O Mercurial é rápido, com adições e modificações, e mantém o crescimento do repository sob controle ao mesmo tempo. O Git também é rápido, mas seu repository cresce muito rapidamente com arquivos modificados até que você reembale – e esses pacotes podem ser muito lentos. Mas o repository é muito menor que o do Mercurial.

O site mercurial tem uma grande descrição das semelhanças e diferenças entre os dois sistemas, explicando as diferenças de vocabulário e conceitos subjacentes. Como um usuário de longo tempo, isso realmente ajudou a entender a mentalidade do Mercurial.

Se você estiver migrando do SVN, use o Mercurial, pois sua syntax é MUITO mais compreensível para usuários do SVN. Fora isso, você não pode dar errado com qualquer um. Mas verifique o tutorial do GIT e o HGinit antes de selecionar um deles.

Este link pode ajudá-lo a entender a diferença http://www.techtatva.com/2010/09/git-mercurial-and-bazaar-a-comparison/

Algumas pessoas acham que os sistemas VCS precisam ser complicados. Eles incentivam a inventar termos e conceitos no campo. Eles provavelmente pensariam que numerosos PhDs sobre o assunto seriam interessantes. Entre esses provavelmente estão aqueles que projetaram o Git.

O Mercurial é projetado com uma mentalidade diferente. Os desenvolvedores não devem se importar muito com o VCS e, em vez disso, devem gastar seu tempo em sua function principal: engenharia de software. O Mercurial permite que os usuários usem e abusem do sistema sem deixá-los cometer erros não recuperáveis.

Qualquer ferramenta profissional deve vir com um CLI claramente projetado e intuitivo. Os usuários do Mercurial podem fazer a maior parte do trabalho emitindo comandos simples sem nenhuma opção estranha. Em Git double dash, opções loucas são a norma. O Mercurial tem uma vantagem substancial se você é um CLI (e, para ser honesto, qualquer Engenheiro de Software que se preze deveria ser).

Para dar um exemplo, suponha que você faça um commit por engano. Você esqueceu de editar alguns arquivos. Para desfazer sua ação no Mercurial, basta digitar:

$ hg rollback

Você então recebe uma mensagem dizendo que o sistema desfaz sua última transação.

No Git você tem que digitar:

$ git reset --soft HEAD^

Então, ok, suponha que você tenha uma ideia do que é a redefinição. Mas, além disso, você precisa saber quais são as redefinições “–soft” e “–hard” (qualquer palpite intuitivo?). Ah, e claro, não esqueça o personagem ‘^’ no final! (agora o que no nome de Ritchie é isso …)

A integração do Mercurial com ferramentas de terceiros, como kdiff3 e meld, também é muito melhor. Gere seus patches mesclar seus ramos sem muito barulho. O Mercurial também inclui um servidor http simples que você ativa digitando

hg serve

E deixe que outros naveguem pelo seu repository.

O resultado é que o Git faz o que o Mercurial faz, de uma maneira muito mais complicada e com um CLI muito inferior. Use o Git se você quiser transformar o VCS do seu projeto em um campo de pesquisa científica. Use o Mercurial se você quiser fazer o trabalho de VCS sem se importar muito com isso e se concentrar em suas tarefas reais.