Удаляются ли когда-нибудь коммиты git после сброса ветки? - PullRequest
0 голосов
/ 21 февраля 2019

Допустим, у меня есть только основная ветвь, и я сделал несколько коммитов: коммит 1, 2 и 3.

Если я сделаю git reset --hard для коммита 2, тогда нажмите и продолжайте коммитить код.Будет ли commit 3 оставаться в базе данных git навсегда или в конечном итоге будет удален?

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Они живут до тех пор, пока git gc не очистит их, как сказал WofWca , но точно, когда это происходит, может быть немного трудно определить.

Некоторые команды запускают git gc --auto длявы автоматически.В наши дни это включало git commit: git commit всегда должно было запускать это, но код был случайно отброшен в очень ранней версии Git - Git 1.5.4 - и не восстанавливался до 2.17.Но git gc --auto ничего не делает, если, по его оценке, еще нет причин для запуска, и это в большинстве случаев выполняется. 1 Затем, когда git gc решит, что должен запустить, или когда вы запускаете git gc без --auto, чтобы запустить его сразу, даже тогда он может не удалить эти коммиты пока .

Что поддерживает коммит?Ну, ответ сложный:

  1. Каждая ссылка - и имена ветвей - это ссылки, полное имя которых начинается с refs/heads/ - может иметь reflog .В журнале reflog хранятся записей журнала reflog , которые представляют собой записи с метками времени, в которых, по сути, указана ссылка на хэш-идентификатор H на дату D .Это позволяет Git восстанавливать состояние ветви (или любой другой ссылки) по состоянию на конкретное время, заданное в абсолютном или относительном выражении, до тех пор, пока не истек срок действия записей reflog около этого времени.

    Срок действия этих записей журнала do истекает, за исключением refs/stash, для которого по умолчанию никогда не истек срок действия записей журнала.Git удаляет все просроченные записи, оставляя в журнале только не просроченные записи.Срок действия каждой записи настраивается.Значение по умолчанию составляет 30 или 90 дней, как установлено gc.reflogExpire и gc.reflogExpireUnreachable.Какой из них применяется?Ну, это сложно: это зависит от понятия достижимость .Чтобы получить полное представление о том, что означает достижимость, см. Think Like (a) Git .

    В данном конкретном случае нас интересует, является ли идентификатор хеша, сохраненный в записи reflog,достижимо из хеш-идентификатора, хранящегося в самой ссылкеТо есть, учитывая имя типа refs/heads/master, мы проверяем master@{1}, чтобы увидеть, является ли это предком master.Если это так, то запись reflog достижима (из текущего master).Если нет, эта запись reflog является недоступной достижимой (из текущей master).Это в свою очередь выбирает, какую из двух gc.reflogExpire переменных следует использовать.(Если ветвь имеет пользовательскую настройку через gc.<pattern>.reflogExpire и / или gc.<pattern>.reflogExpireUnreachble, она используется вместо этого, конечно. В документации это называется pattern и, по-видимому, используется код соответствия шаблона имени файла,например, .gitattributes.)

    Выбрав переменную срока действия, Git сравнивает временную метку reflog с предполагаемой датой истечения срока действия.Если срок действия записи reflog истек, она удаляется.

    Если запись reflog сохраняется, она защищает объект, идентификатор хеша которого содержит reflog, и всех объектов, доступных из этого объекта.,Для объектов коммита это означает, что сам коммит защищен, как и все его предки, а также их и их снимки.

    Короткая версия этого заключается в том, что по умолчанию записи reflog остаются в течение как минимум 30 дней.,Записи рефлогов, которые являются предками текущей ветки, остаются в течение не менее 90 дней.После этого вида git reset запись не является предком кончика ветви, поэтому применяется правило 30 дней.

  2. Если шаг 1 не сохраняетнепосредственно для внутреннего объекта, существует также журнал для самого HEAD, который может сохранить объект напрямую.И, конечно, любой из них может сохранить объект косвенно через правила достижимости.

  3. Если ни шаги 1, ни 2 не сохраняют объект прямо или косвенно, он все еще может быть еще не удален: все объекты получают льготный период, который по умолчанию равен 14 дням и может быть настроен как gc.pruneExpire.Этот льготный период не позволяет git gc --auto, работающему в фоновом режиме, удалять объект, созданный какой-либо активной командой Git.Например, git commit может работать git write-tree, а git write-tree занят выделением объектов дерева на основе содержимого индекса.После завершения git write-tree, git commit запускает git commit-tree для создания самого объекта фиксации.

    Все они встроены в git commit, но, тем не менее, все они создают свободные объекты, ни один из которых не являетсяпока еще доступен из любой ссылки, поэтому все эти будут иметь право на сборку мусора.Но 14-дневный льготный период означает, что git commit может, теперь, когда записаны некоторые древовидные объекты и новый объект фиксации, завершить фиксацию, указав имя ветви для фиксации и добавив запись reflog в reflog ветви.Пока git commit удается выполнить все это в течение двух недель, Git в порядке.Если ваш компьютер слишком медленный, чтобы завершить git commit за две недели, что ж, это довольно плохо, во многих отношениях, чем один.

Итак, это дает вам набор правил:какие коммиты сохраняются или нет.Кроме того, помните, что в репозиториях bare (хранящихся на серверах) обычно отключены повторные журналы, и они редко имеют дело с незакрепленными объектами - объекты, поступающие на серверы, обычно вводятся как тонкие pack , который сервер "откармливает", а затем обычно все равно перепаковывает в ближайшее время.Таким образом, серверы имеют тенденцию собирать свои объекты намного раньше, чем обычные репозитории, отличные от обычных.


1 Чтобы решить, пора ли что-то делать, git gc --auto выполняет следующие шаги:

  1. Подсчитать количество файлов pack , исключая помеченные "keep".Если это превышает пороговое значение, это время для gc, который включает в себя перепаковку.

  2. Если шаг 1 не сработал, посчитайте количество потерянных объектов в *Каталог 1130 *.(17 здесь - произвольный выбор, и он жестко закодирован. Вы должны спросить у Линуса или кого-то еще, почему 17. Более очевидный выбор - 42 или, возможно, 2a, поскольку они шестнадцатеричные. :-)) Если это превышает пороговое значение, этовремя для сборщика мусора, который собирает один новый пакет.

  3. Если шаг 1 или 2 не сработал, не выполняйте сбор мусора.В противном случае, запустите хук pre-auto-gc, чтобы дать ему возможность прервать сборку мусора.Если ловушка не существует или выходит с успешным, т. Е. Нулевым, состоянием, продолжайте и выполните GC.

Два порога в шагах 1 и 2 управляются gc.autopacklimit, который по умолчанию равен 50, и gc.auto, который по умолчанию равен 6700. Вы можете настроить один или оба из них с помощью git config.Если вы установите gc.auto на ноль или отрицательный, это запрещает оба типа auto-gc, независимо от того, что вы установили gc.autopacklimit на.

Число, которое вы настраиваете в gc.autopacklimit, делится на 256 с дробнымчасть округляется, так что по умолчанию 6700 выдает 27 (6700/256 - 26.171875).Причина деления на 256 состоит в том, что незакрепленные объекты разбросаны по 256 подкаталогам на основе первых двух шестнадцатеричных символов их хеш-идентификатора объекта.Предполагается, что распределение хэшей является равномерным, поэтому, если в .git/objects/17 имеется 26 объектов, вероятно, также имеется около 26 объектов в каждом из других каталогов 255 .git/objects/<em>XX</em>, поэтому примерно 26 x 256 = 6656 потерянныхобъекты.Если в 17/ имеется 27 незакрепленных объектов, вероятно, имеется около 27 x 256 = 6912 незакрепленных объектов.Оценка числа путем подсчета одного подкаталога происходит быстрее, чем вычисление фактического числа путем подсчета всех подкаталогов.Как обычно, Git делает все быстро, когда ему это удается, как в этом случае.

0 голосов
/ 21 февраля 2019

Они останутся.Вы можете позвонить git gc, чтобы очистить их.Чтобы найти их, вы можете, например, использовать git reflog и git fsck.

AFAIK, чтобы удалить их на GitHub, вам необходимо обратиться в службу поддержки ( см. ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...