Полностью удалить фиксацию из базы данных git

Мне нужна фиксация, которая больше не будет в базе данных git коммитов. Мне нужно уметь удалить commit abc123... так что git checkout abc123... возвращает error: pathspec 'abc123...' did not match any file(s) known to git.

QA Как удалить "git commit" ответы на это частично, как в том, как удалить ссылки на фиксацию из HEAD, но не охватывает поиск всех ветвей, в которых присутствует фиксация, и не распространяется на истечение срока действия и очистку фиксация, когда она была сделана обвисшей фиксацией.

Как я могу это достичь?

Ответ 1

  1. Список всех ветвей, содержащих фиксацию:

    git branch --contains COMMITSHA
    
  2. Удалите фиксацию из этих ветвей:

    git checkout BRANCH
    git rebase -i COMMITSHA^
    # delete line with commit and save
    

    Если измененная ветвь отслеживается на любом удаленном устройстве, нажмите ее там с переопределением:

    git push --force REMOTE BRANCH
    

    например:

    git push --force origin master
    

    (Обратите внимание, что, в зависимости от вашего процесса разработки, фиксация может появляться и в необработанных удаленных ветких.)

  3. Очистите фиксацию, чтобы она не могла быть восстановлена из вашего локального репо:

    git reflog expire --all BRANCH1 BRANCH2 # list all branches you changed
    git prune --expire now
    

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

    Будьте предупреждены, что вышеприведенные команды удаляют все оборванные объекты из Git repo и всю историю изменений ветки - поэтому вы не сможете восстановить (не-судебно-медицинскими средствами) все, что было потеряно до его запуска.

  4. Сообщите всем сотрудникам, чтобы получить измененные ветки и обновить любую работу, на которой они могли бы основываться на них. Они должны сделать следующее:

    git fetch REMOTE      
    

    Для каждой ветки, основанной на ветке, которую вы изменили выше (включая ветвь, если она есть локально):

    git checkout BRANCH
    git rebase REMOTE/BRANCH
    git reflog expire --all BRANCH
    

    По завершении:

    git prune --expire now
    

Ответ 2

  1. Удостоверьтесь, что никакие refs не нуждаются в фиксации (возврат к предыдущему или переустановка)
  2. Удалите объект из .git/objects (он будет находиться в папке с именем после первых двух символов хэша, а имя файла будет остальным хэшем).

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