Estratégia para revisão de código antes da mesclagem para mestre das ramificações de recursos

22

Eu e minha equipe usamos ramos de recursos (com git). Gostaria de saber qual é a melhor estratégia para revisão de código antes de mesclar para dominar.

  1. Eu compro uma nova ramificação do master, vamos chamá-la fb_ # 1
  2. Eu cometo algumas vezes e do que quero mesclá-lo de volta ao master
  3. Antes de mesclar, alguém deve fazer uma revisão de código

Agora existem 2 possibilidades:

  1. I fundir mestre para fb_ # 1 ( não fb_ # 1 a master) para torná-lo como up-to-date possível
  2. Um companheiro de equipe revisa as mudanças entre o chefe principal e o chefe fb_ # 1
  3. Se fb_ # 1 estiver ok, mesclamos fb_ # 1 para dominar
  4. Prós: nenhum código obsoleto em revisão
  5. Contras: se outra pessoa mesclar algo entre "1". e "2." as alterações dele aparecem na revisão, embora pertençam a outra revisão.

  1. Um colega de equipe revisa as alterações entre o ponto de checkout (mestre da base de mesclagem git fb_ # 1) e fb_ # 1 head
  2. Prós: vemos exatamente o que foi alterado durante o trabalho no ramo de recursos
  3. Contras: algum código obsoleto pode aparecer na revisão.

Qual o caminho que você acha melhor e por quê ? Talvez haja outra abordagem mais adequada?

Andrzej Gis
fonte

Respostas:

9

Há uma variação da sua primeira opção:

  1. mesclar master para fb_ # 1 (não fb_ # 1 para master) para torná-lo o mais atualizado possível
  2. Um colega de equipe revisa as alterações entre o mestre no ponto em que você mesclou e o cabeçalho fb_ # 1
  3. Se fb_ # 1 estiver ok, mesclamos fb_ # 1 para dominar
  4. verificação rápida de que a mesclagem está ok

por exemplo.

... ma -- ... -- mm -- ... -- mf  <- master
      \            \         /
       f1 ... fn -- fm -----      <-- fb_#1

Onde:

  • ma é o ancestral do mestre e fb_ # 1.
  • fn é a última alteração no seu ramo
  • mm é o commit que era master / HEAD no momento em que você se fundiu ao seu ramo (dando fm ).

Portanto, você compara mm e fm em sua revisão inicial e depois verifica rapidamente após mesclar o mf para garantir que nada de significativo tenha mudado no mestre durante as etapas 1 a 3. Parece ter todos os profissionais e nenhum dos contras da revisão inicial.

Isso pressupõe que a revisão seja rápida em comparação com a frequência normal de alterações enviadas para o mestre, portanto, fm -> mf geralmente seria um avanço rápido.

Se não for esse o caso, por qualquer motivo, os contras passarão da revisão inicial para a revisão pós-mesclagem, e pode ser mais simples mesclar diretamente no mestre e fazer uma única revisão lá.

Sem utilidade
fonte
Como obtenho "o ponto que você mesclou"? O "cabeçote mestre da base de mesclagem do git" ficará bom ou mostrará o ponto de ramificação inicial?
Andrzej Gis 15/10
A menos que você deliberadamente atualize o mestre após a mesclagem, ele será apenas mestre.
Inútil
Sim, mas como chegar a esse ponto se alguém o atualizar?
Andrzej Gis
Quando você estiver no ramo fb, use git show HEAD. Como esse será o commit de mesclagem fm , ele listará os dois pais. Então, você tem o hash de mm . Alternativamente, você pode trivialmente ver o pai em gitkou qualquer outro navegador git
Useless
13

  • Você redefine a ramificação no mestre para atualizá-la e manter as alterações separadas.

    Isso cria um novo histórico do ramo. Serão novas revisões com novos IDs que terão o mesmo conteúdo, mas serão derivadas do mestre mais recente e não serão vinculadas às revisões antigas. As revisões antigas ainda estão acessíveis no "reflog" se você precisar consultá-las, por exemplo, porque você descobriu que cometeu um erro na resolução de conflitos. Além disso, eles são inúteis. Por padrão, o Git remove o reflog após 3 meses e descarta as revisões antigas.

  • Você usa o rebase interativo ( git rebase -ie git commit --amend) para reordenar, editar e limpar as alterações, para que cada uma faça uma alteração logicamente fechada.

    Isso cria novamente um novo histórico, desta vez com o benefício adicional de que você pode reestruturar as alterações para fazer mais sentido durante a revisão.

  • Prós:

    • nenhum código obsoleto em revisão
    • vemos exatamente o que foi alterado durante o trabalho no ramo de recursos
  • Contras:
    • um pouco mais de trabalho
    • você deve tomar cuidado para não refazer tudo o que já foi mesclado ou compartilhado e o destinatário não espera que ele seja rebobinado.

Normalmente, o trabalho extra significa que você deve revisar o código por conta própria primeiro e isso também trará muitos problemas.

É isso que o Linux e o Git fazem. E não é incomum ver séries de 20 a 25 patches sendo submetidas para revisão e reescritas várias vezes nesses projetos.

Na verdade, o Linux fez isso desde o início do projeto, quando o controle de versão escolhido era tarballs e patches. Quando muitos anos depois, Linus decidiu criar o git, foi o principal motivo para implementar o rebasecomando e sua variante interativa. Também por causa disso, o git tem uma noção separada de autor e committer . Autor é quem criou a revisão pela primeira vez e o responsável pela última vez que a tocou. Como no Linux e no Git os patches ainda são enviados por email, os dois quase nunca são a mesma pessoa.

Jan Hudec
fonte
1
+1 também o OP não perguntou sobre as próximas etapas, mas para colocar seu recurso no master, você pode usar um merge --no-ffque mostrará claramente essa ramificação no master em vez de o recurso desaparecer no restante dos commits
stijn
@stijn: --no-fftem suas vantagens e desvantagens. Pessoalmente, acho mais barulho do que qualquer coisa. YMMV.
Jan Hudec
Sim, é uma questão de preferência. Se o mestre normalmente é limpo e correto, não me importo que grandes recursos tenham uma 'bolha' separada. Se mestre é um já confusão, sem-ff só piora as coisas
stijn
Gostaria de poder aceitar o modo de uma resposta. Uma solução híbrida seria ideal. Usar rebase e comparar com o ponto de ramificação parece ser o melhor caminho a percorrer.
Andrzej Gis 17/10/2013
Segundo Con - Eu não acho que você pode fazer isso se você já compartilhou seu ramo com ninguém. Quando você reescreve o histórico, haverá inconsistências.
sixtyfootersdude
4

Na verdade, existe uma terceira possibilidade - e provavelmente muitas outras, uma vez que o GIT é mais uma implementação de uma estrutura de SCM do que uma implementação de uma metodologia de SCM. Essa terceira possibilidade é baseada rebase.

O rebasesubcomando GIT pega uma série de confirmações (normalmente do ponto de ramificação até a ponta do tópico topic) e as reproduz em outro lugar (normalmente na ponta do ramo de integração, por exemplo master). O rebasesubcomando produz novas confirmações, o que oferece a oportunidade de reorganizar as confirmações de uma forma que é mais fácil de revisar. Isso gera uma nova série de consolidação, semelhante ao que topiccostumava ser, mas aparecendo enraizada na parte superior do ramo de integração. Esse novo ramo ainda é chamado topicpelo GIT, para que a referência antiga seja descartada. Rotulo informalmente topic-0o estado original do seu ramo topic-1e assim por diante em várias refatorações.

Aqui está a minha sugestão para o seu topicramo:

  1. (Etapa opcional) Você reorganiza interativamente a ramificação do tópico topicem seu ponto de ramificação (consulte a --fixupopção paracommit e as opções -ie ), o que lhe dá a oportunidade de reescrever seus commits de uma maneira que seja mais fácil de revisar. Isso resulta em uma ramificação .--autosquashrebasetopic-1

  2. Você rebase sua ramificação de tópico na parte superior de sua ramificação de integração, é semelhante a uma mesclagem, mas "não polui" o histórico com uma mesclagem que é meramente um artefato de engenharia de software. Isso resulta em uma ramificação topic-2.

  3. Mandar topic-2 a um colega de equipe que o analise com a ponta do master.

  4. E se topic-2 estiver tudo bem, mescle-o para dominar.

NOTA As ramificações - nas quais ramificação se refere à árvore de confirmação - serão chamadas pelo GIT da mesma forma; portanto, no final do processo, apenas a ramificação terá topic-2um nome no GIT.

Prós:

  • Nenhum código obsoleto em revisão.
  • Não há comentários espúrios de "fusões estrangeiras" (o fenômeno que você descreveu em 1º).
  • Oportunidade de reescrever confirmações de maneira limpa.

Contras:

  • Em vez de um ramo topic-0, há três ramos artefatos topic-0, topic-1e topic-2que são criados na árvore de cometer. (Embora a qualquer momento, apenas um deles tenha um nome no GIT.)

No seu 1º cenário «se alguém mesclar algo entre" 1 ". e "2." »refere-se ao tempo decorrido entre a criação do ponto de ramificação e o horário em que você decide mesclar. Nesse cenário «se alguém mesclar algo entre" 1 ". e "2." »refere-se ao tempo decorrido entre o rebase e a mesclagem, que geralmente é muito curto. Assim, no cenário que forneço, você pode «bloquear» omaster ramificação pelo tempo da mesclagem sem perturbar significativamente o seu fluxo de trabalho, enquanto isso é impraticável no 1º cenário.

Se você estiver fazendo revisões sistemáticas de código, provavelmente é uma boa idéia reorganizar as confirmações de maneira adequada (etapa opcional).

Gerenciar os artefatos de ramificação intermediária apenas apresenta uma dificuldade se você os compartilhar entre repositórios.

Michael Le Barbier Grünewald
fonte
Não deve haver topic-0, topic-1e topic-2ramos. No segundo em que a recuperação é concluída, a versão anterior é irrelevante. Então tudo que haveria é topic@{1}, topic@{2}, topic@{yesterday}, topic@{3.days.ago}etc. para salvar sua bunda no caso de você achar que você ferrou resolução de conflitos na rebase.
Jan Hudec
Os três ramos existem, mas não têm nome (sem ref). Talvez eu deva enfatizar isso.
Michael Le Barbier Grünewald 15/10
As revisões existem e são apontadas por entradas de reflog. Mas como galhos, há apenas um topic. Porque branch no git é apenas o nome.
Jan Hudec
Como isso me salva de "fusões estrangeiras"? E se alguém se unir ao mestre depois que eu enviar o tópico 2 a um colega de equipe e que ele o revise na ponta do mestre?
Andrzej Gis 15/10
@JanHudec A qualquer momento, há apenas um ramo chamado topicno GIT, é sempre um dos ramos (um ramo como em cometer árvore, não como em referência GIT) I rotulados topic-0, topic-1, topic-2.
Michael Le Barbier Grünewald 15/10