Como 'git pull' em um ramo que não é o atual?

126

Quando você executa git pullna masterramificação, ela geralmente é retirada origin/master. Estou em um ramo diferente chamado newbranch, mas preciso executar um comando que faça a git pullpartir de origin/masterpara dentro, mastermas não posso executar git checkoutpara alterar o ramo selecionado até que a solicitação seja concluída. Existe uma maneira de fazer isso?

Para fornecer alguns antecedentes, o repositório armazena um site. Fiz algumas alterações newbranche as implantei alternando o site para newbranch. Agora, essas alterações foram mescladas a montante na masterfilial, também estou tentando alternar o site para a masterfilial. Neste ponto, newbranche origin/mastersão idênticos, mas masterestão atrasados origin/mastere precisam ser atualizados. O problema é que, se eu fizer da maneira tradicional:

$ git checkout master
   # Uh oh, production website has now reverted back to old version in master
$ git pull
   # Website is now up to date again

Preciso fazer o mesmo que acima ( git checkout master && git pull), mas sem alterar o diretório de trabalho para uma revisão anterior durante o processo.

Malvineous
fonte
@phi: Eu não acho que funcionaria, porque estou dentro newbranche não há nada para esconder!
Malvineous
Eu clonava em um diretório novo, mesclava newbranch no master, mesclava o master novamente no newbranch e depois git pull de onde você está. Master e newbranch serão os mesmos.
aet
@ aet Ele poderia fazer isso agora em seu diretório atual, fazendo git fetch; git merge origin/masterde dentro newbranch. Não há benefício em clonar uma segunda cópia inteira do repositório.
meagar
3
estreitamente relacionado: stackoverflow.com/questions/3216360/…
Ciro Santilli escreveu:

Respostas:

5

Você tem uma árvore de trabalho na qual não quer tocar, então use outra. O clone é barato, foi criado para isso.

git fetch origin master       # nice linear tree
git clone . ../wip -b master  # wip's `origin/master` is my `master`
cd ../wip                     # .
git pull origin origin/master # merge origin's origin/master
git push origin master        # job's done, turn it in.
cd ../main
rm -rf ../wip                 # wip was pushed here, wip's done

git checkout master           # payload

O problema com todas as outras respostas aqui é que elas não funcionam. Se você precisar da mesclagem ou reorganização para a qual você possui a configuração pull, precisará de outra árvore de trabalho e do procedimento acima. Caso contrário, apenas git fetch; git checkout -B master origin/masterfará.

jthill
fonte
2
Ao executar, git checkout mastervocê fará o checkout do masterramo antigo porque não fez um git pullna mainpasta para sincronizá-lo com a origem / mestre. É isso que estou tentando evitar.
Malvineous
O checkout feito pelo clone é do antigo mestre, mas esse checkout está em um diretório que o servidor da web não está vendo. O checkout principal no final é do master totalmente mesclado que foi retirado do wip.
jthill
Na linha 6, você envia o mesclado (atualizado) de mastervolta para origin, mas não acredito que seu checkout final seja atualizado master. Não há git pullcomo atualizar a masterramificação no maindiretório, portanto, a menos que esteja faltando algo, seus comandos não são diferentes de apenas executar git checkout masterpor conta própria e obter a masterárvore antiga . Se você observar atentamente, não está executando nenhum comando no maindiretório que se comunica a montante (exceto a linha 1, que é executada antes de você fazer alterações no
repositório
bem, você pode experimentá-lo em um repositório de teste ou verificar os documentos de envio.
jthill
1
@jwg comparado com o que, por favor? Certifique-se de atender a todas as necessidades declaradas do OP.
jthill
163

Direto: Atualizando de uma ramificação remota para um mestre de ramificação atualmente sem check-out :

git fetch origin master:master

onde a origem é seu controle remoto e você está atualmente com check-out em algum ramo, por exemplo, dev .

Se você deseja atualizar sua ramificação atual, além da ramificação especificada de uma só vez:

git pull origin master:master
Martin Peter
fonte
4
Hm, parece que nem sempre funciona; Acabei de ser solicitado a mesclar com minha ramificação WIP.
Underscore_d
@underscore_d mesmo para mim.
Greg
1
Trabalhou para mim ... se ele pede para fundir então eu imagino que há mudanças em seu ramo que você está atualizando que não estão comprometidos com a origem
desnatado
2
Como é que isso deveria funcionar? Ele não funciona para mim, apenas tenta mesclar origem / mestre no meu ramo de check-out atualmente.
Mhogerheijde 26/03
3
Isso puxa o mestre para o ramo atual. Definitivamente, NÃO é isso que está sendo pedido. Se você alterar puxar para buscar, isso seria exatamente o que está sendo solicitado.
111118 Jeff Wolski
90

Isso é respondido aqui: Mesclar, atualizar e puxar ramificações do Git sem usar caixas

# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master

# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo
Thomas
fonte
2
É o melhor, pois trabalha com alterações locais não confirmadas.
Tomasz Gandor
2
Se você quiser apenas acompanhar as alterações mais recentes, faça git fetch origin master:master. git fetchpor si só presumiria que você pretendia atualizar o ramo atual e não outro ramo.
John Leidegren
2
Essa é a resposta mais simples e direta. Esta deve ser a resposta aceita IMO.
Keeve #
@ JohnLeidegren - exceto que nem sempre funciona como planejado. Consulte os comentários para stackoverflow.com/a/42902058/274579 answer.
ysap
22

Como se vê, a resposta é enganosamente simples:

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Isso permite que você atualize o masterramo sem mudar para ele até depois ele foi atualizado.

Malvineous
fonte
11
Isso não faz o que você perguntou como fazer.
jthill
Como o comentário acima diz, a pergunta que você acabou de fazer não é realmente a pergunta que você acabou de responder. Você deve atualizar sua pergunta para que seja menos especificamente sobre a mesclagem em uma ramificação sem fazer check-out e mais sobre como migrar diretamente para a versão mais recente de uma ramificação disponível em um controle remoto sem antes verificar a versão antiga.
meagar
1
É absolutamente a resposta que veio aqui à procura de :)
Sophistifunk
1
Não é o que o OP queria, mas me ajudou, para ser honesto.
Marcel Bro
1
@anoniim, não é o que o OP queria? Você quer dizer o OP que acabou de responder a esta pergunta?
smac89
12

Você está preocupado com algo que não pode ser corrigido, pois as operações do Git não são atômicas. Você sempre terá um furo no qual seu diretório de trabalho fica a meio caminho entre as ramificações, mesmo se você atualizar o mestre sem primeiro alternar para ele. É por isso que o Git não é uma ferramenta de implantação .

Como você não está realmente comprometendo o código em seu ambiente de produção (espero), na verdade, não é necessário fazer check-out de uma filial. Você pode simplesmente fazer um a git fetchpara atualizar suas referências remotas e, em seguida, git checkout origin/mastermover o diretório ativo diretamente para o commit atualmente apontado por origin/master. Isso colocará você em um estado principal desanexado, mas, novamente, como você não está enviando código, isso não importa.

Esse é o menor buraco que você terá, mas, como eu disse, ainda existe; checkoutnão é atômico.

magro
fonte
Entendo as limitações do uso do git para implantação, o problema é que o furo nesse caso terá minutos, em vez de menos de um segundo. Boa idéia sobre check-out origin/master, porém, que pode apenas fazer o truque.
Malvineous
O que torna o buraco "minutos" longo? Puxando dados pela rede? Basta fazer um git fetchantes de fazer qualquer outra coisa e tirar a transferência real dos dados.
meagar
Tem alguns minutos porque um arquivo (agora) não rastreado seria substituído por uma confirmação anterior. Então eu tenho que copiar o arquivo, fazer as coisas do git e colocá-lo de volta. Os 'minutos' vêm da minha velocidade de digitação. (Sim, eu poderia script, mas que era apenas para fazer um ponto que ter git fazer tudo em si é mais rápido.)
Malvineous
3

Você pode usar update-ref para isso:

git fetch
git update-ref refs/heads/master origin/master
git checkout master

Observe que isso descartaria quaisquer confirmações locais na ramificação principal. No seu caso, não haverá nenhum, então tudo bem. Para outras pessoas que tentam fazer isso onde há confirmações locais, acho que não é possível, pois a mesclagem só pode ser executada na ramificação atual.

Philip Beber
fonte
Isso seria equivalente a git branch --force master origin/master? Isso força o chefe local masterpara apontar para a cabeça de originsmaster
Keego
2

A solução da Malvineous funciona para mim

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Apenas em dar o erro


warning: not deleting branch 'master' that is not yet merged to
         'refs/remotes/origin/master', even though it is merged to HEAD.
error: The branch 'master' is not fully merged.
If you are sure you want to delete it, run 'git branch -D master'.

Então eu corro com a opção -D

obrigado

Sebastian Oscar Lopez
fonte
0

git fetch origin master:master

  • "Puxa" (na verdade, busca) master.
  • Se você tiver alterações masterque ainda não foram enviadas, origin/masterserá mesclado ao seu mestre.
  • Se houver conflitos de mesclagem, será necessário resolvê-los primeiro.
Luzian
fonte