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

Я установил несколько веток удаленного отслеживания в 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 и т. Д.


person kaybenleroll    schedule 08.04.2010    source источник


Ответы (5)


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

git fetch origin
git merge origin/an-other-branch
person Gareth    schedule 08.04.2010
comment
Подробнее: 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). - person Chris Johnsen; 10.04.2010
comment
Итак, если у origin есть 1000 веток, вы бы сделали удаленную ветку для всех из них? - person Gauthier; 08.06.2010
comment
Конечно. Если я добавил к себе удаленный репозиторий с 1000 веток, и я спрашиваю, какие ветки есть у удаленного, то, черт возьми, лучше, дайте мне все 1000 - person Gareth; 11.06.2010
comment
будет git merge origin/an-other-branch объединить origin/an-other-branch со всеми локальными ветвями, которые настроены для его отслеживания? как я могу объединиться только в одну локальную ветку? - person amphibient; 04.02.2014
comment
Git только что-то объединит в вашу текущую проверенную ветку. В основном это связано с тем, что было бы сложно иметь дело с конфликтами в ветках, которые вы не проверяли. - person Gareth; 04.02.2014
comment
Итак, что делает git pull (без аргументов) - с какой веткой он объединяется? Объединяет ли он ветвь удаленного отслеживания, соответствующую ветке current? - person The Red Pea; 02.12.2015

Выбор только одной ветви: _1 _ / _ 2_ 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. - Refspec (или через github). Это невероятно сложно найти через Google.

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

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

Ветви удаленного отслеживания (в refs/remotes) доступны только для чтения. Вы не изменяете их напрямую. Вы изменяете свою собственную ветку, а затем нажимаете на соответствующую ветку в удаленном репо. Результат не будет отражен в вашем refs/remotes до тех пор, пока не будет выполнено соответствующее извлечение или выборка. Мне было трудно понять это различие из man-страниц git, в основном потому, что локальная ветвь (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, и т. Д.

person cdunn2001    schedule 17.01.2011
comment
Знаете ли вы, что ваша ссылка на Git Internals - это ссылка на тот же вопрос? - person Shahbaz; 11.11.2011

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

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

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

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

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

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

person VonC    schedule 08.04.2010

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

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

person RDL    schedule 08.04.2010
comment
Я думаю, что OP отличается. ветка, бывает у меня. - person Arefe; 23.05.2018

это команды:

git fetch origin
git merge origin/somebranch somebranch

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

git merge origin somebranch

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

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

person user1524957    schedule 21.07.2013