Конвертировать git-репозиторий в мелкий? - PullRequest
44 голосов
/ 15 января 2011

Как я могу преобразовать уже клонированный репозиторий git в поверхностный репозиторий?

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

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

Я уже пробовал

git repack -a -d -f -depth=1

Но это на самом делехранилище больше.

Ответы [ 6 ]

37 голосов
/ 06 ноября 2016

Это сработало для меня:

git pull --depth 1
git gc --prune=all
11 голосов
/ 29 октября 2011

Вы можете конвертировать git-репо в мелкое на месте по этой линии:

git show-ref -s HEAD > .git/shallow
git reflog expire --expire=0
git prune
git prune-packed

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

4 голосов
/ 24 сентября 2017

Решение:

git clone --depth 1 file:///full/path/to/original/dir destination

Обратите внимание, что первый "адрес" должен быть file://, это важно. Кроме того, git будет считать ваш исходный локальный адрес file: // «удаленным» («origin»), поэтому вам нужно обновить новый репозиторий, указав правильный git remote.

2 голосов
/ 11 ноября 2018

Обратите внимание, что мелкое репо (например, с git clone --depth 1 в качестве способа преобразования существующего репо в мелкое) может завершиться неудачей на git repack.

См. коммит 5dcfbf5 , коммит 2588f6e , коммит 328a435 (24 октября 2018) Йоханнес Шинделин (dscho) .
(Объединено с Junio ​​C Hamano - gitster - в коммит ea100b6 , 06 ноября 2018 г.)

repack -ad: удалить список мелких коммитов

git repack может отбрасывать недоступные коммиты без дальнейшего предупреждения, делая соответствующие записи в .git/shallow недействительными, что вызывает серьезные проблемы при углублении веток.

Один сценарий, когда недоступные коммиты сбрасываются на git repack, это когда git fetch --prune (или даже git fetch, когда ссылка была тем временем) может сделать коммит недостижимым, что было достижимы до.

Поэтому небезопасно предполагать, что git repack -adlf будет хранить недоступные коммиты в одиночку (при условии, что они не были упакованы в первую очередь, что является предположением, которое, по крайней мере, делает некоторый код Git).

Это особенно важно учитывать при взгляде на .git/shallow file: если какие-либо коммиты, перечисленные в этом файле, становятся недоступно, это не проблема, но если они пропадают, это равно a проблема.
Одним из симптомов этой проблемы является то, что углубление может теперь ошибка с:

fatal: error in object: unshallow <commit-hash>

Чтобы избежать этой проблемы, давайте удалим неглубокий список в git repack при передаче опции -d, если только не передана также -A (что заставило бы теперь недоступные объекты превратиться в свободные объекты быть удаленным).
Кроме того, нам также необходимо учитывать --keep-reachable и --unpack-unreachable=<date>.

Примечание: альтернативное решение обсуждалось во время обзора этого патча должен был научить git fetch просто игнорировать записи в .git/shallow, если соответствующие коммиты не существуют локально.
Тем не менее, быстрый тест показал, что файл .git/shallow записывается во время мелкого клона 1062 *, и в этом случае коммиты тоже не существуют, но есть "мелкая" строка нужно отправить.
Следовательно, этот подход был бы намного более привередливым, чем подход, представленный этим патчем.

0 голосов
/ 26 марта 2019

Конвертировать в мелкие с определенной даты:

git pull --shallow-since=YYYY-mm-dd
git gc --prune=all

Также работает:

git fetch --shallow-since=YYYY-mm-dd
git gc --prune=all
0 голосов
/ 15 января 2011

Допустим, самый ранний коммит, который вы хотите сохранить, имеет SHA1 c0ffee.

  1. Создайте новую пустую ветку
  2. Оформите заказ tree самого раннего коммита, который вы хотите сохранить, без фактической проверки коммита: git checkout c0ffee -- . (Теперь HEAD все еще указывает на вашу новую пустую ветвь, но ваше рабочее дерево и индекс оба выглядят как деревоc0ffee)
  3. Зафиксировать все дерево: git commit -m "Initial commit, copied from c0ffee"
  4. В этот момент git diff-tree newbranch c0ffee не должно выдавать никаких выходных данных - у них одно и то же дерево.(В качестве альтернативы вы можете сделать git show -s c0ffee --format=%T и git show -s newbranch --format=%T, и они должны показывать один и тот же хеш.)
  5. git rebase --onto newbranch c0ffee master
  6. git branch -d newbranch
  7. git gc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...