Reestruturando ramificações remotas no Git

135

Estou usando um repositório Git intermediário para espelhar um repositório SVN remoto, no qual as pessoas podem clonar e trabalhar. O repositório intermediário tem sua ramificação principal rebatida todas as noites a partir do SVN upstream, e estamos trabalhando nas ramificações de recursos. Por exemplo:

remote:
  master

local:
  master
  feature

Posso enviar com êxito minha ramificação de recursos de volta ao controle remoto e terminar com o que espero:

remote:
  master
  feature

local:
  master
  feature

Em seguida, reconfiguro a ramificação para rastrear o controle remoto:

remote:
  master
  feature

local:
  master
  feature -> origin/feature

E está tudo bem. O que eu gostaria de fazer a partir daqui é refazer a ramificação do recurso para a ramificação mestre no controle remoto, mas eu gostaria de fazer isso na minha máquina local. Eu gostaria de poder fazer:

git checkout master
git pull
git checkout feature
git rebase master
git push origin feature

Para manter a ramificação do recurso remoto atualizada com o mestre remoto. No entanto, esse método faz com que o Git se queixe:

To <remote>
 ! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to '<remote>'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

git pullfaz o truque, mas causa uma consolidação de mesclagem que eu gostaria de evitar. Estou preocupado que a mensagem afirme feature -> featuremais do que feature -> origin/featureisso, mas isso pode ser apenas uma coisa de apresentação.

Estou perdendo alguma coisa, ou estou fazendo isso de maneira completamente errada? Não é essencial evitar fazer a rebase no servidor remoto, mas torna muito mais difícil corrigir conflitos de mesclagem da rebase.

kfb
fonte
Eu tive o mesmo problema. Eu queria iniciar um modelo de rebase de ramificação ( assim ). Então notei que cometi um erro: se você deseja fazer uma nova redefinição (você não deve enviar as alterações ao recurso remoto antes de fazer a redefinição para o master). Portanto, você compromete algum código no seu recurso. E agora você deseja enviá-lo para o seu recurso remoto. Antes que você faça isso: -Você deve buscar e puxar seu mestre, se precisar. -Você deve refazer o master se houver algumas alterações no master que você não possui em seu recurso. Agora você pode empurrar o recurso e não haverá problema.
21416 Markus

Respostas:

185

Tudo se resume a saber se o recurso é usado por uma pessoa ou se outros estão trabalhando com ele.

Você pode forçar o push após o rebase se for apenas você:

git push origin feature -f

No entanto, se outras pessoas estiverem trabalhando nisso, você deve mesclar e não se recuperar do mestre.

git merge master
git push origin feature

Isso garantirá que você tenha um histórico comum com as pessoas com quem está colaborando.

Em um nível diferente, você não deve fazer fusões inversas. O que você está fazendo é poluir o histórico de sua ramificação de recurso com outras confirmações que não pertencem à característica, dificultando o trabalho subseqüente com essa ramificação - reformulando ou não.

Este é o meu artigo sobre o assunto chamado ramificação por recurso .

Espero que isto ajude.

Adam Dymitruk
fonte
29
+1 para if others are working on it, you should merge and not rebase off of masterrebase deve ser usado apenas em filiais privadas.
Hendra Uzia 29/08/2012
6
alternativ para git push origin recurso -f você também pode eliminar o seu recurso remoto e função impulso novamente
Markus
2
A mesclagem do mestre em sua ramificação criará uma consolidação de mesclagem e causará conflitos com qualquer outra ramificação de recurso aberto do mestre depois que suas alterações forem enviadas.
Steven
+1 para git push origin feature -f. Em certos contextos, pode ser necessário realizar uma nova reformulação mesmo com ramificações remotas. O ponto crucial é saber o que você está fazendo. E devemos assumir que você pode excluir confirmações em repositório remoto.
26419 enagra
33

É bom que você tenha abordado esse assunto.

Essa é uma coisa / conceito importante no git que muitos usuários do git se beneficiariam com o conhecimento. O git rebase é uma ferramenta muito poderosa e permite que você esmague as confirmações em conjunto, remova as confirmações etc. Mas, como qualquer ferramenta poderosa, você basicamente precisa saber o que está fazendo ou algo pode dar realmente errado.

Quando você estiver trabalhando localmente e brincando com suas filiais locais, poderá fazer o que quiser, desde que não tenha enviado as alterações ao repositório central. Isso significa que você pode reescrever sua própria história, mas não outras. Brincando apenas com o material local, nada terá impacto em outros repositórios.

É por isso que é importante lembrar que, depois de enviar confirmações, você não deve recuperá-las posteriormente. A razão pela qual isso é importante é que outras pessoas podem extrair seus commits e basear o trabalho deles em suas contribuições para a base de código, e se você decidir posteriormente mover esse conteúdo de um lugar para outro (refazê-lo) e empurrá-los alterações, outras pessoas terão problemas e precisam refazer o código. Agora imagine que você tenha 1000 desenvolvedores :) Isso causa muitos retrabalhos desnecessários.

ralphtheninja
fonte
Voto
Powers
1
Atualizado meu idioma.
Ralphtheninja
5

Como você se reestruturou featureem cima do novo master, seu local featurenão é mais um avanço rápido origin/feature. Então, acho que é perfeitamente bom substituir a verificação de avanço rápido fazendo isso git push origin +feature. Você também pode especificar isso em sua configuração

git config remote.origin.push +refs/heads/feature:refs/heads/feature

Se outras pessoas trabalharem em cima disso origin/feature, elas serão perturbadas por esta atualização forçada. Você pode evitar isso mesclando o novo masterno em featurevez de rebasear. O resultado será realmente um avanço rápido.

Tilman Vogel
fonte
1

Você pode desativar a verificação (se tiver certeza de que sabe o que está fazendo) usando a --forceopção para git push.

Andrew Aylett
fonte
15
O problema é, eu não tenho certeza que eu realmente sei o que estou fazendo :)
KFB
@r_: Por favor, leia minha resposta. Ele pode ajudá-lo em sua compreensão do que você está fazendo :)
ralphtheninja