Как выполнить git fetch и git merge из ветки удаленного отслеживания (например, git pull)

111

Я установил несколько веток удаленного отслеживания в git, но мне кажется, что я никогда не смогу объединить их в локальную ветку после того, как обновлю их с помощью «git fetch».

Например, предположим, что у меня есть удаленная ветка с именем «an-other-branch». Я установил это локально как ветку отслеживания, используя

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

Все идет нормально. Но если эта ветка обновляется (обычно я перемещаю машину и фиксирую ее с этой машины), и я хочу обновить ее на исходной машине, у меня возникают проблемы с выборкой / слиянием:

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

Каждый раз, когда я это делаю, я получаю сообщение «Уже обновлено», и ничего не сливается.

Однако

git pull origin an-other-branch

всегда обновляет его так, как вы ожидаете.

Кроме того, запуск git diff

git diff origin/an-other-branch

показывает, что есть различия, поэтому я думаю, что у меня неправильный синтаксис.

Что я делаю не так?

РЕДАКТИРОВАТЬ [2010-04-09]: я проверял пару раз, и я определенно не на другой ветке. Должен ли мой git fetch, за которым следует git merge (как показано выше), делать то же самое, что и git pull? Я получу рабочий процесс, показывающий результаты статуса git и т. Д.

кайбенлеролл
источник

Ответы:

170

Вы не получаете ветку, вы получаете весь пульт:

git fetch origin
git merge origin/an-other-branch
Гарет
источник
8
Дополнительные сведения: git fetch origin an-other-branchсохраняет полученную подсказку FETCH_HEAD, но не сохраняет origin/an-other-branch(то есть обычную «ветку удаленного отслеживания»). Таким образом, можно было бы сделать это git fetch origin an-other-branch && git merge FETCH_HEAD, но делать это так, как говорит @Gareth, лучше (или просто использовать git pull ).
Крис Джонсен
Итак, если у origin есть 1000 веток, вы бы сделали удаленную ветку для всех?
Готье
4
Конечно. Если я добавил к себе удаленный репозиторий с 1000 веток, и я спрашиваю, какие ветки у пульта дистанционного управления, черт возьми, лучше дать мне все 1000
Гарет
будет git merge origin/an-other-branchобъединяться со origin/an-other-branchвсеми локальными ветками, которые настроены для его отслеживания? как я могу объединиться только в одну локальную ветку?
амфибия
1
Итак, что делает git pull(без аргументов) - какую ветвь объединяет? Объединяет ли он ветвь удаленного отслеживания, соответствующую текущей ветке?
The Red Pea
69

Выбор только одной ветки: fetch/ merge vs. pull

Люди часто советуют отделить «получение» от «слияния». Вместо этого говорят:

    git pull remoteR branchB

сделай это:

    git fetch remoteR
    git merge remoteR branchB

Что они не упоминают, так это то, что такая команда выборки фактически извлекает все ветки из удаленного репо, что не является тем, что делает эта команда извлечения. Если у вас есть тысячи веток в удаленном репо, но вы не хотите видеть их все, вы можете запустить эту неясную команду:

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

Конечно, это до смешного сложно запомнить, поэтому, если вы действительно хотите избежать получения всех веток, лучше изменить ваш, .git/configкак описано в ProGit.

А?

Лучшее объяснение всего этого можно найти в главе 9-5 ProGit, Git Internals - The Refspec ( или через github ). Это невероятно сложно найти через Google.

Во-первых, нам нужно прояснить некоторую терминологию. При удаленном отслеживании ветвей, как правило, нужно знать 3 разных ветки:

  1. Филиал на удаленном репо: refs/heads/branchBвнутри другого репо
  2. Ваша ветка удаленного отслеживания : refs/remotes/remoteR/branchBв вашем репо
  3. Ваша собственная ветка: refs/heads/branchBвнутри вашего репо

Ветви удаленного отслеживания (in refs/remotes) доступны только для чтения. Вы не изменяете их напрямую. Вы изменяете свою собственную ветку, а затем нажимаете на соответствующую ветку в удаленном репо. Результат не отразится на вашем refs/remotesдо тех пор, пока не будет выполнено соответствующее извлечение или выборка. Мне было трудно понять это различие из man-страниц git, в основном потому, что local branch ( refs/heads/branchB), как говорят, «отслеживает» ветку удаленного отслеживания при .git/configопределении branch.branchB.remote = remoteR.

Думайте о «refs» как о указателях C ++. Физически это файлы, содержащие SHA-дайджесты, но в основном это просто указатели на дерево коммитов. git fetchдобавит много узлов в ваше дерево фиксации, но то, как git решает, какие указатели перемещать, немного сложно.

Как упоминалось в другом ответе , ни

    git pull remoteR branchB

ни

    git fetch remoteR branchB

будет двигаться refs/remotes/branches/branchB, а последний, конечно, не может двигаться refs/heads/branchB. Однако оба двигаются FETCH_HEAD. (Вы можете catвнутри любого из этих файлов .git/увидеть, когда они изменятся.) И git mergeбудет ссылаться на FETCH_HEAD, при настройке MERGE_ORIGи т. Д.

cdunn2001
источник
1
Знаете ли вы, что ваша ссылка на Git Internals - это ссылка на тот же вопрос?
Shahbaz
9

Вы уверены, что an-other-branchпри слиянии находитесь на локальном компьютере ?

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

Другое объяснение :

все изменения из ветки, которую вы пытаетесь объединить, уже были объединены с веткой, в которой вы сейчас находитесь.
В частности, это означает, что ветвь, которую вы пытаетесь объединить, является родительской для вашей текущей ветки.

если вы опережаете удаленное репо на одну фиксацию, это удаленное репо устарело, а не вы.

Но в вашем случае, если git pullработает, это просто означает, что вы не на правильной ветке.

VonC
источник
3

Git pull на самом деле является комбинированным инструментом: он запускает git fetch (получение изменений) и git merge (объединение их с вашей текущей копией)

Вы уверены, что находитесь в правильной ветке?

RDL
источник
Я думаю, что OP отличается. ветка, бывает у меня.
Чакладер Асфак Арефе
1

это команды:

git fetch origin
git merge origin/somebranch somebranch

если вы сделаете это во второй строке:

git merge origin somebranch

он попытается объединить локальный мастер в вашу текущую ветку.

Вопрос, насколько я понял, был ли вы уже загружены локально и хотите теперь объединить свою ветку с последней из той же ветки.

user1524957
источник