É certo confirmar código não útil?

40

É uma boa idéia exigir a confirmação apenas do código ativo?

Esta confirmação não precisa deixar o repositório em um estado de trabalho como:

  • ... estamos nos estágios iniciais do projeto, o código ainda não é estável.
  • ... você é o único desenvolvedor do projeto. Você sabe por que as coisas não estão funcionando. Além disso, você não está parando o trabalho de ninguém, comprometendo o código quebrado.
  • ... o código atualmente não funciona. Nós vamos fazer uma grande mudança. Vamos nos comprometer, a fim de ter um ponto para reverter se as coisas ficarem feias.
  • ... a cadeia é longa, não há problema se houver código quebrado na ramificação local. Ou seja,

    1. ficheiros locais
    2. área de preparação
    3. confirma no ramo local
    4. confirma no ramo remoto de recursos pessoais
    5. mesclar com developramificação remota
    6. mesclar com masterramificação remota
    7. mesclar com releaseramificação remota
  • ... comprometer-se cedo, comprometer-se frequentemente.

Portanto, na pergunta acima vinculada, a maioria das respostas diz que a confirmação de código não compilável não é problema nas ramificações locais e de recursos. Por quê? Qual é o valor de um commit quebrado?


Adicionado: Existem alguns comentários altamente votados, dizendo que em um brach local pode-se fazer o que quiser. No entanto, não estou interessado no lado técnico da questão. Em vez disso, gostaria de aprender as melhores práticas - os hábitos, que as pessoas que trabalham muitos anos na indústria, têm mais produtivo.


Estou impressionado com a vasta quantidade de ótimas respostas! Eles me levaram à conclusão de que não sou adepto do uso de ramificações para organizar meu código.

Vorac
fonte
28
Nas filiais locais, tudo acontece. Confirme o que quiser. Apenas limpe antes de empurrar.
Joachim Sauer
@Joachim Sauer, estou perguntando sobre as melhores práticas e o raciocínio por trás delas, a fim de criar bons hábitos . Atualmente, eu frequentemente comprometo código quebrado. E reverter é um pesadelo, através das dezenas de confirmações nos últimos dois dias.
Vorac
9
se você desenvolver cada recurso em seu próprio ramo, em seguida, que a decisão é trivial: descartar o ramo, continuar a partir de um novo ramo criado no master atual
Joachim Sauer
11
a menos que você defina o que torna o commit "quebrado", é impossível responder com autoridade a essa pergunta. Veja também: Um programador deve corrigir a compilação com falha de outra pessoa?
gnat
11
"Por quê? Qual é o valor de um commit quebrado?" A capacidade de identificar um problema e testar várias resoluções diferentes, além de ser capaz de retornar com segurança ao problema que você sabia que tinha, em vez de um estado em que você tenha esse problema e talvez alguns novos também. .
Joshua Taylor

Respostas:

20

Uma das filosofias de ramificação (seção Desenvolvendo estratégia de ramificação e política de linha de código em estratégias avançadas de ramificação do SCM - também leia as práticas recomendadas do Perforce , é um pdf, mas entra em alguns outros detalhes) é que você ramifica na política de incompatabile.

Uma política de linha de código especifica o uso justo e check-ins permitidos para a linha de código e é o manual essencial do usuário para o SCM da linha de código. Por exemplo, a política de uma linha de código de desenvolvimento deve declarar que não é para lançamento; da mesma forma, a política de uma linha de código de lançamento deve limitar as alterações nas correções de erros aprovadas. A política também pode descrever como documentar as alterações que estão sendo registradas, que revisão é necessária, que teste é necessário e as expectativas de estabilidade da linha de codificação após os check-ins. Uma política é um componente crítico para um processo de desenvolvimento de software documentado e aplicável, e uma linha de código sem uma política, do ponto de vista do SCM, está fora de controle.

(das práticas recomendadas do Perforce)

Digamos que você possua as ramificações 'release' (ou 'master') a partir das quais uma versão é criada e 'trunk' (ou 'dev') onde os desenvolvedores verificam o código de funcionamento. Estas são as políticas dos ramos. Observando que o 'código de funcionamento' faz parte da política de ramificação 'dev', nunca se deve comprometer o código quebrado na ramificação dev. Muitas vezes, existem coisas como servidores de CI conectados a essas ramificações e o check-in de código quebrado no dev pode atrapalhar a ramificação de todos e interromper a construção.

No entanto, há momentos em que é apropriado fazer check-in de código parcial que não funciona. Nesses casos, deve-se ramificar - uma política incompatível com o tronco. Nesta nova ramificação, pode-se decidir a política ('código quebrado está ok') e depois confirmar o código.

Há uma regra simples para determinar se uma linha de código deve ser ramificada: ela deve ser ramificada quando seus usuários precisam de políticas de check-in diferentes. Por exemplo, um grupo de liberação de produto pode precisar de uma política de check-in que imponha testes rigorosos, enquanto uma equipe de desenvolvimento pode precisar de uma política que permita check-ins frequentes de alterações parcialmente testadas. Essa divergência de política exige uma ramificação da linha de código. Quando um grupo de desenvolvimento não deseja ver outro

(das práticas recomendadas do Perforce)

Perceba que isso é proveniente de um SCM baseado em servidor central com uma forte mentalidade corporativa. A idéia central ainda é boa. Isso geralmente é pensado implicitamente - você não faz o check-in de código de desenvolvimento não testado no ramo de lançamento. Isso é uma política.

Então, ramifique, diga que esse ramo pode ter código quebrado e se comprometer.


fonte
40

Uma das filosofias sugeridas por Linus Torvalds é que a programação criativa deve ser como uma série de experimentos. Você tem uma ideia e a segue. Nem sempre dá certo, mas pelo menos você tentou. Você deseja incentivar os desenvolvedores a tentar idéias criativas e, para fazer isso, deve ser barato tentar esse experimento e barato para se recuperar. Este é o verdadeiro poder do git se compromete a ser tão barato (rápido e fácil). Ele abre esse paradigma criativo que capacita os desenvolvedores a tentar algo que eles poderiam não ter. Essa é a libertação do git.

WarrenT
fonte
2
É realmente uma coisa bonita. Não acho que a comunidade tenha realmente aprendido a apreciar o git e o DVCS em geral.
ChaosPandion
5
Contanto que as pessoas não confundam essa filosofia com programação de tentativa e erro, o que deve ser evitado.
Pieter B
10

Sim, desde que não seja um ramo de lançamento.

Nos ramos pessoais, tudo acontece e pode ser descartado se o experimento não funcionar. Esse é um dos principais benefícios do DVCS: liberdade

O valor de confirmar código quebrado ?: colaboração e experimentação

dukeofgaming
fonte
Pequenos ajustes: Sim, desde que não seja executado na produção. Código oculto por um recurso de alternância, por exemplo.
Rob Crawford
5

Sim, está tudo bem e é algo que eu faço muito.

O objetivo de confirmar código não compilável (pelo menos em ramificações) é que às vezes seu código é um trabalho em andamento, mas que o trabalho realizado até agora vale a pena salvar e / ou compartilhar com outras pessoas

Minhas práticas são:

  • escreva testes primeiro
  • as confirmações wip (trabalho em andamento) são boas
  • confirmar com frequência (vários em um dia) e cedo (salvar as etapas de 'trabalho')
  • pressione após cada confirmação (no caso de seu disco rígido travar / o barramento bater em você).
  • sempre trabalhe primeiro nos galhos
  • quando possível, mesclar apenas o código de trabalho para dominar
  • rebase interativo no git para esmagar wips antes da mesclagem principal

A questão principal e talvez a que você está abordando é quando você tem um recurso que basicamente funciona e é extremamente necessário para a empresa (e, portanto, precisa estar no 'mestre'), mas tem alguns testes com falha. Uma opção aqui pode ser fazer um teste pendente que permite avançar por enquanto. No entanto, isso é repleto de perigos, pois o teste nunca pode ser corrigido e pode definir um padrão em outras áreas de testes "simplesmente pendentes" em vez de corrigi-los.

Outra opção seria usar e implantar temporariamente a filial. Isso pode ajudar em determinadas situações, mas geralmente não é recomendado e não é sustentável.

Talvez a melhor opção seja basicamente adotar uma abordagem mais profissional para o desenvolvimento de software e realmente exigir testes de trabalho para qualquer código comprometido. Essa é frequentemente a parte "difícil" do desenvolvimento de software, não a codificação que muitas pessoas imaginam. Uma abordagem melhor provavelmente exigirá melhores estimativas iniciais, alocação de recursos, definição de prioridades, etc. mais, durante o desenvolvimento Agile, permitindo tempo suficiente e usando disciplina suficiente para corrigir quaisquer problemas no momento em que ocorrem e durante as sessões de apontamento de aparência.

Concentre-se no que significa 'feito' - significa que o código E os testes foram escritos, foram refatorados e funcionam. Se você ouvir comentários como "feito principalmente, só precisa escrever / corrigir / refatorar testes, isso NÃO será feito. Dizer que um recurso é feito sem que seja tecnicamente completo é um dos erros mais comuns dos programadores juniores.

Michael Durrant
fonte
3

O valor de qualquer confirmação, quebrada ou não, é que o código é confirmado em um servidor. Em ambientes profissionais, esse servidor é seguro, redundante e em execução. Se eu trabalhar o dia inteiro, confirmar é uma forma de garantir que meu código sobreviva, aconteça o que acontecer à minha máquina local. Os discos rígidos morrem. Laptops são perdidos ou roubados. Os backups do servidor de repositório estarão disponíveis mesmo se o prédio queimar.

nvoigt
fonte
8
Isso não é necessariamente verdade para DVCSes. Por exemplo, se o seu repositório pessoal local ou filial de recurso for local, ele poderá ou não ser feito backup (e isso é especialmente verdade se você estiver trabalhando offline na rede corporativa sem acesso aos recursos da empresa). As ramificações mestre e de liberação devem estar em algum lugar com backup, mas isso não é necessariamente verdadeiro para uma ramificação local.
Thomas Owens
Mesmo nos DVCSes, um commit vale algo, pois o código é "mais permanente" que o dos arquivos. Pelo menos para git.
Joachim Sauer
3
@ThomasOwens, com todo o respeito, se o administrador do DVCS configurar seu sistema para que não haja backup dos repositórios ou filiais locais, o administrador do DVCS é um idiota e precisa encontrar um novo emprego mais adequado aos talentos dele ("Deseja frita com isso? "). Se o administrador do DVCS fez dessa maneira porque seus funcionários de TI disseram para ele, isso vale também para a sua organização de TI. De qualquer forma, isso é indiscutivelmente uma acusação de todo o conceito do DVCS: comprometer o código ao VCS POR DEFINIÇÃO significa comprometê-lo ao backup automático.
John R. Strohm
6
@ JohnR.Strohm Ao viajar, muitas vezes tenho acesso limitado à rede, portanto não tenho acesso a nenhum dos recursos de backup ou unidades de rede. Estou desenvolvendo sem backup até ter acesso a uma rede. Este é o objetivo de um DVCS - você não precisa da rede. O seu repo deve ser copiado? Provavelmente, mas é apenas um requisito para liberações ou repositórios mestre. Você realmente não deve passar dias entre enviar para um repositório de backup de qualquer maneira, mas esses pressupostos não devem ser um código quebrado.
Thomas Owens
11
@ThomasOwens meu argumento é que, embora seu acesso ao servidor de backup seja esporádico, o comprometimento com ele deve ser uma prioridade sobre o funcionamento do código. Você sempre pode fazer seu código funcionar em outra máquina, mesmo outras pessoas em sua equipe podem fazer o código funcionar em suas máquinas. Se estiver apenas na sua máquina, o cliente provavelmente não se importará se funcionar. O cliente cuida de uma nova liberação do servidor de construção que, por sua vez, extrai do repositório do servidor.
nvoigt
3

Pense nisso desta maneira. Como desenvolvedor, uma das coisas mais perturbadoras que você faz é impedir que outros desenvolvedores de sua equipe trabalhem em suas tarefas.

A filosofia de apenas confirmar código de trabalho vem de equipes de desenvolvimento que trabalham no mesmo tronco único no repositório. Pode parecer loucura agora, mas há 10 anos, essa era a maneira normal de trabalhar. Um ramo aparecia quando você queria criar uma versão estável, mas o pensamento de um desenvolvedor trabalhando em um ramo para implementar um novo recurso era quase inédito.

Se seu ambiente significa que suas confirmações não afetam imediatamente outros desenvolvedores, confirme com frequência. isso lhe dá mais segurança no seu código, facilitando a reversão de um erro de código e muitos sistemas de controle de origem oferecem alguma proteção ao código confirmado (embora nem todos).

Agora, certificando-se de que sua fusão com as ramificações compartilhadas com outros desenvolvedores funcione e que qualquer código que você promova para esse nível seja compilado, passe em todos os testes de unidade e outras verificações de sanidade em equipe ... isso é essencial se você não quiser continue comprando a cerveja no bar ...

Michael Shaw
fonte
3

Antes de começar a ser dogmático sobre como trabalhar com seu controle de versão, vale a pena pensar no motivo pelo qual você está trabalhando com o controle de versão.

A confirmação do controle de versão congela o estado do seu código para referência futura - tudo o resto fica fora disso. Analisar diffs e fazer patches é apenas ver como o código mudou entre os snapshots. Ramificações e tags são apenas formas de organizar instantâneos. Compartilhar código com outros desenvolvedores é apenas permitir que eles analisem um instantâneo específico.

Quando você deve cometer? Quando houver uma chance razoável, você analisará o estado do seu código (ou a mensagem de confirmação explicando uma alteração) no futuro.

O Git oferece muita flexibilidade para organizar seus snapshots. Não há repositório central para que você possa compartilhar seu código com outros desenvolvedores sem enviar seu estado ao repositório 'principal'. Você pode criar, mesclar e excluir ramificações facilmente para isolar os detalhes de um conjunto de estados da narrativa do código principal. Você pode confirmar localmente, para ajudá-lo a desfazer um acompanhamento do seu desenvolvimento atual e, em seguida, agrupar tudo em um único commit antes de enviá-lo para que outros o vejam. Você pode marcar revisões específicas para facilitar a localização posteriormente.

BEIJO . O que funciona melhor para um único desenvolvedor nos estágios iniciais do desenvolvimento de um pequeno projeto será completamente diferente do que você precisa fazer quando houver uma centena de desenvolvedores trabalhando em um sistema de missão crítica de uma década. Em qualquer processo de desenvolvimento de software, você deve evitar criar artefatos desnecessários simplesmente porque alguém lhe disse para fazê-lo.

Sean McSomething
fonte
Sua resposta é inspiradora, mas vaga para mim. Meu problema em questão é que eu crio (acho) muitos commits e, quando preciso reverter, não sei para onde, pois muitos deles não funcionam. O contexto é o desenvolvimento individual de uma equipe pequena de <5. Acho que estou levando muito longe a coisa "confirmar com frequência" e talvez precise recuperar. Como faço para confirmar, que terá uma mensagem de confirmação significativa?
Vorac
11
Se você achar que precisa se comprometer toda vez que compilar / testar, talvez seja necessário encontrar um editor melhor que lhe dê mais histórico de desfazer. Se você não conseguir escrever uma mensagem de confirmação que expresse significativamente suas alterações, não confirme.
Sean McSomething
Se você estiver com problemas para se lembrar de para qual compromisso voltar, não estará mesclando suas alterações com frequência suficiente. Mantenha um ramo "estável", um ramo "de desenvolvimento" e um ramo "experimental". Quando o código estiver funcionando, mescle suas alterações de "experimental" para "dev" (aperte seus commits primeiro) e sinta-se à vontade para interromper "experimental" sabendo que você pode excluí-lo e criar um novo ramo a partir de "dev". Após a conclusão de um recurso inteiro, mescle o dev para estável.
RubberDuck
2

Criar / liberar ramificações

Você nunca deve comprometer deliberadamente código quebrado em uma ramificação de construção. Qualquer ramificação que esteja sob integração contínua ou a partir da qual são feitas liberações ou compilações diárias deve sempre estar em um estado potencialmente liberável.

Outras ramificações: salvar estado frequentemente

Para filiais particulares ou de recursos, os objetivos geralmente são diferentes. O check-in frequente do código (funcionando ou não) pode ser desejável. Geralmente, você desejará confirmar a qualquer momento que precisar voltar ao estado atual.

Considere estes exemplos em que o estado salvo oferece um benefício significativo:

  • Você pode executar uma confirmação imediatamente antes de executar uma pesquisa e substituição global para poder reverter sua árvore em uma única operação, se algo der errado.
  • Você pode executar uma série de confirmações temporárias ao refatorar um pedaço complexo de código para poder dividir ou retroceder se acabar quebrando algo no processo.
  • Você pode executar uma confirmação, iniciar uma nova ramificação ou criar uma tag quando quiser tentar algo experimental enquanto conseguir retornar ao estado da árvore de trabalho atual a qualquer momento.
CodeGnome
fonte
0

Não há problema em comprometer uma base de código quebrada, desde que seja local.

Por quê?

  • É essencial usar a confirmação como um ponto de salvamento no seu desenvolvimento
  • Ele mostra um padrão de pensamento usado ao desenvolver o produto.
  • Não quebra a colaboração .

No entanto, quando há uma equipe de programadores, a filosofia da casa de programação é primordial e substitui os comportamentos de confirmação individuais. Algumas casas de programação decidem registrar todo o progresso, enquanto outras decidem apenas confirmar o código que resolve um recurso. Nesse caso, o valor ( custo , do ponto de vista do gerenciamento de software) de uma confirmação interrompida é terrível:

  1. o tempo usado para outros recursos agora é gasto corrigindo erros ...
  2. o corte de desenvolvimento não é atendido ...
  3. o produto não é enviado a tempo

Outros pontos podem ser adicionados a esses três efeitos cascateados exponencialmente em um colapso da empresa ... é claro, isso deve ser um efeito do comprometimento habitual crônico de códigos ruins.

iGbanam
fonte
0

Eu não acho que esteja certo cometer código quebrado.

O que acontece se

  • Uma correção urgente é necessária. A base de código está em um estado quebrado. Você é forçado a reverter, consertar e implantar.

  • Outra pessoa começa a trabalhar no mesmo ramo sem saber que você cometeu um código quebrado. Eles podem estar perseguindo um 'arenque vermelho' pensando que suas mudanças quebraram alguma coisa.

  • Você decide deixar a empresa, sair de férias ou não pode trabalhar por qualquer motivo. Seus colegas terão que se aprofundar para descobrir o que está quebrado e por que ele foi cometido em um estado quebrado.

  • Alguém implanta seu 'código quebrado'? Pode ser um fim de jogo, se você estiver trabalhando com dados pessoais ou em um provedor de pagamentos.

Responder para @WarrenT

Eu concordo com você que, em um mundo ideal, onde todos trabalham em uma ramificação de recursos, a confirmação de códigos não funcionais pode funcionar. Trabalhei em grandes projetos e, mesmo assim, houve casos em que várias pessoas tiveram que trabalhar em um único ramo de recursos. Também vi pessoas comprometendo o código 'não funcionando' com o ramo principal porque o lançamento estava a semanas e planejavam corrigi-lo no dia seguinte. Todas essas coisas são candidatas a um desastre e acredito firmemente que devem ser evitadas a todo custo.

CodeART
fonte
Voto negativo. Nenhum desses cenários é provável se você estiver usando um fluxo de trabalho DVCS padrão.
user16764
11
Com o fluxo de trabalho git (ou outro DVCS), os desenvolvedores estão trabalhando em ramificações, ramificações locais, NÃO no tronco principal. A próxima pergunta seria se um desenvolvedor enviasse código quebrado para outro repositório. É uma questão de uma equipe entender o que são os ramos para quê e usar bons comentários em seus commits. Uma correção automática seria feita apenas em uma ramificação de liberação. É claro que ninguém deveria fundir códigos quebrados lá. As equipes precisam ter regras sobre o fluxo de trabalho, mas o que é feito em um repositório local é uma questão totalmente diferente.
warrent
Eu acho que há uma diferença entre "código não útil" (o que o OP pediu) e "código quebrado" ao qual você se refere.
Simon
@ WarrenT Por favor, veja a resposta.
Codeart
-1

Algumas perguntas para ajudar você a determinar se não há problema em confirmar código não útil:

  1. Você está sendo sobrecarregado?
  2. Seus companheiros de equipe quebram constantemente a construção?
  3. Sua base de código está uma bagunça e aparentemente não pode ficar pior?

Se você disser sim a alguma das opções acima, sim, não há problema em confirmar um código não funcional.

Lembre-se de corrigi-lo o mais rápido possível, cubra-o com todos os testes de unidade aplicáveis ​​e peça desculpas por quebrar a compilação.

Rudolf Olah
fonte