Conheço algumas pessoas que usam git pull --rebase
por padrão e outras que insistem em nunca usá-lo. Acredito entender a diferença entre mesclar e rebasear, mas estou tentando colocar isso no contexto de git pull
. Trata-se de não querer ver muitas mensagens de confirmação de mesclagem ou existem outros problemas?
806
Respostas:
Você deve usar
git pull --rebase
quandoDe fato - por que não então? É mais claro e não impõe um agrupamento lógico em seus commits.
Ok, acho que precisa de alguns esclarecimentos. No Git, como você provavelmente sabe, você é incentivado a ramificar e mesclar. Sua ramificação local, na qual você puxa alterações, e ramificação remota são, na verdade, ramificações diferentes, e
git pull
é sobre como mesclá-las. É razoável, já que você pressiona com muita frequência e geralmente acumula várias alterações antes que elas constituam um recurso completo.No entanto, às vezes - por qualquer motivo - você acha que seria realmente melhor se esses dois - remotos e locais - fossem um ramo. Como no SVN. É aqui que
git pull --rebase
entra em jogo. Você não mescla mais - na verdade, confirma em cima da ramificação remota . É disso que se trata.Se é perigoso ou não, é se você está tratando a filial local e remota como algo inseparável. Às vezes, é razoável (quando suas alterações são pequenas ou se você está no início de um desenvolvimento robusto, quando mudanças importantes são trazidas por pequenas confirmações). Às vezes não é (quando você normalmente cria outro ramo, mas você fica com preguiça de fazer isso). Mas essa é uma pergunta diferente.
fonte
git config --global pull.rebase preserve
(preserve preserve, além de habilitar a refazer a refração, para tentar preservar mesclagens se você tiver feito localmente).Eu gostaria de fornecer uma perspectiva diferente sobre o que "git pull --rebase" realmente significa, porque às vezes parece se perder.
Se você já usou o Subversion (ou CVS), pode estar acostumado ao comportamento de "svn update". Se você tiver alterações a confirmar e a confirmação falhar porque as alterações foram feitas a montante, você "svn update". O Subversion prossegue mesclando alterações upstream com as suas, resultando potencialmente em conflitos.
O que o Subversion acabou de fazer foi essencialmente "pull --rebase". O ato de reformular suas alterações locais para que ele seja relativo à versão mais recente é a parte "rebasing" dela. Se você fez "svn diff" antes da falha na tentativa de confirmação e comparou o diff resultante com a saída de "svn diff" posteriormente, a diferença entre os dois diffs é o que a operação de rebasagem fez.
A principal diferença entre o Git e o Subversion, neste caso, é que no Subversion, "suas" alterações existem apenas como alterações não confirmadas na sua cópia de trabalho, enquanto no Git você tem confirmações reais localmente. Em outras palavras, no Git você bifurcou a história; sua história e a história a montante divergiram, mas você tem um ancestral em comum.
Na minha opinião, no caso normal de ter sua filial local simplesmente refletindo a filial upstream e desenvolvendo-a continuamente, a coisa certa a fazer é sempre "--rebase", porque é isso que você realmente está semanticamente fazendo . Você e outras pessoas estão cortando a história linear pretendida de um ramo. O fato de alguém ter empurrado um pouco antes da tentativa de empurrar é irrelevante e parece contraproducente para cada acidente de tempo resultar em mesclagens na história.
Se você realmente sente a necessidade de algo ser um ramo por qualquer motivo, essa é uma preocupação diferente na minha opinião. Mas, a menos que você tenha um desejo específico e ativo de representar suas alterações na forma de mesclagem, o comportamento padrão deve, na minha opinião, ser "git pull --rebase".
Por favor, considere outras pessoas que precisam observar e entender a história do seu projeto. Deseja que o histórico esteja repleto de centenas de fusões por todo o lado ou apenas algumas poucas fusões que representam fusões reais de esforços de desenvolvimento divergentes intencionais?
fonte
git config --global branch.autosetupmerge always
?Talvez a melhor maneira de explicar isso seja com um exemplo:
git checkout master && git pull
. O mestre já está atualizado.git checkout master && git pull
. O mestre já está atualizado.git merge topic-branch-A
git merge topic-branch-B
git push origin master
antes de Alicegit push origin master
, o que é rejeitado porque não é uma mesclagem de avanço rápido.git pull --rebase origin master
git push origin master
, e todo mundo fica feliz por não precisar ler um commit inútil de mesclagem quando olhar para os logs no futuro.Observe que o ramo específico que está sendo mesclado é irrelevante para o exemplo. O mestre neste exemplo poderia ser tão facilmente um ramo de lançamento ou um ramo de desenvolvimento. O ponto principal é que Alice e Bob estão mesclando simultaneamente suas ramificações locais em uma ramificação remota compartilhada.
fonte
git co master && git pull; git checkout topic-branch-A; git rebase master; git checkout master; git merge topic-branch-A; git push origin master
repetir se o esforço de alguém para dominar aconteceu antes do meu. Embora eu possa ver as vantagens sucintas em sua receita.Eu acho que você deve usar
git pull --rebase
ao colaborar com outras pessoas no mesmo ramo. Você está no seu trabalho → confirmar → trabalhar → ciclo de confirmação, e quando você decide enviar seu trabalho, seu envio é rejeitado, porque houve um trabalho paralelo no mesmo ramo. Neste ponto, eu sempre faço apull --rebase
. Não uso squash (para nivelar confirmações), mas me refiz para evitar as confirmações de mesclagem extras.À medida que seu conhecimento sobre o Git aumenta, você se vê muito mais histórico do que com qualquer outro sistema de controle de versão que eu usei. Se você tem uma tonelada de pequenas confirmações de mesclagem, é fácil perder o foco da imagem maior que está acontecendo em sua história.
Na verdade, essa é a única vez que refizo (*) e o restante do meu fluxo de trabalho é baseado em mesclagem. Mas, enquanto seus confirmadores mais frequentes fizerem isso, a história parecerá muito melhor no final.
(*) Enquanto ministrava um curso Git, um aluno me prendeu por isso, pois também defendia o rebasamento de ramos de recursos em determinadas circunstâncias. E ele havia lido esta resposta;) Esse rebote também é possível, mas sempre deve estar de acordo com um sistema pré-combinado / acordado e, como tal, não deve "sempre" ser aplicado. E naquela época eu normalmente também não
pull --rebase
, o que é a questão;)fonte
Eu não acho que haja uma razão para não usar
pull --rebase
- eu adicionei código ao Git especificamente para permitir que meugit pull
comando sempre se rebase contra confirmações upstream.Ao analisar a história, nunca é interessante saber quando o cara / garota que trabalha no recurso parou para sincronizar. Pode ser útil para o cara / moça enquanto ele estiver fazendo isso, mas
reflog
é para isso. É só adicionar ruído para todos os outros.fonte
pull --rebase
sempre deve ser usado, por que não opull
faz por padrão?.gitconfig
para fazer com que algumas das opções façam a coisa certa. Eu acho que o git rebase faz a coisa errada por padrão, assim como o git tag, etc ... Se você discorda, não precisa justificar sua opinião.master
, e se o ramo no qual você entrar ainda não for público (ainda). Se você puxa, por outro lado, de um ramo de recurso para omaster
local é mais o contrário: nunca há um motivo para usá-lo--rebase
, certo? Essa pode ser a razão pela qual não é padrão. Descobri que Rebases é como as mudanças devem passar do topo da hierarquia para baixo e mesclas são como elas fluem de volta para cima. derekgourlay.com/blog/git-when-to-merge-vs-when-to-rebaseApenas lembra-te:
Portanto, escolha a maneira como você deseja lidar com seu ramo.
É melhor você saber a diferença entre mesclar e refazer :)
fonte
Eu acho que tudo se resume a uma preferência pessoal.
Deseja ocultar seus erros bobos antes de fazer alterações? Se assim
git pull --rebase
for , é perfeito. Ele permite que você comprima mais tarde seus commits para alguns (ou um) commit. Se você tiver mesclagens no seu histórico (sem push), não é tão fácil fazer umgit rebase
posterior.Eu, pessoalmente, não me importo de publicar todos os meus erros bobos, por isso tenho a tendência de mesclar em vez de me refazer.
fonte
git pull --rebase
pode ocultar uma reescrita do histórico de um colaboradorgit push --force
. Eu recomendo usargit pull --rebase
apenas se você souber que esqueceu de enviar seus commit antes que alguém faça o mesmo.Se você não cometeu nada, mas seu espaço de trabalho não está limpo, pouco
git stash
antes de fazê-logit pull
. Dessa forma, você não reescreverá silenciosamente seu histórico (o que pode excluir silenciosamente parte do seu trabalho).fonte