Ответ 1
Скажите, что вы начинаете с истории
$ git lola --name-status * e709131 (HEAD, master) bar | A bar * 61493ac ABC/file - 3.ext | A ABC/file - 3.ext * 34cce9e ABC/file - 2.ext | A ABC/file - 2.ext * 115e6d5 ABC/file - 1.ext | A ABC/file - 1.ext * 5ea5b42 foo A foo
Примечание: git lola - нестандартный, но очень полезный псевдоним.
git rm
поддерживает параметр для удаления поддеревьев.
-r
Разрешить рекурсивное удаление при указании имени ведущего каталога.
После запуска
$ git filter-branch --index-filter 'git rm --cached -r --ignore-unmatch ABC' \ --prune-empty --tag-name-filter cat -- --all
вы увидите вывод, похожий на
Rewrite 115e6d5cd06565ca08f1e5c98c4b91246cf59fa1 (2/5)rm 'ABC/file - 1.ext' Rewrite 34cce9e90f832460137e620ebacc8a73a99e64ce (3/5)rm 'ABC/file - 1.ext' rm 'ABC/file - 2.ext' Rewrite 61493ac3211808f34f616dbc33d51d193b3f45a3 (4/5)rm 'ABC/file - 1.ext' rm 'ABC/file - 2.ext' rm 'ABC/file - 3.ext' Rewrite e709131f1fe6103adf37616c9fa500994aeb30d0 (5/5)rm 'ABC/file - 1.ext' rm 'ABC/file - 2.ext' rm 'ABC/file - 3.ext' Ref 'refs/heads/master' was rewritten
Если вы довольны результатом, удалите старого мастера с помощью
$ git update-ref -d refs/original/refs/heads/master
и теперь у вас есть история
$ git lola --name-status * 19680d4 (HEAD, master) bar | A bar * 5ea5b42 foo A foo
Чтобы ответить на второй вопрос, скажите, что вы хотите удалить только ABC/file - 2.ext
. Помните, что вам понадобятся два слоя кавычек: один слой для всей команды, а другой - чтобы избежать пробелов в аргументе этой команды, имя файла для удаления.
Один из способов сделать это -
$ git filter-branch --index-filter \ 'git rm --cached --ignore-unmatch "ABC/file - 2.ext"' --prune-empty \ --tag-name-filter cat -- --all
Обратите внимание на двойные кавычки внутри одиночных кавычек.
Если вы запустили эту команду, ваша история стала бы
$ git lola * a8d1b0d (HEAD, master) bar * cff0c4e ABC/file - 3.ext * 115e6d5 ABC/file - 1.ext * 5ea5b42 foo