Git fetch, FETCH_HEAD и источник/мастер

Я очень новичок в git, и у меня возникают проблемы с простой операцией fetch.

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

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

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

Ответ 1

Я немного смущен командами, которые вы используете. 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 master branch
|-FETCH_HEAD            <= file updated by `git fetch`, contains info of what was fetched

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

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

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

Для обновления локальной ветки master с изменениями в origin/master требуется использовать git merge ... или git rebase .... 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 ... должны дать вам представление о текущем состоянии вашего репозитория. Оттуда вы можете определить, нужно ли вам что-то делать, чтобы получить данные в вашей локальной ветке (s) с помощью git merge или git rebase.

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

Ответ 2

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

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

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

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

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

Ответ 3

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

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

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

Ответ 4

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

  • Добавить пульт для вашего сотрудника
  • Извлеките изменения из своего репозитория
  • Создайте локальную ветвь, которая ссылается на удаленную ветку

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

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

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

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

git fetch coworker

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

git checkout -b hamster coworker/hamster

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

С этого момента вы можете работать с хомяком и нажимать на него с помощью

git push coworker hamster

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

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

git pull