Как я могу потянуть в голый репозиторий?

У меня есть "основной" открытый репозиторий и "личный" голый репозиторий. Я хочу обновить формы изменений "main" до "personal", поэтому я запускаю:

$ git pull
fatal: /home/gimenero/applib/git/libexec/git-core/git-pull cannot be used without a working tree.

Как перенести изменения на "main"?

Ответ 1

A git pull выполняет a fetch, за которым следует merge, и вы не можете объединиться без рабочего дерева. (Невозможно разрешить конфликты слияния, если они возникнут.)

Вместо этого вы можете просто извлечь. Предполагая, что ваш основной репозиторий настроен как удаленный названный источник в вашем личном репозитории:

$ git fetch origin master:master

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

Ответ 2

Обновить с помощью:

$ git fetch origin +refs/heads/*:refs/heads/* --prune

Что это делает?

Сначала в сторону: когда мы говорим о ветке с именем "xyz", git фактически обращается к ней как к refs/heads/xyz. Но вы можете ввести " xyz " для краткости, потому что иначе это было бы безумием. (Между прочим, тегами являются refs/tags/xyz.) Обычный xyz является неоднозначным, поскольку это может быть ветвь, тег или первые N букв хеша коммита. refs/heads/xyz с другой стороны, явно представляет собой ветвь.

Поэтому, даже если вы можете набрать git fetch origin foo:bar чтобы захватить их ветку foo качестве именованного bar в вашем хранилище, вы можете более явно ввести git fetch origin refs/heads/foo:refs/heads/bar чтобы сделать то же самое. (Хотя, если foo самом деле был тегом, а не ветвью, последний потерпит неудачу, потому что их refs/heads/foo не существуют. Явность ftw.)

git fetch origin refs/heads/*:refs/heads/* означает, что все их ветки принадлежат нам. Команда запускается так, как будто часть * заменяется именем их ветки для каждой из их ветвей. то есть git fetch origin refs/heads/abc:refs/heads/abc refs/heads/def:refs/heads/def... (при условии, что они имеют ветки с именами abc и def).

Параметр --prune означает, что все ветки, которые есть в нашем репозитории, которые соответствуют refs/heads/* но не существуют в их репозитории, удаляются.

Наконец, префикс + должен разрешать выборки без ускоренной перемотки вперед. Без этого любые обновления веток, требующие принудительного обновления, отклоняются.

Если сложить вместе, конечный результат состоит в том, что ветки в вашем хранилище выглядят точно так же, как и их.

Вот пример вывода:

 - [deleted]               (none)     -> bar
 * [new branch]            foo        -> foo
   4812558a5f..a6aeec6517  abc        -> abc
 + a1b2c3d4e5...1a2b3c4d5e def        -> def  (forced update)
  • Пример говорит нам, что у них есть ветки foo, abc, def то время как у нас есть (был) один дополнительный: bar
  • Обратите внимание на удаление bar помощью --prune и принудительное обновление def разрешенное префиксом +.

Вот что происходит вместо этого, если + и --prune были отключены:

 * [new branch]            foo        -> foo
   4812558a5f..a6aeec6517  abc        -> abc
 ! [rejected]              def        -> def  (non-fast-forward)

Одна последняя вещь:

Сравните команду сверху со следующим:

$ git fetch origin +refs/heads/*:refs/remotes/origin/* +refs/tags/*:refs/tags/* [--prune]

По сути, это то, что происходит, когда мы git fetch origin [--prune] !