Как эффективно извлечь 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 года) позволяет получать:
- с даты
--shallow-since=<date>
- с большей глубиной:
--deepen=N
Я не знаю, подходит ли это для вашей установки, но я использую полный клон репо в отдельном каталоге. Затем я делаю мелкий клон из удаленного репозитория со ссылкой на локальный.
git clone --depth 1 --reference /path/to/local/clone git@some.com/group/repo.git
Таким образом, на самом деле извлекаются только различия с эталонным хранилищем и удаленным. Чтобы сделать это еще быстрее, вы можете использовать --shared
вариант, но не забудьте прочитать об ограничениях в git
документация (это может быть опасно).
Также я узнал, что в некоторых случаях, когда пульт сильно изменился, клон начинает получать слишком много данных. Хорошо тогда разбить его и обновить репо-репозиторий (который, как ни странно, занимает гораздо меньшую полосу пропускания, чем изначально). А затем снова запустить клон.