O controle de versão deve conter código e configuração necessários para criar o aplicativo.
Isso significa que:
Coisas temporárias que foram introduzidas por um curto período de tempo (o tempo necessário para identificar a localização de um bug ou para experimentar um recurso de um idioma, por exemplo) não devem estar em um controle de versão: mantenha-o até que você precise e remova-o simplesmente ao fazer o commit .
Arquivos locais adequados a uma máquina específica podem ser mantidos em uma ramificação.
Eu evitaria mantê-los apenas localmente, pois é muito doloroso refazer tudo isso quando seu laptop é roubado ou um vírus obriga a reinstalar o sistema operacional (e, a propósito, você descobre que seu último backup foi feito há dois anos) .
Por outro lado, tenha cuidado com a estrutura do arquivo: a configuração local está OK, até que se torne avassaladora, e obriga a fazer uma única alteração em todos os arquivos de cada um dos 42 desenvolvedores participantes do projeto.
Preste atenção na oportunidade de remover as particularidades entre as máquinas. Isso pode significar:
Dando acesso a um servidor SQL dev para substituir instâncias locais em máquinas de desenvolvedores,
Usando serviços de distribuição de pacotes como Pypi ou npm para pacotes públicos e suas contrapartes particulares para pacotes internos,
Peça aos membros da equipe para instalar as mesmas versões de software,
Torne as atualizações de software o mais transparente possível,
Ou torne possível implantar o sistema operacional e o software necessário em uma máquina com um clique (mais o tempo para cada desenvolvedor instalar seu Vim vs. Emacs, Chrome vs. Firefox etc.)
Tão:
Arquivos de projeto. Os caminhos podem precisar ser editados para refletir o layout no PC atual.
Por que não usar o mesmo layout em todos os PCs? Os caminhos dentro do projeto devem ser relativos ao arquivo do projeto, o que significa que não importa onde o projeto está localizado. Versões de software e bibliotecas são melhores para evitar erros crípticos que aparecem apenas em algumas máquinas e são impossíveis de reproduzir para outros membros da equipe.
Exemplo:
Em um projeto criado com o Visual Studio, você pode encontrar:
Os próprios arquivos. Os caminhos são relativos, não importa se, na minha máquina, o projeto está localizado H:\Development\Hello World Project\
enquanto outros membros da equipe fazem check-out no projeto C:\Work\HelloWorld\
.
As dependências, ou seja, bibliotecas de terceiros e internas. Ambos os tipos devem ser tratados pelo NuGet, o que torna obsoletas todas as discussões relacionadas a conflitos. Se você não possui a mesma versão da biblioteca que eu tenho, peça ao NuGet para atualizar as dependências. Tão simples como isso (quando funciona bem, o que nem sempre é o caso).
Observe que é crucial manter as bibliotecas internas também em um NuGet particular. Ter um monte de bibliotecas armazenadas em uma pasta compartilhada ou enviadas por e-mail para uma equipe leva a servidores de CI anárquicos e depressivos.
As configurações. É crucial que a equipe compartilhe as mesmas configurações. Se metade da equipe decide tratar os avisos como erros e metade da equipe mantém os avisos como estão, os membros da primeira parte da equipe gastam seu tempo removendo os avisos gerados pelos desenvolvedores da segunda parte da equipe.
As configurações relacionadas aos utilitários. Isso é complicado, porque alguns membros da equipe podem ter instalado alguns utilitários, enquanto outros não.
É altamente recomendável ter o mesmo conjunto de ferramentas instalado. Se alguns programadores quiserem usar o StyleCop, mas outros não, a equipe não fará o trabalho. Se alguns usam contratos do Código, mas outros não, eles terão os mesmos problemas.
Makefiles. Por exemplo, a otimização pode precisar ser desativada durante a depuração, mas não para o servidor de IC.
Mantenha vários makefiles no controle de versão. Não é incomum criar também uma versão de depuração no servidor de CI e enviá-la a um cliente que tenha um bug complicado.
Hacks feios e sujos. Por exemplo, retorne 7 no meio de uma função, para testar algo, dependendo da função, e suspeita de quebra no valor de 7.
Eu evitaria esse código em primeiro lugar. Para testar algo, use testes de unidade. Se realmente levar alguns segundos para trocar algum código com o objetivo de depurar , faça-o, mas você removerá esse código em alguns minutos, portanto, não há necessidade de confirmá-lo.
Ao descrevê-lo, você deve escrever um teste. Por exemplo, se você quiser ter certeza de que:
class TemperatureConverter
{
public int CelsiusToFahrenheit(int temperature)
{
...
}
}
lança uma exceção quando temperature
é inferior a AbsoluteZero
constante, você não deve jogar com o próprio código. Em vez disso, crie um teste de unidade que:
- documente seu código,
- aumentar a confiabilidade do seu código,
- garantir que os mantenedores possam confiar no teste de regressão ao modificar o método acima,
- servir a outros desenvolvedores de sua equipe que talvez precisem fazer o mesmo teste.