git filter-branch
может работать на диапазонах коммитов;Итак, что мы можем сделать, это отфильтровать «до» и «после» по отдельности и использовать трансплантаты, чтобы связать их вместе:
git branch rename $COMMIT_ID_OF_RENAME
git branch pre-rename rename~
## First filter all commits up to rename, but not rename itself
git filter-branch --subdirectory-filter $OLDNAME pre-rename
## Add a graft, so our rename rev comes after the processed pre-rename revs
echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts
## The first filter-branch left a refs backup directory. Move it away so the
## next filter-branch doesn't complain
mv .git/refs/original .git/refs/original0
## Now filter the rest
git filter-branch --subdirectory-filter $NEWNAME master ^pre-rename
## The graft is now baked into the branch, so we don't need it anymore
rm .git/info/grafts
Это немного сложнее, если вам нужно отфильтровать несколько ветвей или тегов;ветви до переименования могут быть включены в первую ветвь фильтра, а ветви после должны быть включены до ^rename
во второй ветке фильтра.
Другой вариант - добавить индексный фильтр (или деревовместо этого), который проверяет оба каталога, старый и новый, и сохраняет то, что есть.
Поскольку вы не предоставили тестовый репозиторий, вот сценарий быстрой проверки работоспособности для этого сценария:
#!/bin/bash
set -u
set -e
set -x
rm -rf .git x y foo
git init
mkdir x
echo initial > x/foo
git add x/foo
git commit -m 'test commit 1'
echo tc2 >> x/foo
git commit -a -m 'test commit 2'
mv x y
git rm x/foo
git add y/foo
git commit -a -m 'test rename'
git branch rename HEAD
echo post rename >> y/foo
git commit -a -m 'test post rename'
git branch pre-rename rename~
git filter-branch --subdirectory-filter x pre-rename
echo `git rev-parse rename` `git rev-parse pre-rename` >> .git/info/grafts
mv .git/refs/original .git/refs/original0
git filter-branch --subdirectory-filter y master ^pre-rename
rm .git/info/grafts
git log -u
Если эта процедура не работает для вас, то в истории вашего хранилища может быть что-то еще странное, что вы не описали, например, другое переименование, скрывающееся в истории.