Deixe-me responder seus pontos direta e claramente:
Nosso problema é com sidebranches de longo prazo - do tipo em que você tem algumas pessoas trabalhando em uma sidebranch que se separa do master, desenvolvemos por alguns meses e, quando atingimos um marco, sincronizamos os dois.
Você geralmente não deseja deixar suas filiais sem sincronização por meses.
Sua ramificação de recurso ramificou-se de algo, dependendo do seu fluxo de trabalho; vamos chamá-lo master
por uma questão de simplicidade. Agora, sempre que você se comprometer com o domínio, você pode e deve git checkout long_running_feature ; git rebase master
. Isso significa que suas ramificações estão, por design, sempre sincronizadas.
git rebase
também é a coisa correta a fazer aqui. Não é um truque ou algo estranho ou perigoso, mas completamente natural. Você perde um pouco de informação, que é o "aniversário" do ramo de recursos, mas é isso. Se alguém achar que isso é importante, ele poderá ser fornecido salvando-o em outro lugar (no seu sistema de tickets ou, se a necessidade for grande, em um git tag
...).
Agora, IMHO, a maneira natural de lidar com isso é, esmagar o sidebranch em um único commit.
Não, você absolutamente não quer isso, deseja um commit de mesclagem. Uma consolidação de mesclagem também é uma "consolidação única". De alguma forma, ele não insere todas as confirmações individuais da ramificação "no" mestre. É um único commit com dois pais - a master
cabeça e a cabeça do ramo no momento da mesclagem.
Certifique-se de especificar a --no-ff
opção, é claro; mesclar sem --no-ff
deve, no seu cenário, ser estritamente proibido. Infelizmente, --no-ff
não é o padrão; mas acredito que há uma opção que você pode definir que o faça. Veja o git help merge
que --no-ff
faz (em resumo: ele ativa o comportamento que descrevi no parágrafo anterior), é crucial.
não estamos retroativamente lançando meses de desenvolvimento paralelo na história do mestre.
Absolutamente não - você nunca está despejando algo "na história" de algum ramo, especialmente não com um commit de mesclagem.
E se alguém precisar de uma melhor resolução para a história do sidebranch, bem, é claro que ainda está tudo lá - simplesmente não está no mestre, está no sidebranch.
Com um commit de mesclagem, ele ainda está lá. Não no mestre, mas no sidebranch, claramente visível como um dos pais da fusão, e mantida por toda a eternidade, como deveria ser.
Viu o que eu fiz? Todas as coisas que você descreve para o seu commit de squash estão ali com o --no-ff
commit de mesclagem .
Aqui está o problema: trabalho exclusivamente com a linha de comando, mas o resto da minha equipe usa o GUIS.
(Observação: também trabalho quase exclusivamente com a linha de comando (bem, isso é mentira, eu geralmente uso o emacs magit, mas isso é outra história - se eu não estiver em um local conveniente com a configuração individual do emacs, prefiro o comando linha também). Mas, por favor, faça um favor e tentar pelo menos git gui
uma vez. é por isso muito mais eficiente para escolher linhas, pedaços etc. para adicionar / ruína completa.)
E descobri que os GUIS não têm uma opção razoável para exibir o histórico de outros ramos.
Isso porque o que você está tentando fazer é totalmente contra o espírito de git
. git
constrói a partir do núcleo em um "gráfico acíclico direcionado", o que significa que muitas informações estão no relacionamento pai-filho de confirmações. E, para mesclagens, isso significa que a verdadeira mesclagem se compromete com dois pais e um filho. As GUIs de seus colegas ficarão bem assim que você usar os no-ff
commits de mesclagem.
Portanto, se você chegar a um commit de squash, dizendo "esse desenvolvimento compactado do ramo XYZ", é uma grande dor ver o que há em XYZ.
Sim, mas isso não é um problema da GUI, mas do squash commit. Usar uma abóbora significa deixar a cabeça do ramo do recurso pendente e criar uma confirmação totalmente nova master
. Isso quebra a estrutura em dois níveis, criando uma grande bagunça.
Então eles querem que essas grandes e longas sidebranches de desenvolvimento sejam mescladas, sempre com um commit de mesclagem.
E eles estão absolutamente certos. Mas eles não são "fundidos em ", eles estão apenas se fundiram. Uma mesclagem é uma coisa verdadeiramente equilibrada, não possui um lado preferido que é mesclado "no" outro ( git checkout A ; git merge B
é exatamente o mesmo que git checkout B ; git merge A
exceto por pequenas diferenças visuais, como as ramificações sendo trocadas git log
etc.).
Eles não querem nenhum histórico que não seja imediatamente acessível a partir da ramificação principal.
O que é completamente correto. No momento em que não há recursos unificados, você teria um único ramo master
com um histórico rico que encapsulava todas as linhas de confirmação de recursos que existiam, voltando ao git init
commit desde o início dos tempos (observe que eu especificamente evitei usar o termo " branches "na parte final desse parágrafo porque o histórico naquele momento não é mais" branches ", embora o gráfico de confirmação seja bastante ramificado).
Eu odeio essa ideia;
Então você sente um pouco de dor, já que está trabalhando contra a ferramenta que está usando. A git
abordagem é muito elegante e poderosa, especialmente na área de ramificação / fusão; se você fizer o que é correto (como mencionado acima, especialmente com --no-ff
), é aos trancos e barrancos superado por outras abordagens (por exemplo, a confusão do subversion de ter estruturas de diretórios paralelas para ramificações).
significa um emaranhado infindável e inevitável da história do desenvolvimento paralelo.
Sem fim, paralelo - sim.
Inavegável, emaranhado - não.
Mas não estou vendo que alternativa temos.
Por que não trabalhar como o inventor git
, seus colegas e o resto do mundo, todos os dias?
Temos alguma opção aqui além de mesclar constantemente sidebranches em master com commit de mesclagem? Ou existe uma razão pela qual o uso constante de consolidação de mesclagem não seja tão ruim quanto eu temo?
Nenhuma outra opção; não é tão ruim.