O que devo fazer quando já esperei demais entre commits?

98

Eu era desobediente ... Muito "codificação cowboy", não o suficiente para se comprometer. Agora, aqui estou eu com um enorme commit. Sim, eu deveria estar me comprometendo o tempo todo, mas agora é tarde demais.

O que é melhor?

  1. Faça uma inscrição muito grande listando todas as coisas que alterei
  2. Tente dividi-lo em confirmações menores que provavelmente não serão compiladas, pois os arquivos possuem várias correções, alterações, nomes de métodos adicionais etc.
  3. Tente fazer reversões parciais de arquivos apenas para confirmações apropriadas e, em seguida, coloque as novas alterações de volta.

Nota: a partir de agora eu sou o único programador trabalhando neste projeto; a única pessoa que vai olhar para qualquer um desses comentários de commit é eu, pelo menos até contratarmos mais programadores.

A propósito: estou usando SVN e Subclipse. Eu criei uma nova ramificação antes de fazer qualquer uma dessas alterações.

Mais informações : Eu fiz uma pergunta separada relacionada a como cheguei a essa situação, em primeiro lugar: Como se preparar para reescrever a cola de uma aplicação

    
por durron597 27.02.2014 / 15:52
fonte

10 respostas

52

Para responder, você deve se perguntar como espera usar os resultados desses commits no futuro. Os motivos mais comuns são:

  • Para ver qual release um bug foi introduzido.
  • Para ver por que uma determinada linha de código está presente.
  • Para mesclar em outro ramo.
  • Para poder verificar uma versão anterior para solucionar um problema que um cliente ou testador está vendo nessa versão.
  • Para incluir ou excluir determinadas partes de um lançamento.

As duas primeiras razões podem ser atendidas com apenas um grande check-in, supondo que você possa criar uma mensagem de check-in que se aplique igualmente bem a cada linha de código alterado. Se você for o único programador, os commits menores não facilitarão sua integração. Se você não planeja fazer um lançamento ou teste com apenas parte de suas alterações não enviadas, as duas últimas razões não se aplicam.

Existem outras razões para fazer pequenos commits, mas são para enquanto você está no meio das mudanças, e esse tempo passou. Essas razões estão tornando mais fácil retroceder um erro ou uma mudança experimental, e é mais fácil manter a sincronização com colegas sem grandes fusões assustadoras.

Da minha compreensão de sua situação como você descreveu, parece que há pouco ou nenhum benefício em dividir seu commit neste momento.

    
por 27.02.2014 / 18:20
fonte
39

Acho que o que você fizer, tentar evitar o código que você conhece não compilará.

Se você acha que sua terceira opção é viável, isso pode ser uma boa maneira de fazê-lo, contanto que você possa garantir que sua sequência de commits não crie um sistema não-compensável. Caso contrário, apenas faça o commit grande. É feio, mas é simples, rápido e funciona. No futuro, cometer mais frequentemente .

    
por 27.02.2014 / 16:02
fonte
18

A razão mais importante para fazer commits frequentes, pequenos e significativos é ajudar na compreensão da história do código. Em particular, é muito difícil entender como o código mudou se for difícil gerar diffs compreensíveis.

A opção 1 ofusca o histórico de alterações feitas, mas, caso contrário, não causará problemas.

A opção 2 ofusca o histórico de alterações que você fez, possivelmente um pouco menos que a opção 1, mas pode causar outros problemas para você ou para os outros se eles assumirem ou concluírem que os commits são distintos , por exemplo pode ser mesclado em outros ramos de forma independente. A menos que exista uma strong razão prática para que isso seja preferível à opção 1, isso é menos ideal do que isso.

A

Opção 3 é a melhor, sendo tudo o mais igual, mas se, como você descreveu em outro lugar, isso exigir tempo "extremo" ou incorrer em outros custos significativos, você tem que pesar esses custos contra os benefícios esperados de criar commits mais limpos.

Com base nas informações que você forneceu, eu optaria pela opção 1. Talvez você devesse configurar lembretes solicitando que você confirmasse suas alterações?

Prototipagem e Reescrita

Outra consideração a ter em mente, especialmente à luz da sua nota sobre ser o único programador, e minha suspeita de que você está trabalhando em uma base de código relativamente nova, é que provavelmente é bom desenvolver hábitos diferentes no que diz respeito a alterações para quando você está criando um novo código versus mantendo ou estendendo o código existente. Provavelmente não há uma divisão terrivelmente nítida entre os dois, mas acho que ainda é uma distinção útil.

Ao criar um novo código para protótipo, confirme sempre que quiser salvar suas alterações, quase certamente em uma ramificação, mas talvez em um projeto separado. Ou talvez até mesmo trabalhe fora do controle de versão. Você pode se concentrar em reunir evidências sobre a viabilidade de várias hipóteses ou projetos que você está considerando. Costumo escrever pequenos protótipos usando ferramentas diferentes, por exemplo LINQPad em vez do Visual Studio para código C #.

Quando você validar uma hipótese ou design específico, reescreva-a em seu projeto principal, idealmente em uma ramificação, e faça os pequenos e significativos commits que melhor ajudarão a entender os outros (incluindo você no futuro) quanto à natureza das alterações que você está fazendo.

    
por 27.02.2014 / 18:46
fonte
12

Embora a única resposta razoável seja nunca quebre o tronco , algumas vezes isso não é possível. Por exemplo, o svn pode quebrar o commit se você cometer muito (talvez uma opção ou um recurso, não tenho certeza). Em casos especiais, basta fazer o check-in em pedaços. Desde que você é um único programador, não vai incomodar ninguém.

Portanto, eu escolheria a opção 1. Se não for possível, a opção 2.

A opção 3 requer muito esforço e simplesmente não vale a pena.

    
por 27.02.2014 / 16:10
fonte
7

Try to break it into smaller commits that likely won't compile, as files have multiple fixes, changes, additional method names, etc.

Quando me encontro em uma situação semelhante, usei a seguinte técnica:

  1. Adicione somente o código relevante para um recurso específico: git add --patch
  2. Ocultar todas as outras alterações: git stash save --keep-index
  3. Executar testes / tentar compilar
  4. Confirme as alterações se tudo estiver bem, se não for para 1

Não estou familiarizado com o SVN, por isso não sei se isso é aplicável à sua situação específica, mas a base deve ser a mesma: isole pequenas partes do código e teste-as individualmente.

    
por 27.02.2014 / 18:37
fonte
3

Como sobre a opção 4: Faça backup do estado atual de seu repositório em um local temporário, reverta seu repo para seu estado original, faça uma lista de todas as alterações feitas (ainda é possível ver o backup temporário) e reimplementar manualmente (e compile e teste!) como commits separados.

Isso deve ser mais fácil, porque você já escreveu o código, é apenas um pouco de descobrir quais partes copiar e colar do seu backup temporário.

Quando você reimplanta todas as alterações de forma limpa e, portanto, garante que as confirmações sejam independentes, pequenas e compilar, você pode excluir o backup temporário e tudo será quase exatamente como (exceto a data / hora de commits) teria sido se você fez isso desde o início.

    
por 27.02.2014 / 20:36
fonte
3

Você é o único programador; basta fazer um único checkin massivo detalhando os bits importantes do que você fez.

Você provavelmente reverterá "partes" do que fez? Se não, então continue com a opção 1.

Existem alguns motivos para verificar o código em um sistema de controle de versão. E todos eles, quando você é o único desenvolvedor, giram em torno da segurança - ou seja, se você estragar tudo, a máquina morrer ou qualquer outra coisa, você sempre poderá voltar ao último ponto de verificação.

É improvável que um programador que entra no projeto mais tarde queira reverter para uma versão que não é compilada. Então, IMHO, a opção 2 é loucura.

A opção 3 soa como uma perda de tempo, que se eu fosse seu chefe e visse você desperdiçando horas fazendo isso, eu teria uma pequena conversa com você sobre o que seu tempo vale a pena.

Para iterar: ao fazer o check-in do seu código, você está cobrindo / salvando seu bumbum em caso de falha em sua máquina. Tudo o mais, em uma equipe de um homem só, é fachada.

    
por 28.02.2014 / 00:28
fonte
2

Minha regra é: nenhum check-in sem uma revisão de código séria. Se eu estiver sozinho, terei que revisar o código por mim mesmo, mas será revisto em . Você parece ter uma quantidade de alterações de código que outra pessoa não pôde revisar, portanto você não pode revisá-la por si mesmo (revisar seu próprio código é mais difícil e requer mais disciplina, porque você faz a suposição errada de que seu próprio código está correto ).

A regra totalmente inquebrável de todo mundo é: nunca registre o código que nem mesmo compila, e evite seriamente checar o código que não funciona.

Solução: Copie seu código alterado, volte ao ponto original. Mesclar uma mudança por vez no código original, revê-lo, testá-lo, check-in. Com o método de programação que você descreveu, você é obrigado a encontrar alguns erros graves dessa maneira.

É também uma boa maneira de treinar bons hábitos de programação.

    
por 28.02.2014 / 11:08
fonte
1

Eu acho que você está se preocupando demais. Se você é o único programador e não tem uma folha de especificações para trabalhar, então depende inteiramente de você o que você faz. Eu suponho que ninguém vai te punir por fazer um grande commit, então os únicos problemas que você vai encontrar são tecnológicos, como não ser capaz de reverter alterações de arquivos individuais dentro do commit. Já que você está apenas no controle do repo neste momento, isso também não deve ser uma grande preocupação.

Há uma linha a ser traçada entre o pragmatismo e o dogmatismo. O que você fez não seria uma boa ideia em uma equipe e provavelmente não deveria ser repetido daqui para frente, mas na sua situação eu apenas enviaria o commit grande.

    
por 28.02.2014 / 11:35
fonte
-1

O problema não está em longos atrasos entre commits, mas no fato de você manter o código no estado uncompilable por muito tempo. Primeiro de tudo, qual é a sua definição de "longo"? Para algumas pessoas, 5 minutos para o estado de transição é muito, mas alguns podem polir seu código por dias, mesmo sem tentar executar o compilador.

Na verdade, isso não importa - o que importa é que você perdeu o controle do seu código, o seu código se tornou incontrolável. Isso é normal, significa apenas que você tem dívida tecnológica e é hora de pensar em refatoração. Então você está frustrado? Seu código não compila, você nem tem testes unitários? Como você pode pensar em refatorar neste caso? Não se preocupe. Termine o seu "cowboy coding" e comece a limpá-lo. O ideal é tentar escrever alguns testes. Você não tem tempo para isso? Ok, comece com pequenas melhorias.

Algumas alterações não exigem testes. Altere o nome da variável para mais adequado, mova o código repetido para uma função separada, etc ... Você terá uma idéia melhor do seu código. Depois disso, você pode fazer mudanças maiores. Mais uma vez, tente escrever testes, se possível. Torne seu código gerenciável.

Depois disso, você verá que a próxima mudança não leva muito tempo (o que quer que isso signifique).

    
por 27.02.2014 / 16:34
fonte