Что означает глубина для git clone? - PullRequest
0 голосов
/ 08 декабря 2018

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

Я провел несколько экспериментов с параметром --depth для клонаи столкнулся с каким-то странным поведением.Вот что говорит об этом справка для git clone: ​​

--depth <depth>
           Create a shallow clone with a history truncated to the specified number of commits. Implies
           --single-branch unless --no-single-branch is given to fetch the histories near the tips of all
           branches. If you want to clone submodules shallowly, also pass --shallow-submodules.

Это будет означать, что <depth> будет равно числу коммитов, которые будут получены во время клона, но это не так.Вот что я получил, когда попробовал разные значения для глубины:

| depth   | commit count linux repo | commit count git repo |
|---------|-------------------------|-----------------------|
| 1       | 1                       | 1                     |
| 5       | 15                      | 13                    |
| 10      | 80                      | 46                    |
| 100     | 93133                   | 39552                 |
| 1000    | 788718                  | 53880                 |

Для клонирования я использовал эту команду git clone --depth 10 https://github.com/torvalds/linux.git, git clone --depth 100 https://github.com/git/git.git, а для подсчета коммитов я использовал эту git log --oneline | wc -l.(На работе я наблюдал то же самое с сервером GitLab, так что это не может быть артефактом работы GitHub.)

Кто-нибудь знает, что происходит?Как значение глубины соответствует фактическому количеству загруженных данных?Я правильно понимаю документацию или есть ошибка?

РЕДАКТИРОВАТЬ: я добавил результаты для второго репо

Ответы [ 2 ]

0 голосов
/ 08 декабря 2018

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *} * * * * * * * * * * * * * * * * '*' '' '' '' '' '' '' '' '' '' 100%].В цитируемой вами документации также подразумевается --single-branch, что упрощает разговор об этом.Важным моментом здесь является то, что прогулка посещает всех родителей каждого коммита, что - для каждого уровня глубины - больше, чем один коммит, если сам коммит является слиянием.

Предположим, у нас естьграф коммитов, который выглядит следующим образом:

$ git log --graph --oneline master
* cf68824 profile: fix PATH with GOPATH
* 7c2376b profile: add Ruby gem support
* 95c8270 profile: set GOPATH
* 26a9cc3 vimrc: fiddle with netrw directory display
* 80b88a5 add ruby gems directory to path
[snip]

Здесь каждый коммит имеет только одного родителя.Если мы используем --depth 3, мы возьмем коммит-наконечник cf68824, его родительский 7c2376b на глубине 2 и, наконец, 95c8270 на глубине 3 - и затем мы остановимся с тремя фиксациями.

Однако в репозитории Git для Git:

$ git log --graph --oneline master
*   965798d1f2 Merge branch 'es/format-patch-range-diff-fix-fix'
|\  
| * ac0edf1f46 range-diff: always pass at least minimal diff options
* |   5335669531 Merge branch 'en/rebase-consistency'
|\ \  
| * | 6fcbad87d4 rebase docs: fix incorrect format of the section Behavioral Differences
* | | 7e75a63d74 RelNotes 2.20: drop spurious double quote
* | | 7a49e44465 RelNotes 2.20: clarify sentence
[snip]

При --depth 3 мы начинаем с 965798d1f2, затем - для глубины 2 - подбираем обоих родителей, ac0edf1f46 и 5335669531.Чтобы добавить коммиты глубины 3, мы подберем всех родителей этих двух коммитов.(Одинокий) родитель ac0edf1f46 здесь не виден, тогда как два родителя 5335669531 (а именно 6fcbad87d4 и 7e75a63d74).Чтобы получить хэш-идентификаторы родителей ac0edf1f46, мы можем использовать:

$ git rev-parse ac0edf1f46^@
d8981c3f885ceaddfec0e545b0f995b96e5ec58f

, что дает нам шесть коммитов: наконечник мастера (который в настоящее время является коммитом слияния), два родителя которогоcommit, один родитель одного из этих родителей и два родителя другого этого родителя.

В зависимости от того, когда именно вы запустили клон Git, самый верхний master часто не является слиянием,но часто имеет слияние в качестве непосредственного родителя, так что --depth 2 будет часто получать вам 3 коммита, и поэтому --depth 3 получит по крайней мере 5, в зависимости от того, являются ли два родителя кончика master сами являются слияниями.

(Сравните приведенный выше вывод git rev-parse, например, с:

$ git rev-parse 965798d1f2^@
5335669531d83d7d6c905bcfca9b5f8e182dc4d4
ac0edf1f46fcf9b9f6f1156e555bdf740cd56c5f

. Суффикс ^@ означает всех родителей коммита, ноне сам коммит .)

0 голосов
/ 08 декабря 2018

--depth означает количество коммитов, которые можно получить при клонировании.

По умолчанию git загружает всю вашу историю всех веток.Это означает, что ваша копия будет иметь всю историю, поэтому вы сможете «переключиться» (оформить заказ) на любой коммит, который пожелаете.

Добавление --depth ограничивает размер вашего клона и извлекает только Xпоследние коммиты

# Cloning a  single branch with the following:
# clone specific branch and limit the history to last X commits
git clone --branch<...> --depath=<X>

Как значение глубины соответствует фактическому количеству загруженных данных?с --depth git будет только загружать контент, соответствующий коммитам в заданном диапазоне, поэтому размер репо будет увеличиваться при увеличении значения


Это будет означать, что будет равно количеству коммитов, которые будут получены во время

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


Как очистить ваш бинарный файл:

Переписать историю git, просто чтобы избавиться от них, кажется слишком большой проблемой

Этот инструмент может сделать это для вас:

https://rtyley.github.io/bfg-repo-cleaner

BFG Repo-Cleaner

альтернатива git-filter-branch.

BFG - более простая и быстрая альтернатива git-filter-branch для очистки плохих данных из истории вашего репозитория Git:

* Удаление сумасшедших больших файлов *
* Удаление паролей, учетных данных и других личных данных

Примеры (с официального сайта) Во всех этих примерах bfg является псевдонимом java -jar bfg.jar.

# Delete all files named 'id_rsa' or 'id_dsa' :
bfg --delete-files id_{dsa,rsa}  my-repo.git
...