Depois de usar Git por vários anos, eu encontrei-me gradualmente usando comandos Git cada vez mais avançados como parte do meu fluxo de trabalho diário. Logo depois de descobrir o rebase Git, rapidamente incorporei – o no meu fluxo de trabalho diário. Aqueles que estão familiarizados com o rebasing sabem quão poderosa é uma ferramenta, e quão tentador é usá-la o tempo todo. No entanto, logo descobri que o rebasing apresenta alguns desafios que não são óbvios quando você começa a fazê-lo. Antes de apresentá-los, vou recapitular rapidamente as diferenças entre a fusão e o rebasing.,
vamos primeiro considerar o exemplo básico onde você quer integrar um ramo de recurso com master. Ao fundir, criamos um novo commit g
que representa a junção entre os dois ramos. O grafo commit mostra claramente o que aconteceu, e podemos ver os contornos do grafo “train track” familiar do Git-repos maior.,
Alternatively, we could rebase before merging. The commits are removed and the feature
branch is reset to master
, after which the commits are re-applied on top of feature
., Os diffs destes commits re-aplicados são geralmente idênticos aos seus homólogos originais, mas eles têm commits pais diferentes, e, portanto, chaves SHA-1 diferentes.
Nós já mudou a base de consolidação de feature
de b
c
, literalmente re-baseando-se., Merging feature
to master
is now a fast-forward merge, because all commits on feature
are direct descendants of master
.
Compared to the merge approach, the resulting history is linear with no divergent branches., A legibilidade melhorada foi a razão pela qual eu preferia reajustar ramos antes de me fundir, e eu espero que este seja o caso para outros desenvolvedores também.no entanto, esta abordagem tem alguns desafios que podem não ser óbvios.
Considere o caso em que uma dependência que ainda está em uso no feature
foi removido no master
. Quando feature
está a ser remediado para master
, o primeiro commit re-aplicado irá quebrar a sua compilação, mas enquanto não houver conflitos de junção, o processo de rebase continuará ininterrupto., O erro do primeiro commit permanecerá presente em todos os commits subseqüentes, resultando em uma cadeia de commits quebrados.
Este erro só é descoberto após o processo de rebase ser terminado, e é normalmente corrigido aplicando um novo commit bugfix g
no topo.,
Se você não conseguir conflitos durante a realocação no entanto, o Git vai fazer uma pausa no conflitantes cometer, permitindo a você corrigir o conflito antes de prosseguir. Resolver conflitos no meio de rebocar uma longa cadeia de commits é muitas vezes confuso, difícil de acertar, e outra fonte de erros potenciais.introduzir erros é extra problemático quando acontece durante o ajuste., Desta forma, novos erros são introduzidos quando você reescreve a história, e eles podem disfarçar bugs genuínos que foram introduzidos quando a história foi escrita pela primeira vez. Em particular, isso fará com que seja mais difícil usar o Git bisect, possivelmente a ferramenta de depuração mais poderosa na caixa de ferramentas Git. Como exemplo, considere o seguinte ramo de recursos. Digamos que introduzimos um bug perto do fim do ramo.,
Você não pode descobrir esse bug até semanas depois que a agência foi intercalado master
. Para encontrar o commit que introduziu o bug, você pode ter que pesquisar através de dezenas ou centenas de commits., Este processo pode ser automatizado escrevendo um script que testa a presença do bug, e executando-o automaticamente através do Git bisect, usando o comando git bisect run <yourtest.sh>
.
Bisect irá realizar uma pesquisa de bissecção através do histórico, identificando o commit que introduziu o bug. No exemplo mostrado abaixo, ele consegue encontrar o primeiro commit defeituoso, uma vez que todos os commits quebrados contêm o bug real que estamos procurando.,
On the other hand, if we’ve introduced additional broken commits during rebasing (here, d
and e
), bisect will run into trouble., Neste caso, esperamos que o Git identifica cometer f
como o mau, mas erroneamente identifica d
em vez disso, pois contém algum outro erro que quebra o teste.
Este problema é maior do que pode parecer à primeira vista.por que usamos Git?, Porque é a nossa ferramenta mais importante para rastrear a fonte de bugs em nosso código. Git é a nossa rede de segurança. Ao refazermos, damos menos prioridade a esta questão, a favor do desejo de se conseguir uma história linear.
um tempo atrás, eu tive que bissectar através de várias centenas de commits para rastrear um bug em nosso sistema. O commit defeituoso foi localizado no meio de uma longa cadeia de commits que não compila, devido a um rebase defeituoso que um colega tinha realizado. Este erro desnecessário e totalmente evitável resultou em eu gastar quase um dia extra em rastrear o commit.,como podemos evitar estas correntes de commits quebrados durante o ajuste? Uma abordagem poderia ser deixar o processo de ajuste de bases terminar, testar o código para identificar quaisquer bugs, e voltar na história para corrigir os bugs onde eles foram introduzidos. Para este fim, poderíamos usar o ajuste interativo.
outra abordagem seria ter git pausa durante cada etapa do processo de ajuste de base, testar quaisquer bugs e corrigi-los imediatamente antes de prosseguir.
Este é um processo pesado e propenso a erros, e a única razão para fazê-lo seria conseguir um histórico linear. Existe uma maneira mais simples e melhor?,
Existe uma junção Git. É um processo simples, de um passo, onde todos os conflitos são resolvidos em um único commit. O commit resultante da fusão marca claramente o ponto de integração entre nossos ramos, e nossa história mostra o que realmente aconteceu, e quando aconteceu.a importância de manter a sua história verdadeira não deve ser subestimada. Ao refazeres, estás a mentir a ti próprio e à tua equipa. Você finge que os commits foram escritos hoje, quando na verdade foram escritos ontem, com base em outro commit., Tiraste os commits do contexto original, disfarçando o que realmente aconteceu. Tem a certeza que o código constrói? Você pode ter certeza de que as mensagens de commit ainda fazem sentido? Você pode acreditar que você está limpando e esclarecendo sua história, mas o resultado pode muito bem ser o oposto.
é impossível dizer que erros e desafios o futuro traz para a sua base de código. No entanto, você pode ter certeza de que uma história verdadeira será mais útil do que uma reescrita (ou falsa).