No Subversion (e CVS), o repositório está em primeiro lugar. Em git e mercurial não existe realmente o conceito de repositório da mesma maneira; aqui as mudanças são o tema central.
+1
O incômodo no CVS / SVN vem do fato de que esses sistemas não
lembram a paternidade das mudanças. No Git e no Mercurial, não apenas um commit pode ter vários filhos, mas também pode ter vários pais!
Isso pode ser facilmente observado usando uma das ferramentas gráficas, gitk
ou hg
view
. No exemplo a seguir, o branch nº 2 foi bifurcado do nº 1 no commit A, e desde então foi mesclado uma vez (em M, mesclado com o commit B):
o---A---o---B---o---C (branch #1)
\ \
o---o---M---X---? (branch #2)
Observe como A e B têm dois filhos, enquanto M tem dois pais . Esses relacionamentos são registrados no repositório. Digamos que o mantenedor do branch # 2 agora deseja mesclar as mudanças mais recentes do branch # 1, ele pode emitir um comando como:
$ git merge branch-1
e a ferramenta saberá automaticamente que a base é B - porque ela foi gravada no commit M, um ancestral da ponta de # 2 - e que ela deve mesclar o que quer que tenha acontecido entre B e C. O CVS não registra esta informação , nem o SVN antes da versão 1.5. Nesses sistemas, o gráfico seria semelhante a:
o---A---o---B---o---C (branch #1)
\
o---o---M---X---? (branch #2)
onde M é apenas um commit gigantesco "esmagado" de tudo o que aconteceu entre A e B, aplicado em cima de M. Observe que depois que a ação é realizada, não há nenhum vestígio deixado (exceto potencialmente em comentários legíveis por humanos) de onde M originou de, nem de quantos commits foram colapsados juntos - tornando a história muito mais impenetrável.
Pior ainda, realizar uma segunda fusão torna-se um pesadelo: é preciso descobrir qual era a base de fusão no momento da primeira fusão (e é preciso saber
que houve uma fusão em primeiro lugar!) E, em seguida, apresentar isso informações para a ferramenta para que ela não tente reproduzir A..B em cima de M. Tudo isso é difícil o suficiente quando se trabalha em estreita colaboração, mas é simplesmente impossível em um ambiente distribuído.
Um problema (relacionado) é que não há como responder à pergunta: "X contém B?" onde B é uma correção de bug potencialmente importante. Então, por que não registrar essa informação no commit, já que é conhecida na hora do merge!
P.-S. - Não tenho experiência com as habilidades de gravação de mesclagem do SVN 1.5+, mas o fluxo de trabalho parece ser muito mais elaborado do que nos sistemas distribuídos. Se esse for realmente o caso, provavelmente é porque - conforme mencionado no comentário acima - o foco é colocado na organização do repositório ao invés das próprias mudanças.