git fetch, FETCH_HEAD и origin/master

Я очень новичок в Git и у меня проблемы с простым fetch операция.

Я пытаюсь получить информацию о прогрессе коллеги из его хранилища. Сначала я сделал git fetch HEAD что побудило git загрузить около 350 МБ данных, так что я был уверен, что он что-то сделал. Тем не мение, origin/master в конечном итоге все еще указывает на тот же старый коммит (на самом деле это под именем dev но я назову это master - у него нет master).

После этого я попробовал git fetch origin master но, похоже, он ничего не делал, он только обновлялся FETCH_HEAD, Я отметил FETCH_HEAD коммит, чтобы я не потерял его, но я все еще хотел бы иметь обновленную удаленную ветку.

Что случилось не так? У меня нет доступа к удаленному хранилищу. Могу ли я все еще исправить это дома?

4 ответа

Решение

Меня немного смущают команды, которые вы используете. HEAD обычно это метка, которую git использует для отслеживания коммита, который в данный момент находится в рабочем каталоге. git fetch Команда ожидает, что удаленная или удаленная конфигурация фиксации будет знать, что вы хотите получить. С помощью git fetch HEAD будет указывать HEAD это пульт в вашем хранилище. Любопытно, что команда работала без ошибок.

Например: git fetch HEAD в репозитории я в настоящее время работаю приводит к следующей ошибке

fatal: 'HEAD' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Команда git remote перечислит все пульты, пока git remote --verbose будет включать в себя адрес удаленного. Не могли бы вы использовать это, чтобы увидеть, если у вас есть пульт, определенный как HEAD а какие удаленные адреса хранятся у ваших друзей?

Однако мои вопросы остались в стороне и помогли прояснить ваше замешательство. git fetch ... Команда обновляет только удаленные ссылки, а не ваши локальные.

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

working directory
|=>.git
|  |=>objects           <= contains data for each commit
|  |=>refs
|     |=>heads
|        |-master       <= file containing current commit of local master branch
|     |=>remotes
|        |=>origin
|           |-master    <= file containing current commit of remote origin's master branch
|-FETCH_HEAD            <= file updated by `git fetch`, contains info of what was fetched

Скажем, вы заказываете главную ветку, git checkout master - git изменит ваш рабочий каталог так, чтобы он соответствовал данным фиксации в папке "objects", которая соответствует значению фиксации в файле ".git / refs /head / master".

Если вы тогда git fetch origin master файл '.git / refs / remotes / origin / master' обновляется до фиксации главной ветви на удаленном источнике - и все данные фиксации, необходимые для этого фиксации, загружаются и помещаются в папку 'objects'.

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

Используя либо git merge ... или же git rebase ... необходимо обновить местный master ветка с изменениями в origin/master, git pull ... делает оба git fetch ... и либо git merge ... или же git rebase ... в зависимости от опций и конфигурации (git merge ... по умолчанию).

После всего этого объяснения вы хотите увидеть, что - если что-нибудь - было получено из хранилища ваших друзей. git branch -avv Команда выведет список всех локальных и удаленных веток с номерами коммитов и, в случае локальных веток, какую удаленную ветку он отслеживает.

Чтобы увидеть, как ветви связаны друг с другом, я считаю полезным использовать инструмент для построения графика дерева хранилища. Есть несколько вариантов на выбор, но я нахожу git log команда достаточна; такие как git log --all --graph --oneline --decorate, Честное предупреждение, это может быть довольно длинным и запутанным для большого хранилища. Более короткий результат можно получить, добавив --simplify-by-decoration аргумент.

Подводя итог: если вы можете исправить это дома, зависит от информации в вашем хранилище. Вышеупомянутые команды; git remote --verbose, git branch -avv а также git log ... должно быть дать вам понимание текущего состояния вашего хранилища. Оттуда вы можете определить, нужно ли вам делать что-то еще, чтобы получить данные в вашем местном филиале (ах), используя git merge или же git rebase,

Как всегда, если вы столкнетесь с проблемами, отправьте сообщение с тем, что вы узнали.

С git 1.8.4 (август 2013), git fetchобновит ветку удаленного отслеживания! Не простоFETCH_HEAD,

Смотрите коммит f269048 от Джеффа Кинга ( peff ):

Когда мы запускаем обычную "git fetch" ​​без аргументов, мы обновляем отслеживание ссылок в соответствии с настроенной ссылкой.
Однако когда мы бежимgit fetch origin master" (или же "git pull origin master"), мы не смотрим на настроенные refspecs вообще, а просто обновляем FETCH_HEAD,

Мы упускаем возможность обновить "refs/remotes/origin/master"(или что-то еще, что пользователь настроил). Некоторые пользователи находят это запутанным, потому что они хотели бы сделать дальнейшие сравнения со старым состоянием удаленного мастера, например:

$ git pull origin master
$ git log HEAD...origin/master

git fetch на самом деле не касается вашего рабочего каталога. Он только выбирает последние изменения с пульта. Для фактического обновления вашего текущего состояния использования git merge или же git rebase, Также вы можете использовать git pull который работает как ярлык git fetch + git merge,

Основное различие между слиянием и перебазированием заключается в том, что в некоторых случаях слияние создает новый коммит с накопленным состоянием (слияние без ускоренной перемотки вперед). ИМХО это плохо, так как напоминает мне о тех временах, когда я использовал SVN. Rebase просто воспроизводит ваши изменения в верхней части указанного коммита, поэтому ваша история всегда линейна. Просто убедитесь, что используете тот же поток, что и ваши коллеги.

Я предлагаю вам прочитать кое-что о git в целом и о потоке git: обязательная для чтения книга и хорошая статья.

Что вы хотите сделать, это:

  • Добавьте пульт для своего коллеги
  • Получить изменения из своего хранилища
  • Создать локальную ветку, которая ссылается на его удаленную ветку

Предположительно, вы уже сделали шаг № 1. Но для полноты, это:

git remote add coworker git://path/to/coworkers/repo.git

где URL может быть любым форматом URL, который поддерживает git.

Теперь, когда вы добавили пульт, вы хотите получить его изменения:

git fetch coworker

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

git checkout -b hamster coworker/hamster

Это создает и переключает вас на ветку под названием хомяк.

С этого момента, вы можете сделать работу на хомяка и подтолкнуть его к нему с

git push coworker hamster

в первый раз, а потом просто git push после этого.

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

git pull

Другие вопросы по тегам