Quando devo parar de me comprometer em dominar novos projetos?

26

Sempre que um novo projeto é iniciado, geralmente faz sentido começar assumindo diretamente o domínio até obter algo "estável" e, em seguida, você começa a trabalhar nas ramificações.

Pelo menos, é assim que eu normalmente faço. Existe uma maneira de iniciar ramificações imediatamente a partir do segundo commit? Faz sentido fazer dessa maneira? Obviamente, o "Commit inicial" estará sempre no mestre, mas depois disso, quando saberei que é o momento certo para começar a criar ramificações para novos recursos?

Droogans
fonte

Respostas:

23

Imediatamente.

A chave é a questão de qual é a política para o Mestre. Com o git, normalmente, a política de ramificação no Master é a versão estável edificável . Às vezes, o Master é a 'linha principal' da qual as ramificações são feitas e mescladas antes da fusão para uma ramificação Release. Essas são duas abordagens diferentes de papel / política.

Muitas vezes, é uma fonte de erros para as pessoas mudarem a função ou a política de uma filial no meio do projeto. É mais fácil para um desenvolvedor solo comunicar essas alterações aos colaboradores, mas tentando fazer com que uma dúzia de programadores reconheça "O Master está agora na versão 1.0, por favor, ramifique os recursos em vez de todos os que estão pressionando"

Eu toquei na abordagem política acima. A política do Master é que seja a versão estável edificável . Verificando em pequenas mudanças incrementais em isso significa que você não tem algo edificável estável em todos os momentos. Não fazer check-in de pequenas alterações vai contra os "lotes de check-ins pequenos (mas completos)" que tendem a ser a melhor política (e incentivada pela fácil ramificação).

De uma perspectiva baseada em funções, você começou com o mestre como funções de linha principal, liberação, manutenção e desenvolvimento e, em seguida, alguns apontam no caminho que a função de desenvolvimento e manutenção se move para as filiais. Isso novamente significa uma mudança no que é permitido no mestre e pode confundir os contribuidores quanto a onde as coisas pertencem. Também pode (um pouco) confundir o histórico da ramificação, incentivando grandes compromissos que significam maior e mais difícil de entender mesclagens.

Chave os papéis e políticas nas filiais simples e consistentes desde o início.

Esse "ramo da mudança de política" pode ser visto nos Padrões de ramificação . A ideia de cada ramo ter funções pode ser lida em Estratégias avançadas de ramificação do SCM . Ambas são leituras muito boas.


fonte
3
Concordo principalmente com isso, mas eu não diria apenas edificável , diria liberável (estável). O mestre não deve conter código que apenas cria, deve conter código que foi realmente testado completamente. Você deve conseguir sair do mestre a qualquer momento, confiante no conhecimento de que não haverá defeitos graves.
Aaronaught
Concordo plenamente com Aaronaught, já que o IMHO é perfeitamente possível (e melhor prática) trabalhar de uma maneira em que o passo de um estado edificável para o próximo seja sempre apenas uma pequena mudança incremental, nunca uma grande.
Doc Brown
1
@MichaelT Eu já vi ramos 'dev' muitas vezes, mas nunca os ouvi explicados no contexto de um "mestre anterior" antes. Eu acho que vou usar isso, obrigado.
Droogans
13

Existem principalmente duas situações em que você normalmente deseja começar a trabalhar com ramificações:

  • quando você ou sua equipe tiver que iniciar um novo recurso que tenha a menor chance de não ser adicionado ao próximo lançamento (que pode ser o primeiro lançamento), inicie o desenvolvimento em um ramo de recurso separado

  • quando você precisar fornecer correções para erros graves na versão mais recente e desejar criar uma nova versão de correção de bugs que contenha apenas essas correções, mas nenhum recurso recém-desenvolvido (e provavelmente instável)

Para esse tipo de decisão, acho útil pensar sempre em termos de "novos recursos" ou "correções de bugs", a partir do ponto em que você tem uma primeira versão compilável / executável do seu programa.

Michael Feathers lista quatro razões para mudar em seu famoso livro, mas eu colocaria "otimizar recursos" em "ramo de novos recursos" (para um recurso não funcional) e "melhorar o design" na maioria das vezes em "ramo de novos recursos" também , uma vez que o IMHO nunca deve melhorar o design quando isso não se destina ao objetivo de facilitar a implementação de um recurso específico .

Doc Brown
fonte
12

Se você segue o git-flow - e, francamente, acho que você é louco se usa o Git e não usa esse modelo de ramificação -, nunca deve se comprometer masteraté estar pronto para um lançamento público.

Seu primeiro commit masterdeve ser um repositório vazio. Seu próximo commit masterdeve ser um commit de mesclagem da developramificação ou uma ramificação de liberação temporária e deve ser estável, testado e pronto para implantação (se for um aplicativo) ou distribuição pública (se for uma biblioteca).

Não são os outros modelos de ramificação para Git, mas a maioria deles são derivados de modelos de SCM centralizado mais velhos e pode levar a sérios problemas em um ambiente DVCS. Você não tem que realmente usar a extensão git-flow, e você não precisa necessariamente todos esses ramos / correcção / característica autorização, mas o esqueleto é develope mastere código instável entra develop.

Aaronaught
fonte
Você nem precisa se comprometer primeiro master. Lembre-se de que masternão há nada de especial no git, não precisa estar lá. Você pode apenas ter uma ramificação de desenvolvimento até desejar fazer um lançamento.
Miles Rout
2
@MilesRout: Embora isso seja verdade em princípio, você não pode mesclar a menos que a ramificação já exista, e o processo determina que todo commit no master deve ser uma mesclagem sem avanço rápido. A menos que eu esteja perdendo alguma coisa, a única alternativa para uma confirmação vazia inicial seria ramificar o mestre de alguma confirmação arbitrária de desenvolvimento ou liberação, o que significaria que eles compartilhariam o mesmo commit, o que você deveria evitar.
Aaronaught 16/01
1
Ah, esse é realmente um bom argumento. +1 para postar e comentar.
Route de milhas
1

Neal Ford, da Thoughtworks, defende o uso de recursos que alternam entre ramificações para evitar o problema do "inferno da mesclagem". Considere o caso em que dois programadores se fundem diariamente a partir do ramo principal e um deles faz alterações consideráveis ​​ao longo de algumas semanas e depois confirma. O outro programador poderia muito bem acabar no inferno da mesclagem. Para evitar esse problema, a Ford recomenda "levar a dor adiante" (um atributo ágil bem conhecido), tendo apenas um ramo e comprometendo-se diariamente. Recurso adicional é adicionado através de alternância de recurso que desativa o recurso até que seja totalmente testado.

Essa metodologia parece funcionar melhor em um ambiente que implementa a entrega contínua, pois os problemas com uma confirmação seriam capturados imediatamente.

Steve Emmerson
fonte
1

Faz dois anos desde a última resposta a essa pergunta e acho que agora a história muda. Para mim, a resposta é "Sempre que você usa o controle do código-fonte para rastrear versões".

Para elaborar, hoje em dia, o rastreamento de versões de projetos com controle de código-fonte nem sempre funciona. (por exemplo, usando o npm para gerenciar a dependência e especificar versões semânticas com '^'). Nesse caso, os artefatos do projeto mudam toda vez que uma construção acontece, não sendo necessário corresponder às alterações do código-fonte todas as vezes. Para lidar com esse tipo de novos desafios, algumas equipes optam por já criar 'artefatos' salvos no sistema de controle de artefatos (por exemplo, JFrog Artifactory) para acompanhar as versões do projeto.

Obviamente, quando você já possui o controle de versão de artefatos no lugar, não extrairia 'código de produção' de uma ramificação GIT e construiria / implementaria na produção; em vez disso, consulte o sistema de controle de artefatos para obter versões executáveis ​​diretamente para implantação. Nesses casos, o conceito de "ramo de liberação" repentinamente perde seu significado. E sempre que sua equipe decide não associar git branch à versão de lançamento, comprometer / pressionar diretamente para dominar se torna uma boa escolha mais uma vez: ele vem como ramo padrão sempre que o repo é clonado, portanto, automaticamente, dada a semântica amplamente aceita e bem comunicada alterar. Ainda assim, como a resposta aceita sugere, você provavelmente deve chefiar uma função de atribuição a ramificações, incluindo mestre, e usá-las apenas para essas funções específicas.

Por fim, vou um passo adiante e sugiro usar o mestre como ramo de desenvolvimento em projetos com apenas alguns dos principais committers. Qual é o caso da minha equipe e provavelmente o mesmo para a maioria das lojas de micro-serviços. A confirmação no mestre remove o processo de comunicação das alterações e potencialmente evita o 'inferno de mesclagem' ao trabalhar em recursos em vários sprints. Além disso, o código no ramo mestre nem precisa 'trabalhar', o processo automatizado de compilação / teste dirá o que deu errado e, de qualquer forma, é fácil verificar o histórico do git e entrar em contato com o autor que quebrou a compilação / teste :-)

Shawn
fonte
0

Vou tomar uma posição radical: ramifique todas as idéias. Primeiro, nas filiais git são baratas, o principal custo de uma filial é lembrar para que serve. Também concordo que o primeiro commit no domínio é um candidato a lançamento. Eu recomendo começar com uma prova de conceito. Quando você provar seu conceito, poderá fundi-lo com seu ramo de desenvolvimento vazio ou reescrever, dependendo de quão boa é sua primeira tentativa. a partir deste ponto, você se ramifica do desenvolvimento para cada bug, recurso, abstração etc.

hildred
fonte