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

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

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

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

Ответы

Ответ 1

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

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

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

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

Ответ 2

Просто сделал 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

Ответ 3

Обратите внимание, что Git 1.9/2.0 (Q1 2014) может быть более эффективным при извлечении для мелкого клона.
См. commit 82fba2b, из Nguyễn Thái Ngọc Duy (pclouds):

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

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

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

Обновление 2015: Git 2.5+ (Q2 2015) даже позволит использовать одиночную фиксацию! См. "Вытащите конкретную фиксацию из удаленного хранилища Git.

Обновление 2016 (октябрь): Git 2.11+ (Q4 2016) разрешает выборку:

Ответ 4

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

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

git clone [email protected]:apache/spark.git --branch master --single-branch --depth 1

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

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

Очень быстро переключаться между тегами/ветвью.

Ответ 5

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

git clone --depth 1 --reference /path/to/local/clone [email protected]/group/repo.git 

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

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