Ответ 1
Один простой (но медленный) способ сделать это с git filter-branch
и --prune-empty
. Без других фильтров никакие другие коммиты не будут изменены, но любые пустые будут отброшены (что приведет к тому, что все последующие коммиты будут иметь новые родительские идентификаторы и, следовательно, все еще "перезаписывают историю": неважно, если это ваш первоначальный импортировать из hg в git, но это большое дело, если другие используют этот репозиторий уже).
Обратите внимание на все обычные оговорки с ветвью фильтра. (Кроме того, в качестве побочного примечания "пустая фиксация" на самом деле имеет тот, который имеет то же дерево, что и предыдущее: это не то, что у него нет файлов вообще, он имеет все те же файлы с одинаковыми режимами, и то же содержимое, что и его родительский commit.Это происходит потому, что git хранит полные снимки для каждой фиксации, а не различия от одной фиксации к следующей.)
Вот крошечный пример, который скрывает множество мест, где вы можете делать более интересные вещи:
$ ... create repository ...
$ cd some-tmp-dir; git clone --mirror file://path-to-original
(Этот первый клон-шаг для безопасности: filter-branch
может быть довольно разрушительным, поэтому всегда полезно начинать его с нового клона, а не с оригинала. Использование --mirror
означает, что все его ветки и теги зеркалируются в этой копии, тоже.)
$ git filter-branch --prune-empty --tag-name-filter cat -- --all
(Теперь подождите очень долгое время, см. документацию по методам, чтобы немного ускорить это.)
$ git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
(Этот шаг скопирован из документации: он отбрасывает все исходные ветки перед запуском фильтра. Другими словами, он делает фильтрацию постоянной. Поскольку это клон, который достаточно безопасен, даже если фильтр пошло не так.)
$ cd third-tmp-dir; git clone --mirror file://path-to-filtered-tmp
(Это делает чистую, красиво сжатую копию отфильтрованной копии, без оставшихся объектов на этапах фильтрации.)
$ git log # and other commands to inspect
Как только вы уверены, что клон отфильтрованного клона хорош, вам не нужен отфильтрованный клон и он может использовать последний клон вместо первого. (То есть вы можете заменить "истинный оригинал" на окончательный клон.)