Как 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
(это может быть опасно).
Также я узнал, что в некоторых случаях, когда удаленный компьютер сильно изменился, клон начинает получать слишком много данных. Хорошо разорвать его и обновить ссылочное репо (что странно занимает гораздо меньшую пропускную способность, чем в первую очередь). Затем снова запустите клон.