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

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

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

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

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

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

Всякий раз, когда я это делаю, я получаю сообщение "Уже самое современное" и ничего не сливается.

Однако a

git pull origin an-other-branch

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

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

git diff origin/an-other-branch

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

Что я делаю неправильно?

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

Ответ 1

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

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

Ответ 2

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

Люди часто советуют вам отделять "выборку" от "слияния". Вместо этого они говорят:

    git pull remoteR branchB

сделайте следующее:

    git fetch remoteR
    git merge remoteR branchB

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

    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 разных ветки:

  • В ответ на удаленное репо: refs/heads/branchB внутри другого репо
  • Отслеживание удаленного отслеживания: refs/remotes/remoteR/branchB в вашем репо
  • Ваше собственное отделение: refs/heads/branchB внутри вашего репо

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

Подумайте о "refs" в качестве указателей С++. Физически это файлы, содержащие 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 и т.д.

Ответ 3

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

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

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

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

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

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

Ответ 4

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

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

Ответ 5

это команды:

git fetch origin
git merge origin/somebranch somebranch

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

git merge origin somebranch

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

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