В чем разница между git clone --mirror и git clone --bare

На странице справки git clone есть что сказать --mirror:

Настройте зеркало удаленного хранилища. Из этого следует --bare,

Но не вдаваться в подробности о том, как --mirror клон отличается от --bare Клон.

8 ответов

Решение

Разница в том, что при использовании --mirrorВсе ссылки копируются как есть. Это означает все: удаленное отслеживание веток, заметок, ссылок / оригиналов /* (резервные копии из фильтра-ветки). В клонированном репо есть все. Он также настроен так, что удаленное обновление будет повторно извлекать все из источника (перезаписывая скопированные ссылки). Идея состоит в том, чтобы действительно отразить хранилище, иметь полную копию, чтобы вы могли, например, разместить свое центральное хранилище в нескольких местах или сделать его резервную копию. Подумайте только о прямом копировании репозитория, за исключением гораздо более элегантного мерзавца.

Новая документация в значительной степени говорит обо всем этом:

--mirror

Установите зеркало исходного хранилища. Из этого следует --bare, По сравнению с --bare, --mirror он не только отображает локальные ветви исходного кода в локальные ветви целевого объекта, он также отображает все ссылки (включая удаленные ветви, заметки и т. д.) и устанавливает конфигурацию refspec таким образом, чтобы все эти ссылки были перезаписаны git remote update в целевом хранилище.

В моем первоначальном ответе также были отмечены различия между пустым клоном и обычным (не голым) клоном - клон не голый устанавливает удаленные ветви отслеживания, создавая только локальную ветвь для HEADв то время как голый клон копирует ветви напрямую.

Предположим, происхождение имеет несколько ветвей (master (HEAD), next, pu, а также maint) некоторые теги (v1, v2, v3), некоторые удаленные филиалы (devA/master, devB/master) и некоторые другие ссылки (refs/foo/bar, refs/foo/baz, которые могут быть заметками, тайниками, пространствами имен других разработчиков, кто знает).

  • git clone origin-url(не голые): вы получите все скопированные теги, локальная ветвь master (HEAD) отслеживание удаленной ветки origin/masterи удаленные филиалы origin/next, origin/pu, а также origin/maint, Отслеживание веток настроено так, что если вы делаете что-то вроде git fetch origin, они будут получены, как вы ожидаете. Любые удаленные ветви (в клонированном удаленном) и другие ссылки полностью игнорируются.

  • git clone --bare origin-url: Вы получите все теги, скопированные, местные филиалы master (HEAD), next, pu, а также maint, нет удаленного отслеживания веток. То есть все ветви копируются как есть, и они настроены полностью независимо, без ожидания повторной загрузки. Любые удаленные ветви (в клонированном удаленном) и другие ссылки полностью игнорируются.

  • git clone --mirror origin-url: Каждый последний из этих ссылок будет скопирован как есть. Вы получите все теги, местные филиалы master (HEAD), next, pu, а также maint, удаленные филиалы devA/master а также devB/master, другие ссылки refs/foo/bar а также refs/foo/baz, Все именно так, как было в клонированном пульте. Удаленное отслеживание настроено так, что если вы запустите git remote update все ссылки будут перезаписаны от источника, как если бы вы просто удалили зеркало и отозвали его заново. Как первоначально сказали документы, это зеркало. Предполагается, что это функционально идентичная копия, взаимозаменяемая с оригиналом.

$ git clone --mirror $URL

это сокращение для

$ git clone --bare $URL
$ (cd $(basename $URL) && git remote add --mirror=fetch origin $URL)

(Скопировано прямо отсюда)

Как это выглядит в текущей man-странице:

По сравнению с --bare, --mirror он не только отображает локальные ветви исходного кода в локальные ветви целевого объекта, он также отображает все ссылки (включая удаленные ветви, заметки и т. д.) и устанавливает конфигурацию refspec таким образом, чтобы все эти ссылки были перезаписаны git remote update в целевом хранилище.

Я добавляю картинку, показываю configРазница между зеркалом и голым. Слева голая, справа зеркало. Вы можете быть ясно, файл конфигурации зеркала есть fetch ключ, который означает, что вы можете обновить его, git remote update или же git fetch --all

Мои сегодняшние тесты с git-2.0.0 показывают, что опция --mirror не копирует хуки, файл конфигурации, файл описания, файл info/exclude и, по крайней мере, в моем тестовом примере несколько ссылок (которые я не не понимаю.) Я бы не назвал это "функционально идентичной копией, взаимозаменяемой с оригиналом".

-bash-3.2$ git --version
git version 2.0.0
-bash-3.2$ git clone --mirror /git/hooks
Cloning into bare repository 'hooks.git'...
done.

-bash-3.2$ diff --brief -r /git/hooks.git hooks.git
Files /git/hooks.git/config and hooks.git/config differ
Files /git/hooks.git/description and hooks.git/description differ
...
Only in hooks.git/hooks: applypatch-msg.sample
...
Only in /git/hooks.git/hooks: post-receive
...
Files /git/hooks.git/info/exclude and hooks.git/info/exclude differ
...
Files /git/hooks.git/packed-refs and hooks.git/packed-refs differ
Only in /git/hooks.git/refs/heads: fake_branch
Only in /git/hooks.git/refs/heads: master
Only in /git/hooks.git/refs: meta

Подробное объяснение из документации GitHub по дублированию репозитория:

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

Клон копирует ссылки с удаленного устройства и помещает их в подкаталог с именем "это ссылки, которые есть у удаленного устройства".

Зеркало копирует ссылки с пульта дистанционного управления и переводит их на свой верхний уровень - оно заменяет свои ссылки на удаленные.

Это означает, что когда кто-то вытаскивает из вашего зеркала и помещает ссылки на зеркала в свой подкаталог, они получат те же ссылки, что и на оригинале. Результат извлечения из современного зеркала аналогичен извлечению непосредственно из первоначального репо.

В отличие от, и оба являются голыми репозиториями. Разница между ними в config файл.

конфигурационный файл выглядит так:

      [remote "origin"]
    url = https://github.com/example
    fetch = +refs/heads/*:refs/remotes/origin/*

конфигурационный файл выглядит так:

      [remote "origin"]
    url = https://github.com/example

конфигурационный файл выглядит так:

      [remote "origin"]
    url = https://github.com/example
    fetch = +refs/*:refs/*
    mirror = true

Итак, мы видим, что основное различие в refspec, используемом для выборки

Формат refspec, во-первых, необязательный, за ним следует <src>:<dst>, куда <src> это шаблон для ссылок на удаленной стороне и <dst>здесь эти ссылки будут отслеживаться локально. В + сообщает Git, что нужно обновить ссылку, даже если это не перемотка вперед.

В случае этого автоматически записывается git remote add origin команда, Git извлекает все ссылки на сервере и записывает их в refs/remotes/origin/ локально.

В случае git clone --bare, нет refspec, который можно было бы использовать для выборки.

В случае, refspec, который будет использоваться для выборки, выглядит как fetch = +refs/*:refs/*. Это означает, tags, remotes, replace (который находится под refsкаталог), а также будет получен. Обратите внимание, что по умолчанию git clone только получить heads.

ПРИМЕЧАНИЕ 1: git clone --mirror а также git clone --bare --mirror эквивалентны.

ПРИМЕЧАНИЕ 2: есть также разница вpacked-refs. Поскольку он записывает ту же информацию, что и refs/heads/, refs/tags/, и друзья записывают более эффективно.

$ git clone --bare https://github.com/example

Эта команда сделает новый файл $GIT_DIR. Кроме того, главы веток на удаленном компьютере копируются напрямую в соответствующие локальные головы веток без сопоставления. При использовании этой опции не создаются ни ветви удаленного отслеживания, ни соответствующие переменные конфигурации.

$ git clone --mirror https://github.com/example

Как и в случае с голым клоном, зеркальный клон включает в себя все удаленные ветки и теги, но все локальные ссылки (включая ветки удаленного отслеживания, заметки и т. Д.) Будут перезаписываться каждый раз при выборке, поэтому он всегда будет таким же, как и исходный репозиторий..

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