As duas ferramentas principais para a Gerência de Configuração de Software (GCS) são o controle de mudança e o controle de versão. Resumidamente, uma ferramenta de controle de mudança registra solicitações de mudança no projeto através de tickets ou tarefas. O controle de versão registra a evolução dos arquivos do projeto. Ferramentas populares de controle de mudança são o Trac e o Redmine; de controle de versão, Subversion, Mercurial e Git.
As ferramentas de controle de mudança até possuem funcionalidades que exibem o histórico e o conteúdo das revisões contidas no controle de versão. Entretanto, para a GCS, o que é realmente necessário é uma amarração entre o pedido de mudança e a revisão em que está implementada e vice-versa, permitindo rastrear a solicitação até sua implementação e o caminho contrário.
No controle de versão, essa ligação é feita no momento da consolidação (commit) através da mensagem de log, onde se registra um padrão tal como “resolve #173″, que indica o ticket finalizado. Do lado do controle de mudança, a amarração correspondente é feita adicionando um comentário ao ticket/tarefa com um padrão parecido —”implementado em [238]” por exemplo —, e depois mudando o estado do ticket/tarefa para ‘fechado’ (ou outro estado, conforme o ciclo de vida definido).
O registro na mensagem de log da consolidação é manual, mas o comentário adicional no ticket pode ser feito automaticamente. No Redmine, por exemplo, ao encontrar o padrão específico na mensagem de log de uma revisão, o ticket associado é fechado imediatamente.
O problema do registro manual na mensagem de consolidação é que um desenvolvedor desatento ou despreparado pode simplesmente não usar o padrão definido. O ideal é que haja algum tipo de validação que pelo menos exija a amarração a um ticket, mas outras checagens podem ser feitas, tais como se o ticket realmente existe, está aberto e pertencente ao autor do commit. No Subversion, essas validações podem ser feitas através de um script de pre-commit.
O script de pre-commit abaixo faz uma validação mínima, exigindo que o padrão referenciando um único ticket ou tarefa exista em toda mensagem de consolidação:
#!/usr/bin/python# -*- coding: utf-8 -*-## Copyright (c) 2011 Pronus Engenharia de Software# Copyright (c) André Felipe Dias# Licensed under the MIT license:# http://www.opensource.org/licenses/mit-license.php# ----------------------------------------------------------------------------------importreimportsysfromsubprocessimportPopen,PIPErepos_path=sys.argv[1]transaction=sys.argv[2]svnlook='/usr/bin/svnlook'log=Popen((svnlook,'log','-t',transaction,repos_path),stdout=PIPE,stderr=PIPE,stdin=PIPE).communicate()[0].lower().strip()padrao=re.findall('(?:ref|refs|resolve|implementa)\s+(#[0-9]+)',log)tickets=re.findall('#\d+',log)ifnotpadrao:sys.exit(''' Padrao nao encontrado. Sao mensagens de log validas: ref #123 resolve #123 implementa #123''')eliflen(tickets)>1:sys.exit('So deve haver referencia a um ticket/tarefa por consolidacao')sys.exit(0)
Nos links abaixo, há outros exemplos de scripts de commit que podem servir de inspiração para validações mais avançadas:
A nova funcionalidade de subrepositórios segue a linha da propriedade svn:externals do Subversion. A idéia é permitir o uso de um repositório dentro de outro (fica sendo um subdiretório) e tratar todos como um só grupo.
As possibilidades são interessantes: é possível montar um projeto combinando partes formadas por projetos independentes.
Ao invés de propriedades, o mercurial usa um arquivo chamado .hgsub para registrar os subrepositórios. Só lembrando que arquivos que começam com ‘.’ são ocultos no Linux.
A criação e o registro dos subrepositórios ainda precisam ser feitos manualmente nesta versão que ainda é experimental. Entretanto, já estão previstas melhorias nesse sentido e também em manter subrepositórios não nativos, isto é, de outros sistemas tais como Subversion ou Git.
Extensão Alias
Alias era uma extensão à parte, mas agora é distribuída junto com o Mercurial. Mesmo assim, precisa ser habilitada no arquivo .hgrc do usuário para funcionar.
Permite a criação de “apelidos” para conjuntos de comandos e parâmetros usados com frequência. Por exemplo:
[extensions]
alias =
[alias]
llog = log --limit 10
A configuração acima cria um “novo” comando llog equivalente à execução do comando log --limit 10.
Extensão Share
Esta extensão permite criar — localmente — áreas de trabalho independentes que compartilham fisicamente o mesmo repositório (diretório store do .hg). A vantagem é que todos os commits feitos aparecem automaticamente no histórico dos repositórios compartilhados sem a necessidade de comandos de push ou pull.
É útil para a criação de uma área de trabalho para um ramo, por exemplo, e não desperdiça espaço com um armazenamento do repositório interno.
Instalação da Versão 1.3
No Linux, é mais vantajoso usar o easy_install para obter a versão mais recente (easy_install -U Mercurial). A outra opção seria usar os pacotes da distribuição, mas essa alternativa costuma ser mais desatualizada.
No Windows, é possível utilizar o Mercurial 1.3, inclusive através da linha de comando, instalado diretamente o TortoiseHg 0.8. Interessante ressaltar que o TotoiseHg também funciona em plataformas não-Windows. Veja a página do TortoiseHg para mais informações.
Para aqueles que vão ficar no controle de versão centralizado, a decisão é bem simples: Subversion. Já é um padrão estabelecido, desbancando outros tais como CVS, Visual Source Safe, ClearCase etc. Não há realmente muito a acrescentar neste ponto.
O verdadeiro desafio está na escolha da ferramenta de controle de versão distribuído.
Licença open source. Não há a menor necessidade de usar uma ferramenta proprietária para controle de versão. Aliás, as melhores são open source.
Rodar em plataformas diferentes (Windows, Linux, etc.). A mesma ferramenta deve permitir que a equipe use a plataforma que quiser/precisar para trabalhar. Melhor ainda se houver uma interface gráfica tipo TortoiseSVN ou plugin para a IDE, mesmo que a linha de comando seja muito mais rápida e produtiva para a maioria das operações do controle de versão.
Massa crítica de projetos já usando. Se vários projetos grandes usam a ferramenta é sinal de que ela já foi testada, avaliada e aceita por outros antes. Além disso, é mais provável que haverá uma comunidade ativa mantendo e desenvolvendo a ferramenta por muitos anos.
Depois de aplicados os critérios na lista, acabam restando praticamente o Git e o Mercurial. Talvez o Bazaar também pudesse ser incluído mas outros como Darcs, Monotone e SVK não passam no critério 3.
A seguir, alguns projetos conhecidos que usam o Mercurial ou o Git:
Git: Linux kernel, Perl, Samba, X.org Server, Qt, Ruby on Rails, GNOME, Google Android, Btrfs da Oracle etc..
Aspectos Sociais na Escolha do DVCS
Critérios de desempate podem ser desempenho, funcionalidades, facilidade de uso, portabilidade, interfaces etc. O problema é que as análises comparativas entre o Mercurial e o Git têm mostrado muito mais semelhanças que diferenças entre os dois. Embora um ou outro tenha uma pequena vantagem em algum dos aspectos, não há diferença realmente significativa que justifique uma decisão baseado nisso.
Processos recentes tem usado outros fatores para o desempate tais como menor curva de aprendizado, suporte à plataforma Windows e preferência dos desenvolvedores para definir a escolha:
A análise comparativa feita pelo Google Code entre o Mercurial e o Git considerou as duas alternativas bastante equilibradas. O Mercurial foi escolhido por ter um conjunto de comandos mais próximos do Subversion, o que facilita a transição dos desenvolvedores, e também por ter desempenho e adequação melhores ao serviço que o Google Code já oferece.
Considerando funcionalidades e desempenho equivalentes, o que vai ser importante na escolha são as afinidades do Git ou Mercurial com as características do projeto/equipe/empresa. O desempate acabará sendo feito por critérios mais subjetivos tais como proximidade com outros projetos relacionados e preferência dos desenvolvedores.
Outros Projetos Relacionados
Projetos maiores que já usam o Mercurial ou o Git acabam atraindo projetos relacionados para o seu campo de influência.
A interferência direta se dá quando é necessário acompanhar ou mesmo participar de certos projetos externos associados com o projeto da equipe. A escolha da mesma ferramenta para todos torna o controle de versão muito mais fácil pois define um padrão homogêneo.
A tabela a seguir apresenta alguns projetos e qual a ferramenta que usam.
Projeto
Git
Mercurial
Google Android
X
Google Code
X
Pylons
X
Python (linguagem)
X
Ruby on Rails
X
Sun (OpenJDK, NetBeans, OpenSolaris)
X
Preferência dos Desenvolvedores
Esse é o critério mais passional de todos. O que leva um desenvolvedor a preferir uma ferramenta a outra varia desde a identificação com a filosofia do projeto até a preferência pelo logotipo do projeto. De qualquer modo, uma tendência clara da equipe por uma ferramenta específica deve ser pesado na decisão final.
Estudos de Caso
Projeto X
Projeto Y
Projeto Z
Escolha Final
Mercurial
Git
Mercurial
Plataforma
Windows
Windows/Linux
Linux
IDE/Interface
Eclipse
NetBeans
linha de comando
Linguagem Principal
Java
Ruby
Python
Projetos relacionados usam
Subversion/Mercurial
Git
Subversion/Mercurial
Preferência dos Desenvolvedores
-
Git
Mercurial
Considerações Finais
Git e Mercurial são ambas ótimas opções de controle de versão distribuído. A análise de um ou outro baseado em número de funcionalidades, forma de implementação interna, desempenho etc. acaba caindo em um tipo de discussão que abunda pelas listas de discussão na internet a fora e que gera muito calor e pouca luz!
Em termos práticos, ambas as ferramentas são muito parecidas e é mais fácil (e prático) escolher entre uma e outra com base na afinidade com o projeto/equipe.
É bom lembrar que controle de versão é muito mais que instalar a ferramenta e sair usando. É necessária a capacitação dos desenvolvedores, a definição de um processo de GCS em sintonia com as particularidades da ferramenta e também integração com uma ferramenta de controle de mudança (por exemplo, o Trac). Já pensando nisso, a Pronus Engenharia de Software lançará em breve o curso de Gerência de Configuração de Software com Trac e Mercurial.
Links Relacionados
Comparação entre Git e Mercurial. Quadro comparativo entre principais características entre os dois. Alguns comentários interessantes também sobre portabilidade e interfaces disponíveis.
Why Git is better than X? Artigo interessante que analisa diversos pontos de Git com boas ilustrações de conceitos.
Thread sobre Git x Mercurial. Exemplo de discussão interminável sobre aspectos técnicos de Git e Mercurial. Típico debate que gera muito calor e pouca luz.
Antes de mais nada, é importante relembrar que controle de versão de software é uma técnica comprovada de engenharia de software. Independente da escolha entre o modelo centralizado ou distribuído, é fundamental que algum controle de versão seja usado.
Para ajudar na escolha, siga o fluxograma a seguir:
Já usa algum controle de versão? Se ainda não, a decisão é simples: melhor já começar com o controle de versão distribuído de uma vez, com uma boa capacitação da equipe e do processo para que tudo corra bem.
Planejar | Executar adoção | migração para DVCS. Pavimentar o caminho para uma transição suave e bem-sucedida. Cronogramas, projeto-piloto, migração, capacitação da equipe, elaboração do processo de desenvolvimento, suporte técnico, acompanhamento, avaliações etc..
Funciona bem? Não há motivo para trocar uma solução que já funciona por outra. Como diz o ditado, em time que está ganhando, não se mexe. Ainda mais em um projeto em andamento, trocar de modelo de controle de versão só adicionaria riscos desnecessários.
Experimentar DVCS? O controle de versão distribuído traz alguns benefícios interessantes e mesmo a estrutura atual funcionando bem, talvez seja possível melhorar ainda mais. A experimentação de uma nova tecnologia geralmente segue um arranjo comum: projeto-piloto simples, escopo bem definido e equipe formada por pessoas pré-dispostas a novas experimentações.
Falta capacitação? Alguma coisa está errada na solução atual. Antes de trocar seis por meia dúzia, é melhor analisar qual a causa: se é por falta de capacitação da equipe, inexistência de um processo bem definido ou se realmente o projeto se encaixa mais no perfil do DVCS.
Migração para DVCS é viável? A subutilização do controle de versão é muito mais comum do que deveria. O sintoma clássico é o uso burocrático do controle de versão basicamente como ferramenta de backup, como já comentado num post anterior. Se é necessário investir em capacitação, talvez valha a pena que essa capacitação já seja feita em uma ferramenta mais moderna. Talvez não. Talvez apenas acertar a solução atual resolva.
Consultoria | Treinamento em Controle de Versão Centralizado. Capacita a equipe e define o processo necessário para usar a solução atual, aproveitando tudo que o controle de versão tem para contribuir.
Considerações Finais
A mudança do controle de versão centralizado pelo distribuído é mais que uma questão apenas de troca de ferramenta. Implica ajustes no processo e também capacitação da equipe de desenvolvimento.
Controle de versão distribuído traz vantagens sim, mas não torna o controle de versão centralizado obsoleto. A decisão de passar de um tipo para outro deve ser analisada com cuidado. De preferência com experimentações para gerar algum tipo de opinião própria e depois com muito planejamento para que não haja surpresas.
A tabela a seguir apresenta sugestões de mudança de acordo com o perfil do uso de controle de versão:
Uso atual do controle de versão
Vale a pena mudar para o Distribuído?
Comentários
Não usa | Subutiliza
Sim
Invista na mais nova geração de controle de versão de uma vez! A definição e um processo e capacitação da equipe ajudarão na melhoria da qualidade do software.
Insatisfatório pois se encaixa no perfil DVCS
Talvez
Depende de alguns fatores. Entre eles de quanto os problemas atrapalham o andamento do projeto.
Satisfatória
Não
Projetos atuais não devem migrar. Mas experimentações são bem-vindas em projetos-piloto.
Controle de versão distribuído (Distributed Version Control Systems – DVCS) é a mais nova geração de sistemas de controle de versão de software. Apesar de o conceito existir já há algum tempo, recentemente as ferramentas se tornaram maduras o suficiente para chamar a atenção de diversos projetos open source, que migraram ou expandiram seu suporte do Subversion (centralizado) para o Mercurial, Git e Bazaar (distribuídos) por exemplo.
Para equipes de desenvolvimento com acesso ao repositório pela rede local, essa arquitetura funciona bem. A velocidade da rede não é problemática, o tempo de resposta do processamento é aceitável e todos os desenvolvedores da equipe têm permissão de leitura e escrita no repositório.
Não foi para resolver exatamente esse tipo de necessidade que o controle de versão distribuído foi criado. Imagine uma situação diferente:
Equipe com centenas de desenvolvedores. Significa que mais processamento vai ser exigido do servidor central, piorando o tempo de resposta;
Equipe espalhada em diferentes filiais da empresa. Acesso remoto ao repositório com limitações de conexão e de permissão de escrita;
A arquitetura cliente-servidor não funciona tão bem para essas situações. Soluções alternativas como aumentar a capacidade de processamento do servidor ou replicar os repositórios nem sempre são viáveis ou fáceis de serem implementadas.
As vantagens estão relacionadas à distribuição do processamento, redundância/replicação de repositórios e as novas possibilidades de colaboração entre desenvolvedores.
Do ponto de vista do desenvolvedor
Rapidez. As operações são processadas localmente. Não é necessário passar pela rede e contatar o servidor central para fazer um commit, log ou diff por exemplo.
Autonomia. A conexão com a rede só é necessária para trocar revisões com outros repositórios. Fora isso, trabalha-se desconectado e em qualquer lugar, como num cliente por exemplo.
Ramos privativos. Além de um repositório próprio, o trabalho local é feito em um ramo privativo que não interfere, nem sofre interferência dos demais, mesmo nas operações de sincronização entre repositórios. O momento de combinar um ramo com outro é uma decisão do desenvolvedor e não obrigatório antes de cada commit, como acontece no centralizado.
Facilidade de Mesclagem. Só a facilidade de criação de ramos não seria suficiente se não fosse o rastreamento automático usado pelos DVCS, que torna o processo de mesclagem muito mais simples e indolor. Observação: No Subversion, o rastreamento automático de merges começou a partir da versão 1.5
Do ponto de vista da gerência/coordenação
Parte das decisões gerenciais envolve manter livre o caminho da equipe para que possam trabalhar da melhor maneira possível. Outras decisões importantes são sobre redução de custos. Nestes dois casos específicos, o modelo distribuído oferece as seguintes vantagens:
Confiabilidade. No sistema centralizado, uma pane no servidor interrompe todo o desenvolvimento. Já no sistema distribuído, além de a equipe poder continuar seu trabalho (observação: veja a seção “controle de mudança ainda é centralizado” mais abaixo), os repositórios dos desenvolvedores funcionam como cópias de backup de todo o projeto.
Redução de custos com servidor. A carga de processamento fica distribuída nas próprias máquinas dos desenvolvedores. O repositório “central”, quando existe, tem o papel do repositório “oficial” e não como processador central das requisições.
Em que situações o controle de versão distribuído não vai tão bem?
Nem tudo são flores com o modelo distribuído de controle de versão.
Maior complexidade
No centralizado, os desenvolvedores trabalham no mesmo ramo, seja esse ramo o principal ou um ramo de manutenção.
Essa forma de trabalho é mais simples de se entender. Mesmo que limitadamente, uma pessoa com pouco conhecimento de controle de versão consegue trabalhar com o resto da equipe.
O modelo distribuído é mais complicado. A arquitetura peer-to-peer, ramos privativos e as mesclagens aparentemente desordenadas podem tornar o grafo da evolução do projeto confuso à primeira vista.
Ao contrário do centralizado, não adianta só commit e update para funcionar “no tranco”. Todos os desenvolvedores da equipe precisam ter um conhecimento maior do modelo, da ferramenta e, de preferência, também de um processo de desenvolvimento que padronize fluxos de trabalho a serem seguidos. Só assim, o grafo acima deixa de ser apenas um emaranhado e passa a representar muito claramente o fluxo do trabalho.
Travamento de arquivos binários precisa ser centralizado
Diferentemente dos arquivos de texto, arquivos binários possuem um formato interno que não é baseado em linhas de texto e, por isso, não podem ser mesclados automaticamente pelo controle de versão ou manualmente pelo desenvolvedor.
Sendo assim, a edição concorrente de arquivos binários é problemática. Duas pessoas editando ao mesmo tempo uma figura, por exemplo, não conseguirão mesclar as modificações depois e o trabalho de uma delas precisará ser refeito.
Com arquivos binários, a melhor solução é usar o travamento, isto é, sinalizar que o arquivo está travado para edição e que ninguém mais deve editá-lo enquanto isso.
O modelo puramente distribuído não é adequado para lidar com travamento justamente por não possuir um servidor central que possa controlar as travas de todos.
Controle de mudança ainda é centralizado
As ferramentas de controle de mudança (e.g. Trac, Redmine, Mantis, Bugzilla) ainda não acompanharam as de controle de versão na arquitetura peer-to-peer. Isto significa que mesmo usando um DVCS, ainda haverá uma ferramenta centralizada para controle de mudança.
O ideal seria que o controle de versão e o controle de mudança fossem integrados e distribuídos, tal como é no Fossil. Essa ferramenta parece ser interessante, mas ainda é muito incipiente.
Resumo das Características do Controle de Versão Distribuído
Ponto de Vista
Vantagens
Desvantagens
Desenvolvedor
Rapidez
Autonomia
Ramos Privativos
Facilidade de Mesclagem
Necessidade de maior conhecimento da ferramenta e do processo
Coordenação/Gerência
Redução de custos com servidor e infraestrutura externa de rede
Confiabilidade
Aumento da produtividade
Necessidade de maior capacitação de desenvolvedores
Importante ter um processo definido
O controle de mudança ainda precisa ser centralizado
Considerações Finais
Controle de versão distribuído oferece muitas vantagens interessantes. Mesmo projetos que não se encaixam diretamente no perfil podem se beneficiar. Entretanto, por ser um pouco mais complexo, o modelo distribuído requer mais preparo da equipe e também do processo, o que não chega a ser realmente um impedimento uma vez que um processo formalizado e equipes capacitadas são fundamentais para produção de software de qualidade.
Em um próximo artigo, vou analisar alguns pontos que ajudarão a decidir a viabilidade ou não de se mudar do centralizado para o controle de versão distribuído.
Acaba de sair a versão 1.5.3 do Subversion. Entre as principais mudanças estão melhorias no desempenho da operação de merge. No caso do Windows, essa melhoria chega a 30%.
A relação completa das mudanças está disponível neste link.
A versão 1.5.0 do Subversion foi lançada no dia 19 de junho. A característica mais importante desta nova versão é o rastreamento automático da operação de merge: o Subversion agora anota (na propriedade svn:mergeinfo) as revisões e caminhos utilizados. Como resultado, o uso de ramificações no projeto fica mais fácil e menos sujeito a erros.
Um dos problemas que se evita é o uso repetido do mesmo merge várias vezes. Por exemplo, imagine que o merge da revisão 100 feita sobre o trunk execute a remoção de um arquivo doc/instrucoes.html e a alteração das linhas 10 e 20 do arquivo source/calc.py. O problema acontece quando você não lembra que já fez o merge dessa revisão (pois não registrou isso na mensagem de log) e depois de um tempo, aplica o mesmo merge de novo.
Se o mesmo merge for usado novamente sobre o trunk, ele tentará remover um arquivo doc/instrucoes.html e alterar novamente as linhas 10 e 20 do arquivo source/calc.py. Entretanto, o arquivo doc/instrucoes.html já não existe mais e o arquivo source/calc.py já havia sido alterado nessas linhas. Na melhor das hipóteses, o resultado é uma série de “skipped missing target” e conflitos. No pior caso, o problema não é detectado e o resultado final é um bicho que sempre me lembra a propaganda da coca-cola mostrada no vídeo abaixo.
A partir da versão 1.5.0, esse problema não aconteceria pois ao tentar realizar o merge, o Subversion detecta que o intervalo já foi usado e não o usa novamente.
Limitações do Merge Tracking
É importante saber que a implementação do rastreamento de merge da versão 1.5.0 não está completa; ainda faltam algumas partes da especificação original que serão implementadas nas próximas versões. Além disso, também há alguns problemas já conhecidos e relatados pendentes de solução. Isto significa que existem alguns casos que a funcionalidade atual não cobre e precisam ser resolvidos manualmente.
Pela lei de Murphy, justamente o caso que você vai precisar, não está coberto ainda pelo Subversion. Pelas experimentações que fizemos aqui na Pronus, situações que envolvem renomeações de arquivos ou diretório é um dos casos não cobertos pelo Subversion 1.5.0.
Considerações Finais
Esta versão do Subversion se mostrou um pouco frustrante, pois esperávamos que este problema de rastreamento de merge tivesse sido totalmente resolvido, mas ainda falta muita coisa a ser feita. Resta aguardar para que a funcionalidade completa seja implementada na próxima versão.
Saber pilotar o Subversion além do commit e update é importante, mas só isso não basta. A falta de um processo adequado de Gerência de Configuração de Software pode levar a resultados indesejáveis devido ao uso inadequado da ferramenta. Um exemplo disto é o mau uso do repositório como backup, que pode levar à situação conhecida como “quebrar a build”.
Imagine uma equipe com 10 desenvolvedores que usam a política de sempre fazer o commit das alterações feitas durante o dia antes de ir embora da empresa.
Em princípio, parece ser uma boa idéia pois aproveita o backup noturno que é feito automaticamente no servidor, evitando o risco de perder alguma coisa caso haja problema na máquina de um desenvolvedor.
Por outro lado, gera o problema de quebrar a build: um desenvolvedor “A” publica (faz o commit) de algo no repositório que não compila. Quando outra pessoa (desenvolvedor “B”) fizer uma atualização (update), sua cópia de trabalho passa a não compilar mais.
O que já é ruim, pode piorar ainda mais: o desenvolvedor “B” resolve consertar a o sistema para que volte a compilar. Paralelamente, o desenvolvedor “A” faz o mesmo, produzindo uma solução parecida mas diferente. Ao publicarem no repositório, vão acabar gerando conflitos.
Não está ruim o suficiente ainda? Troque o desenvolvedor “B” por desenvolvedor “B”, “C”, “D”, “E” etc. e terá o caos instalado com a equipe inteira parada enquanto o problema é resolvido.
Pra fechar com chave de ouro, só falta dizer que a culpa é do controle de versão! Como se fosse responsabilidade do controle de versão verificar o conteúdo do que é publicado no repositório!
Como evitar que esse tipo de problema aconteça?
Uma solução seria o uso de ramos privativos para cada desenvolvedor trabalhar na sua tarefa, de forma que a integração com o trunk é feita só ao final. Vou tratar deste assunto com mais detalhes em outra oportunidade mas já adianto que resolve este problema mas cria outro, que é a necessidade constante de realização de operações de merge. Basta lembrar que merge é a operação mais complicada do controle de versão (seja ele qual for).
A outra solução é bem mais simples. Basta estabelecer a política de nunca publicar no repositório sem antes compilar e testar. Esta solução ainda pode evoluir para um política mais abrangente, que aceita apenas tarefas completadas, compiladas e verificadas.
Necessidade de Um Processo de Gerência de Configuração
Usar uma ferramenta de controle de versão é muito importante, mas será que a equipe de desenvolvimento está realmente tirando algum proveito real disso ou só cumprindo uma etapa burocrática?
Eu trabalhei em uma empresa que usava o CMVC como controle de versão (nem perca tempo procurando sobre a ferramenta pois é antiga e ruim). Ao entrar para a equipe de desenvolvimento, recebi alguns treinamentos mas nenhum relacionado à ferramenta de controle de versão; apenas me ensinaram como fazer as operações equivalentes ao commit e update do Subversion, nada mais. (observação: o CMVC trabalha com a política pessimista de travamento)
Usar o commit e update já ajuda, claro. Evita perder código-fonte e sobrescrever o trabalho de outro desenvolvedor. Mas será que controle de versão é só isso? Está mais para usar o repositório para fazer backup apenas. É como ter uma ferrari na garagem e só usar pra ir comprar pão na padaria a duas quadras de casa.
O controle de versão ajuda a resolver outros tipos de problemas, tais como:
Recuperar um arquivo de uma versão anterior: Um arquivo “A” foi apagado, mas não devia. Agora, passadas N revisões, quero trazer o arquivo de volta, mantendo o histórico com aquele arquivo “A” original.
Desfazer uma mudança sem afetar outras: A revisão atual do repositório é 100 e agora descobriu-se que a mudança feita na revisão 90 não devia ter acontecido. É necessário desfazer esse conjunto de alterações, sem perder as modificações feitas entre as revisões 90 e 100, que são válidas.
Trabalhar em versões diferentes (mas semelhantes) do mesmo software: Uma nova versão foi lançada e é necessário manter seu código ativo para correções de defeitos que porventura serão encontrados e corrigidos.
Replicar a correção de um defeito em vários ramos: Uma correção foi feita em um ramo e agora é necessário que todas as mudanças que foram feitas para corrigir os defeitos sejam refeitas em outros ramos. Um problema em potencial é que os outros ramos receberam suas próprias modificações nesse período.
Para resolver esses problemas, precisa-se de bem mais que commit e update.
Talvez não sejam todos na equipe que precisem saber fazer todas as operações, mas não é nem um pouco confortável mexer numa ferramenta importante como o controle de versão sem ter segurança no que se está fazendo. Investir em treinamento de todos os desenvolvedores ajuda bastante a mudar esse quadro.
Outra coisa importante a saber é que o controle de versão é uma atividade de Gerência de Configuração de Software e resolve uma parte dos problemas da área. Também é importante usar algum software para controle de mudança e ter um processo que guie a utilização das ferramentas.