Recentemente, escrevi sobre este tópico:
Como mantemos este branch de recursos atualizado? Mesclar os commits upstream mais recentes é fácil, mas você deseja evitar a criação de um commit de mesclagem, já que isso não será apreciado quando for enviado para o upstream: você estará então efetivamente re-commitando as alterações upstream, e esses commits upstream receberão um novo hash ( à medida que ganham um novo pai). Isso é especialmente importante, pois esses commits mesclados seriam refletidos em sua solicitação de pull do GitHub quando você enviar essas atualizações para seu branch pessoal de recursos do GitHub (mesmo se você fizer isso depois de emitir a solicitação de pull).
É por isso que precisamos rebase em vez de mesclar:
git co devel #devel is ansible's HEAD aka "master" branch
git pull --rebase upstream devel
git co user-non-unique
git rebase devel
Tanto a opção rebase quanto o comando rebase para git manterão sua árvore limpa e evitarão commits de mesclagem. Mas tenha em mente que esses são seus primeiros commits (com os quais você emitiu sua primeira solicitação de pull) que estão sendo rebaseeados e que agora têm um novo hash de commit, que é diferente dos hashes originais que ainda estão em seu branch de repo remoto do github .
Agora, enviar essas atualizações para seu branch de recurso pessoal do GitHub falhará aqui, pois os dois branches são diferentes: a árvore do branch local e a árvore do branch remoto estão “fora de sincronia”, por causa desses hashes de commit diferentes. O Git lhe dirá para primeiro git pull --rebase
, depois empurre novamente, mas não será um simples envio rápido, pois seu histórico foi reescrito. Não faça isso!
O problema aqui é que você buscaria novamente seus primeiros commits alterados como estavam originalmente, e eles serão mesclados no topo de seu branch local. Por causa do estado fora de sincronia, esse pull não se aplica de forma limpa. Você terá um histórico quebrado onde seus commits aparecem duas vezes. Ao enviar tudo isso para o branch de recursos do GitHub, essas alterações serão refletidas na solicitação de pull original, que ficará muito, muito feia.
AFAIK, na verdade não existe uma solução totalmente limpa para isso. A melhor solução que encontrei é forçar o envio de seu branch local para o branch do GitHub (na verdade, forçando uma atualização não rápida):
Conforme git-push (1):
Update the origin repository’s remote branch with local branch, allowing non-fast-forward updates. This can leave unreferenced commits dangling in the origin repository.
Portanto, não puxe, apenas force o empurrão assim:
git push svg +user-non-unique
ou:
git push svg user-non-unique --force
Na verdade, isso irá sobrescrever seu branch remoto, com tudo em seu branch local. Os commits que estão no stream remoto (e causaram a falha) permanecerão lá, mas serão commits pendentes, que eventualmente serão deletados por git-gc (1). Nada demais.
Como eu disse, esta é AFAICS a solução mais limpa. A desvantagem disso é que seu PR será atualizado com os commits mais recentes, que terão uma data posterior, e podem aparecer fora de sincronia no histórico de comentários do PR. Não é um grande problema, mas pode ser potencialmente confuso.