Como faço para 'git fetch' e 'git merge' a partir de um branch de rastreamento remoto (como 'git pull')

111

Eu configurei alguns branches de rastreamento remoto no git, mas nunca consigo mesclá-los no branch local depois de atualizá-los com 'git fetch'.

Por exemplo, suponha que eu tenha um ramo remoto chamado 'outro-ramo'. Eu configurei isso localmente como um ramo de rastreamento usando

git branch --track an-other-branch origin/an-other-branch

Por enquanto, tudo bem. Mas se esse branch for atualizado (geralmente por mim movendo a máquina e fazendo commit dessa máquina), e eu quero atualizá-lo na máquina original, estou tendo problemas com buscar / mesclar:

git fetch origin an-other-branch
git merge origin/an-other-branch

Sempre que faço isso, recebo uma mensagem 'Já atualizado' e nada se mescla.

No entanto, um

git pull origin an-other-branch

sempre o atualiza como você esperava.

Além disso, executando git diff

git diff origin/an-other-branch

mostra que existem diferenças, então acho que minha sintaxe está errada.

O que estou fazendo de errado?

EDIT [2010-04-09]: Eu verifiquei algumas vezes e, definitivamente, não estou em um ramo diferente. Meu 'git fetch' seguido por um 'git merge' (como mostrado acima) deve fazer exatamente a mesma coisa que um git pull? Vou obter algum fluxo de trabalho mostrando os resultados de um status git etc.

Kaybenleroll
fonte

Respostas:

170

Você não busca um branch, você busca um controle remoto inteiro:

git fetch origin
git merge origin/an-other-branch
Gareth
fonte
8
Mais detalhes: git fetch origin an-other-brancharmazena a dica buscada FETCH_HEAD, mas não origin/an-other-branch(ou seja, o 'ramo de rastreamento remoto' usual). Então, pode-se fazer git fetch origin an-other-branch && git merge FETCH_HEAD, mas fazer como @Gareth diz é melhor (ou apenas use git pull ).
Chris Johnsen,
então, se origin tem 1000 branches, você teria um branch remoto para todos eles?
Gauthier
4
Certo. Se eu adicionar um repositório remoto com 1000 branches ao meu e perguntar quais branches o remoto tem, é muito melhor me dar todos os 1000
Gareth
irá git merge origin/an-other-branchmesclar origin/an-other-branchem todas as ramificações locais definidas para rastreá-lo? como posso mesclar em apenas uma filial local?
anfibiente
1
Então, o que git pull(sem argumentos) faz - qual branch ele mescla? Ele mescla o branch de rastreamento remoto correspondente ao branch atual ?
The Red Pea
69

Selecionando apenas um ramo: fetch/ merge vs. pull

As pessoas freqüentemente aconselham você a separar "buscar" de "mesclar". Eles dizem em vez disso:

    git pull remoteR branchB

faça isso:

    git fetch remoteR
    git merge remoteR branchB

O que eles não mencionam é que esse comando fetch irá, na verdade, buscar todos os branches do repositório remoto, o que não é o que esse comando pull faz. Se você tem milhares de branches no repositório remoto, mas não deseja ver todos eles, pode executar este comando obscuro:

    git fetch remoteR refs/heads/branchB:refs/remotes/remoteR/branchB
    git branch -a  # to verify
    git branch -t branchB remoteR/branchB

Claro, isso é ridiculamente difícil de lembrar, então se você realmente deseja evitar buscar todos os branches, é melhor alterá-lo .git/configconforme descrito no ProGit.

Hã?

A melhor explicação de tudo isso está no Capítulo 9-5 do ProGit, Git Internals - The Refspec ( ou via github ). Isso é incrivelmente difícil de encontrar pelo Google.

Primeiro, precisamos esclarecer algumas terminologias. Para o rastreamento de filial remota, normalmente existem 3 ramos diferentes a serem considerados:

  1. O branch no repo remoto: refs/heads/branchBdentro do outro repo
  2. Seu branch de rastreamento remoto : refs/remotes/remoteR/branchBem seu repo
  3. Seu próprio branch: refs/heads/branchBdentro de seu repo

Ramificações de rastreamento remoto (in refs/remotes) são somente leitura. Você não os modifica diretamente. Você modifica seu próprio branch e, em seguida, envia para o branch correspondente no repo remoto. O resultado não é refletido em seu refs/remotesaté depois de um puxão ou busca apropriado. Essa distinção foi difícil para mim entender nas páginas de manual do git, principalmente porque o branch local ( refs/heads/branchB) é dito para "rastrear" o branch de rastreamento remoto quando é .git/configdefinido branch.branchB.remote = remoteR.

Pense em 'refs' como ponteiros C ++. Fisicamente, eles são arquivos contendo resumos SHA, mas basicamente são apenas ponteiros para a árvore de commits. git fetchirá adicionar muitos nós à sua árvore de commit, mas como o git decide quais ponteiros mover é um pouco complicado.

Conforme mencionado em outra resposta , nenhum

    git pull remoteR branchB

nem

    git fetch remoteR branchB

iria se mover refs/remotes/branches/branchB, e o último certamente não pode se mover refs/heads/branchB. No entanto, ambos se movem FETCH_HEAD. (Você pode catusar qualquer um desses arquivos .git/para ver quando eles mudam.) E git mergeirá se referir a FETCH_HEAD, durante a configuração MERGE_ORIG, etc.

cdunn2001
fonte
1
Você está ciente de que seu link para o Git Internals é um link para esta mesma pergunta?
Shahbaz
9

Tem certeza de que está no local an-other-branchao mesclar?

git fetch origin an-other-branch
git checkout an-other-branch
git merge origin/an-other-branch

A outra explicação :

todas as alterações do branch que você está tentando mesclar já foram mescladas com o branch em que você está.
Mais especificamente, isso significa que o branch que você está tentando fundir é pai do seu branch atual

se você está à frente do repo remoto em um commit, é o repo remoto que está desatualizado, não você.

Mas, no seu caso, se git pullfuncionar, isso significa apenas que você não está no ramo certo.

VonC
fonte
3

Git pull é, na verdade, uma ferramenta de combinação: executa git fetch (obtendo as alterações) e git merge (mesclando-os com sua cópia atual)

Tem certeza de que está no branch correto?

RDL
fonte
Acho que o OP está em diff. ramo, acontece comigo.
Chaklader Asfak Arefe
1

estes são os comandos:

git fetch origin
git merge origin/somebranch somebranch

se você fizer isso na segunda linha:

git merge origin somebranch

ele tentará mesclar o master local em seu branch atual.

A questão, como eu entendi, era que você já buscou localmente e deseja agora mesclar seu branch com o mais recente do mesmo branch.

user1524957
fonte