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

Вы можете получить SQL, который использовался для создания таблицы из sqlite_master:

sqlite> create table demo_tab (
   ...>     name text not null unique,
   ...>     phone_number text not null check(phone_number like '9%')
   ...> );
sqlite> select sql from sqlite_master where type='table' and name='demo_tab';
CREATE TABLE demo_tab (
    name text not null unique,
    phone_number text not null check(phone_number like '9%')
)
1
задан James Lin 21 February 2019 в 04:05
поделиться

2 ответа

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

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

0
ответ дан WofWca 21 February 2019 в 04:05
поделиться

Они живут до тех пор, пока 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 самостоятельно, чтобы запустить его сразу, даже тогда он может еще не удалить эти коммиты .

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

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

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

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

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


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

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

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

  3. Если шаг 1 или 2 не сработал, не делайте GC. В противном случае запустите хук 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/XX каталогов, а также около 26 x 256 = 6656 потерянных объекты. Если в 17/ имеется 27 незакрепленных объектов, вероятно, имеется около 27 x 256 = 6912 незакрепленных объектов. Оценка числа путем подсчета одного подкаталога происходит быстрее, чем вычисление фактического числа путем подсчета всех подкаталогов. Как обычно, Git делает все быстро, когда ему это удается, как в этом случае.

0
ответ дан torek 21 February 2019 в 04:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: