Possível duplicata:
Eu sou um nerd do Subversion, por que devo considerar ou não o Mercurial, o Git ou qualquer outro DVCS?
De vez em quando, você ouve alguém dizendo que o controle de versão distribuído (Git, HG) é inerentemente melhor que o controle de versão centralizado (como o SVN) porque a fusão é difícil e dolorosa no SVN. O problema é que nunca tive problemas com a fusão no SVN, e como você só ouve essa alegação de defensores do DVCS, e não de usuários reais do SVN, isso tende a me lembrar daqueles comerciais desagradáveis na TV em que eles tente vender-lhe algo de que não precisa, fazendo com que atores desonestos finjam que o que você já tem e funciona bem é incrivelmente difícil de usar.
E o caso de uso invariavelmente levantado é a re-mesclagem de uma ramificação, o que me lembra novamente os anúncios de produtos de palha; se você sabe o que está fazendo, não deve (e nem precisa) re-mesclar uma ramificação em primeiro lugar. (É claro que é difícil fazer isso quando você está fazendo algo fundamentalmente errado e bobo!)
Portanto, descontando o caso de uso ridículo do strawman, o que há na mesclagem SVN inerentemente mais difícil do que a mesclagem em um sistema DVCS?
Respostas:
É porque o svn não possuía as estruturas de dados adequadas para determinar com precisão o último ancestral comum dos dois ramos. Isso não é muito importante para uma ramificação que é mesclada apenas uma vez, mas pode causar muitos conflitos de mesclagem incorretos em situações em que várias ramificações são mescladas várias vezes.
Eu não sigo o svn de muito perto, mas meu entendimento é que esses problemas técnicos específicos foram corrigidos nas versões recentes. No entanto, não foi corrigido cedo o suficiente para dissipar o mito, e as pessoas que tentaram o DVCS para as fusões o mantiveram por outros motivos.
fonte
E é aí que reside a fonte da sua confusão e de todo o problema em geral.
Você diz que a fusão de ramificações é "fundamentalmente errada e boba". Bem, esse é exatamente o problema: você está pensando em galhos como coisas que não devem ser mescladas. Por quê? Porque você é um usuário SVN que sabe que a fusão de ramificações é difícil . Portanto, você nunca faz isso e incentiva os outros a não fazê-lo. Você foi treinado para evitar a fusão; você desenvolveu técnicas que você usa para evitar a fusão.
Eu sou um usuário do Mercurial. Mesmo em meus próprios projetos, onde sou o único desenvolvedor, mesclo ramos o tempo todo . Eu tenho um ramo de lançamento, no qual eu corrigi. Bem, eu mesclo isso de volta à linha principal para que a correção vá até lá.
Se eu estivesse usando SVN, adotaria uma estrutura completamente diferente da base de código. Por quê? Como o SVN dificulta a mesclagem, você desenvolve expressões idiomáticas e técnicas para evitar a mesclagem complexa.
Os DVCS facilitam mesclagens complexas porque são o estado padrão . Tudo é um ramo, mais ou menos, em um DVCS. Portanto, toda a estrutura deles é construída desde o início para facilitar a fusão. Isso permite que você desenvolva um fluxo de trabalho que utiliza a mesclagem diariamente, em vez do fluxo de trabalho SVN em que você nunca usa a mesclagem.
O simples fato é o seguinte: você deve abordar um DVCS de uma maneira diferente da SVN. Você deve usar os idiomas apropriados para esses tipos muito diferentes de sistemas de controle de versão. No SVN, você adota idiomas que não envolvem mesclagem porque as mesclas são difíceis. Nos DVCS, você adota idiomas que frequentemente usam mesclagens porque não são um grande problema.
Ferramenta certa para o trabalho certo.
O problema é que o fluxo de trabalho com foco em mesclagem é muito mais agradável e fácil de usar do que o fluxo de trabalho no estilo SVN, no qual você não mescla coisas. É mais fácil ver quando algo do ramo de lançamento foi trazido para o ramo de desenvolvimento. É mais fácil ver as várias interações entre os ramos. É fácil criar ramificações de teste para as coisas e cortá-las se o teste não funcionar. E assim por diante.
Realmente, Joel explica isso muito melhor do que eu . Você deve ter uma boa leitura disso.
fonte
Não há nada muito difícil sobre a fusão SVN ... mais ... se você seguir a filosofia certa
O que vejo na maioria das outras respostas parece vir de pessoas que não usam SVN há algum tempo. Como alguém menciona com precisão: "não foi corrigido cedo o suficiente para dissipar o mito".
Da minha experiência atual de usar o SVN 1.6 a 1.8 em um projeto herdado recentemente, o SVN foi um longo caminho para tornar a fusão uma coisa muito mais fácil. No entanto, não é infalível e acho que não sofre com que os usuários se desviem facilmente do uso pretendido.
Embora eu conhecesse o SVN muito bem e também tentasse o Mercurial para projetos pessoais nesse meio tempo, nunca havia feito muitas ramificações no SVN antes desse projeto. Houve várias tentativas e erros e tive muitos conflitos inesperados de mesclagem quando iniciei.
Por fim, porém, percebi que toda vez que recebia um (ou algum outro problema), era porque não havia feito as coisas corretamente (também conhecido como "o caminho do SVN" - sem dúvida, o caminho do controle de versão). Acredito que é aqui que está a dificuldade: você não pode fazer o que quiser de maneira desorganizada e espera que o SVN funcione perfeitamente, especialmente com mesclagens. As mesclagens exigem disciplina rigorosa do (s) usuário (s) antes de mostrar seu verdadeiro poder.
Aqui estão algumas coisas que eu notei que são recomendações fortes, se não requisitos, para um uso limpo de mesclagens:
Se você não seguir o acima, é bem provável que tenha conflitos. Eles são sempre solucionáveis, mas não muito divertidos para passar o tempo.
Ah, mais uma coisa sobre mesclar onde, de tudo o que li e tentei, o SVN realmente é péssimo: arquivos / pastas excluídos / movidos / renomeados. Aparentemente , o SVN ainda não pode lidar com um arquivo que está sendo renomeado, excluído ou movido em um ramo, e sua versão original modificada em outro ramo ... e depois mesclando-os. Ele simplesmente não saberá para onde o arquivo foi de uma maneira e "esquecerá" as alterações da outra maneira. Uma mudança é obviamente insolúvel (você exclui ou altera o arquivo, não pode fazer as duas coisas), mas a aplicação de alterações nos arquivos movidos / renomeados deve funcionar e não funciona. Espero que isso seja corrigido em breve.
Então, apesar de tudo, a fusão do SVN é fácil? Eu acho que não. Não de uma maneira despreocupada, com certeza. Isso é ruim ? Acho que não. Ele só aparece na sua cara quando você a usa da maneira errada e não pensa o suficiente no que está fazendo.
Com base nisso, posso ver por que as pessoas podem preferir o Mercurial (por exemplo), pois é um pouco mais branda sobre essas coisas da minha experiência e tinha tudo automatizado desde o início (pelo menos nas versões anteriores). No entanto, o SVN alcançou um pouco, então não vale mais tanto esforço.
fonte
Os modelos de dados internos são fundamentalmente diferentes.
Fundamentalmente, no SVN, quando você olha para o histórico de uma ramificação, vê apenas o que aconteceu nessa ramificação. Portanto, quando você mesclar de ramificação
B
em ramificaçãoA
, o histórico da ramificaçãoA
conterá uma confirmação grande contendo todas as alterações feitas explicitamenteB
desde que foram ramificadas.Nas primeiras versões do SVN, se você tiver que mesclar ramificação
B
em ramificaçãoA
mais uma vez, precisará especificar manualmente qual intervalo de revisão de ramificaçãoB
deseja mesclar para evitar mesclar as mesmas revisões duas vezes. É claro que o desenvolvedor inteligente usaria uma mensagem de confirmação como 'Mesclado em B: 1234'.O SVN 1.5 "corrigiu" isso. Mas não mudou como as fusões são aplicadas fundamentalmente. Apenas adicionou alguns metadados extras à ramificação
A
, informando ao SVN que a revisão 1234 foi mesclada, permitindo que o SVN escolha automaticamente o intervalo de revisão correto.Mas essa solução é basicamente uma solução alternativa para um modelo de dados que fundamentalmente não suporta o rastreamento do que foi mesclado.
Mesclar duas ramificações é um exemplo relativamente simples. Mas imaginar esse cenário mais complexo
A
detrunk
e faça algumas confirmações aquiB
deA
e fazer alguns commits aquitrunk
eA
B
emtrunk
A
emB
A
emtrunk
B
emtrunk
(isso realmente não deve fazer nada)Manipular isso corretamente usando o modelo de metadados se torna extremamente complexo (não sei se o SVN realmente manipula esse cenário corretamente e não me sinto inclinado a testá-lo).
Lidar com esse cenário no git é extremamente simples.
No git, toda vez que você confirma, o objeto interno que representa essa confirmação contém uma referência ao cabeçalho anterior. Quando você mescla um ramo, o commit contém referências ao cabeçalho anterior de todos os ramos que estão sendo mesclados (você pode mesclar mais de um ramo por vez no git)
Portanto, quando você examina o histórico de um único commit no git, pode ver todo o histórico, quando foi ramificado, quando foi mesclado e o histórico dos dois ramos entre a ramificação e a mesclagem.
Portanto, ao mesclar em uma ramificação parcialmente mesclada, é extremamente simples determinar o que já foi mesclado e o que não foi.
Não tenho experiência com Mercurial, mas suspeito que seu funcionamento interno seja semelhante ao git.
Então, fundamentalmente, para o SVN, era um objetivo do projeto tornar as ramificações baratas. Mas no git, era um objetivo do projeto tornar a fusão barata.
Por fim, da última vez que usei o SVN, ele não foi capaz de lidar com mesclagens, onde um arquivo foi renomeado em uma ramificação e modificado em outra.
fonte
Fiz várias combinações de SVN - incluindo ter ramificações de desenvolvimento e lançamento de longa duração. De um modo geral, eu sobrevivi. A fusão é sempre complicada, mas com o DCVS a desvantagem não é terrivelmente ruim - tudo é local, basta atualizar para uma boa revisão conhecida e continuar. Enquanto o SVN aconteceu muito no servidor, a recuperação foi feia - geralmente envolvia a remoção da cópia local e o check-out de uma nova ramificação limpa para tentar novamente. Não foi ruim no meu caso - uma conexão de gigabit com a caixa SVN ajuda. Mas tivemos alguns contratados que tiveram muitos problemas com isso, pois estavam em conexões lentas, então tudo levou uma eternidade, incluindo fusões.
fonte
Aqui está uma das coisas mais legais do git. Não é herdado do DVCS, é apenas algo que o git se destaca. Você pode mesclar revisões específicas de qualquer ramificação em outra ramificação. Basicamente, apenas pega o diff e o aplica ao outro ramo, mas faz o rastreamento e é muito mais automático.
Portanto, se você possui a ramificação 2.0 e a ramificação 3.0 e descobre um bug na 2.0, pode corrigi-lo na 2.0 e pegar o conjunto de revisões que a resolvem e mesclar apenas essas revisões na ramificação 3.0. Não acredito que o SVN tenha outra maneira de fazer isso, a não ser pegar manualmente as diferenças para cada revisão e aplicá-las
Obviamente, o algoritmo de mesclagem automática também parece funcionar muito mais suavemente, e o git foi construído a partir do zero no modelo "faça uma ramificação para todas as coisas", de modo que a ramificação é realmente suave e fácil. Parece natural ramificar-se frequentemente com a leveza dos galhos
fonte