git filter-branch частично потерял историю

У меня было репо в одной папке, и я разбил его на подмодули некоторое время назад.

инициал: (T0)

-mainpackage
\-subpackage1
\-subpackage2

ток: (Т1)

-subpackage1
-subpackage2
-mainpackage

В настоящее время я могу видеть всю историю git с самого начала. теперь я хочу переместить этот subpackage1 в другое репо.

когда я выполняю операцию и фильтрую ветку с помощью git filter-branch --subdirectory-filter <directory of subpackage1> -- --all, я теряю историю между T0 и T1, что составляет большую часть коммитов.

когда я отслеживаю историю с помощью git log --follow --pretty=format:"%H" <filename>, я вижу, что у одного и того же файла были две последние версии с путем к файлу (например, «subpackage/src/../filename») и старые коммиты только с именем файла (например, «имя файла»).

Как я могу восстановить прошлую историю для всего подмодуля (в лучшем случае) или отдельных файлов (в худшем случае - меня интересует только история 4-5 файлов)


person tkcn    schedule 20.01.2020    source источник
comment
На самом деле у Git нет истории файлов. Единственная история в любом репозитории состоит из коммитов в репозитории. Команда filter-branch копирует (некоторые или все) старые коммиты в новые; затем вы перестаете использовать старые и вместо них начинаете использовать новые и предположительно улучшенные. Если новые коммиты не являются той историей, которую вы хотели, вам понадобится другой набор копий. Убедитесь, что вы скопировали все коммиты, которые хотели сохранить.   -  person torek    schedule 20.01.2020
comment
Что делает git log --follow <path>: начинает с последних коммитов (как указано в командной строке по именам веток, если вы их использовали, или как указано в HEAD в противном случае). Затем пройдитесь по всем коммитам, по одному. Если этот коммит во время прогулки изменяет указанный файл, распечатайте его. Если нет, то не печатайте. Если способ изменения файла состоит в том, чтобы переименовать файл с dir2/newfile.ext на dir1/oldfile.ext, начните искать dir1/oldfile.ext со следующего (ну, предыдущего) коммита назад к началу времени.   -  person torek    schedule 20.01.2020
comment
Если ваша фильтр-ветвь скопировала все коммиты, в которых есть dir2/* файлы, но выкинула все dir1/* файлы при копировании, и пропустила коммиты, в которых не было dir2/* файлов, ну тогда новая история, сделанная копированием только dir2/*-содержащих коммитов файлов (и даже тогда только их dir2/* части), не будет dir1/* файлов. Так что --follow не увидит переименования и не переключится на поиск dir1/oldfile.ext.   -  person torek    schedule 20.01.2020
comment
Вам нужно будет придумать другой фильтр — отличный от --subdirectory-filter — чтобы вы сохраняли файлы не с именем subpackage1/* в этих предыдущих коммитах. Какое имя вы дадите этим файлам в копиях этих коммитов, зависит от вас/ваших фильтров.   -  person torek    schedule 20.01.2020
comment
с помощью Follow я могу видеть всю историю, поэтому на самом деле у меня есть хэши всех коммитов. фильтр подкаталога пропускает коммиты из старой папки. Я пробовал индексную фильтрацию, но это также очищало старые коммиты.   -  person tkcn    schedule 21.01.2020
comment
Да, --subdirectory-filter означает отбрасывать файлы, которых нет в подкаталоге, т. е. новые коммиты (результат копирования) не затрагивают (и даже не содержат) файлы за пределами подкаталога. Если вы напишете свой собственный --index-filter, вы сможете выбрать, что оставить, а что выбросить, но простого способа нет.   -  person torek    schedule 21.01.2020


Ответы (1)


Вы можете решить свою проблему, передав git_filter_repo в качестве параметра все пути, по которым существовали файлы.

e.g.

git-filter-repo --path mainpackage/subpackage1 --path subpackage1

person Ricardo Arnold    schedule 24.01.2021