Что действительно делает git fetch?

Теперь я хочу объединить удаленную ветвь, назвав ее origin/branch1 , с моей веткой branch1 , так как мой партнер нажал новую фиксацию на branch1 на удаленном компьютере после нашего последнего слияния, и я не совершал его с момента последнего коммита и хочу получить обновление от этой фиксации. Я использовал следующие команды:

 $ git fetch origin branch1 Compressing... *branch branch1 ->FETCH_HEAD $ git merge origin/branch1 Already up-to-date 

Я не хотел этого. То, что было в моем сознании, прежде чем делать это, было использование fetch, чтобы получить то, что добавил мой партнер, и обновил origin/branch1 ветвь удаленной ветви. Тем не менее, «Уже обновленный» означает, что я не смог получить обновления в моей локальной ветке1. Затем я проверил значение sha1 origin/branch1 на

 $ git ls-remote origin 

и обнаружил, что он сохранил устаревшее значение старой фиксации после того, как мы слились в прошлый раз. Он сообщает, что git fetch origin branch1 не может обновить origin/branch1 . Я сделал еще один эксперимент, когда мой партнер создал в своей ветке другую ветку с именем «branch2» и нажал фиксацию в ветке2 на удаленное начало. Затем я все еще использовал

 $ git fetch origin branch2 Compressing... $ git merge origin/branch2 No branch named "origin/branch2" 

«Сжатие» сообщило мне, что первая команда загрузила что-то в branch2 по происхождению успешно, однако вторая команда сообщила мне, что не было ветви с именем origin / branch2! Таким образом, я пришел к выводу, что ни один из них не может git fetch origin branchname origin/branchname локально и не может создать удаленную ветвь, если она не существует.

После того, как я заменил git fetch origin branch# git fetch origin с помощью git fetch origin , все git merge s работали так, как я ожидал.

Однако я часто вижу комбинацию

 $ git fetch remote branch-name $ git merge remote/branch-name 

Итак, мой вопрос в том, в чем разница между git fetch remote git fetch remote branch-name git fetch remote и git fetch remote branch-name ? И в каких условиях мне удастся позволить ему работать по моему желанию этой комбинацией?

Если вам нужно знать, что именно делает git fetch или какая-либо другая команда git , просто префикс его с помощью GIT_TRACE=1 , поэтому он даст вам вывод трассировки с любыми другими командами, которые вызывают, например

 $ GIT_TRACE=1 git fetch origin master 03:08:15.704945 git.c:348 trace: built-in: git 'fetch' 'origin' 'master' 03:08:15.706183 run-command.c:347 trace: run_command: 'ssh' 'git@github.com' 'git-upload-pack '\''FOO/BAR.git'\''' 03:08:16.006394 run-command.c:347 trace: run_command: 'rev-list' '--objects' '--stdin' '--not' '--all' '--quiet' 03:08:16.013096 run-command.c:347 trace: run_command: 'rev-list' '--objects' '--stdin' '--not' '--all' 03:08:16.013625 exec_cmd.c:129 trace: exec: 'git' 'rev-list' '--objects' '--stdin' '--not' '--all' 03:08:16.016617 git.c:348 trace: built-in: git 'rev-list' '--objects' '--stdin' '--not' '--all' From github.com:FOO/BAR * branch master -> FETCH_HEAD 03:08:16.153070 run-command.c:347 trace: run_command: 'gc' '--auto' 03:08:16.153748 exec_cmd.c:129 trace: exec: 'git' 'gc' '--auto' 03:08:16.157704 git.c:348 trace: built-in: git 'gc' '--auto' 

который в основном делает ssh на удаленный хост, запускает git-upload-pack который отправляет объекты, упакованные обратно в git-fetch-pack который получает отсутствующие объекты из другого репозитория.

В man git-upload-pack мы можем читать:

Вызывается git fetch-pack , узнает, какие объекты отсутствует в другой стороне, и отправляет их после упаковки.

И в man git-fetch-pack мы можем читать:

Вызывает git-upload-pack в возможно удаленном репозитории и просит отправить объекты, отсутствующие в этом репозитории, для обновления названных глав. Список локаций, доступных локально, обнаруживается путем сканирования локальной refs / hierarchy и отправки на git-upload-pack запущенного на другом конце.


Чтобы ответить на вопрос, разница между git fetch remote и git fetch remote branch-name заключается в том, что если вы не укажете параметр <refspec> (например, ветвь), он извлекает все ветки и / или теги (см. git ls-refs ) из одного или нескольких других репозиториев вместе с объектами, необходимыми для завершения их историй. По умолчанию загружаются только те теги, которые доступны доступным объектам (например, вы получаете только теги, которые указывают на интересующие вас ветви).

И когда вы запускаете с явными ветвями и / или тегами, git сначала определяет, что нужно извлечь, а затем получать только соответствующие ссылки (ветви или теги). Например, git fetch origin master будет извлекать только основную ветвь.