Как эффективно извлечь git из мелкого клона

Мы используем git для распространения операционной системы и поддержания ее в актуальном состоянии. Мы не можем распространять полный репозиторий, так как он слишком большой (>2 ГБ), поэтому мы использовали неглубокие клоны (~300 МБ). Однако в последнее время при извлечении из мелкого клона он теперь неэффективно извлекает весь репозиторий размером более 2 ГБ. Это несостоятельная трата пропускной способности для развертываний.

В документации git говорится, что вы не можете получить из мелкого репозитория, хотя это строго не так. Есть ли обходные пути, чтобы сделать git clone --depth 1 в состоянии извлечь только то, что изменилось от этого? Или какая-то другая стратегия, чтобы размер дистрибутива был как можно меньшим, при этом все биты должны быть обновлены git?

Я безуспешно пытался клонировать из --depth 20 чтобы увидеть, будет ли он обновляться более эффективно, это не сработало. Я также заглянул в http://git-scm.com/docs/git-bundle, но это, кажется, создает огромные пакеты.

5 ответов

Решение

--depth это git fetch вариант. Я вижу, документ не особо подчеркивает, что git clone делает выборку

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

--depth=1 fetch просто получает подсказки для веток и никакой предыдущей истории. Дальнейшие выборки из этих историй будут извлекать все новое с помощью описанной выше процедуры, но если ранее извлеченные коммиты не вошли в вновь извлеченную историю, fetch извлечет все это - если вы не ограничите выборку с помощью --depth,

Ваш клиент сделал выборку глубины =1 из одного репо и переключил URL на другой репо. По крайней мере, один длинный путь предков в ссылках этого нового репо, по-видимому, не разделяет никаких коммитов с чем-либо, что в данный момент находится в вашем репо. Это может стоить расследования, но в любом случае, если нет какой-либо конкретной причины, ваши клиенты могут просто делать каждую выборку --depth=1,

Только что сделал g clone github.com:torvalds/linux и это заняло так много времени, поэтому я просто пропустил его CTRL+C,

Потом сделал g clone github.com:torvalds/linux --depth 1 и это действительно клонировали довольно быстро. И у меня есть только один коммит в git log,

Так clone --depth 1 должно сработать. Если вам нужно обновить существующее хранилище, вы должны использовать git fetch origin branchname:branchname --depth 1, Это тоже работает, он получает только один коммит.

Подводя итог:

Начальный клон:

git clone git_url --depth 1

Обновление кода

git fetch origin branch:branch --depth 1

Если вы можете выбрать конкретную ветку, это может быть еще быстрее. Вот пример использования основной ветви Spark и последнего тега:

Начальный клон

git clone git@github.com:apache/spark.git --branch master --single-branch --depth 1

Обновление до определенного тега

git fetch --depth 1 origin tags/v1.6.0

Таким образом становится очень быстро переключать теги / ветви.

Обратите внимание, что Git 1.9/2.0 (первый квартал 2014 года) может быть более эффективным при извлечении мелкого клона.
Смотри коммит 82fba2b, от Нгуен Тай Нгук Дуй ( pclouds ):

Теперь, когда git поддерживает передачу данных от или к мелкому клону, эти ограничения больше не верны.

Все детали в " shallow.c : 8 шагов для выбора новых коммитов для .git/shallow ".

Вы можете увидеть последствия в таких коммитах, как 0d7d285, f2c681c и c29a7b8, которые поддерживают клон, send-pack /receive-pack с / из мелких клонов.
smart-http теперь также поддерживает мелкую выборку / клонирование.
Вы даже можете клонировать форму мелкого репо.

Обновление 2015: git 2.5+ (второй квартал 2015 года) даже позволит получить один коммит! Смотрите раздел " Извлечение определенного коммита из удаленного репозитория git ".

Обновление 2016 (октябрь): git 2.11+ (четвертый квартал 2016 года) позволяет получать:

Я не знаю, подходит ли это для вашей установки, но я использую полный клон репо в отдельном каталоге. Затем я делаю мелкий клон из удаленного репозитория со ссылкой на локальный.

git clone --depth 1 --reference /path/to/local/clone git@some.com/group/repo.git 

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

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

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