Как переместить каталог в репозиторий Git для всех коммитов?
Скажем, у меня есть репо, которое включает эту структуру каталогов:
repo/
blog/
_posts/
some-post.html
another-file.txt
Я хочу переместить _posts
на верхний уровень репо, поэтому структура будет выглядеть так:
repo/
_posts/
some-post.html
another-file.txt
Это достаточно просто с git mv
, но я хочу, чтобы история выглядела так, как будто _posts
всегда существовала в корне репо, и я хочу иметь возможность получить всю историю some-post.html
через git log -- _posts/some-post.html
. Я предполагаю, что могу использовать магию с помощью git filter-branch
, чтобы достичь этого, но я не понял, как это сделать. Любые идеи?
Ответы
Ответ 1
Вы можете использовать фильтр подкаталогов для достижения этого
$ git filter-branch --subdirectory-filter blog/ -- --all
РЕДАКТИРОВАТЬ 1: Если вы не хотите эффективно создавать _posts
корень, вместо этого используйте древовидный фильтр:
$ git filter-branch --tree-filter 'mv blog/_posts .' HEAD
РЕДАКТИРОВАТЬ 2: Если blog/_posts
не существовало в некоторых из коммитов, приведенное выше не будет выполнено. Используйте это вместо:
$ git filter-branch --tree-filter 'test -d blog/_posts && mv blog/_posts . || echo "Nothing to do"' HEAD
Ответ 2
В то время как ответ Рамкумара очень полезен и заслуживает внимания, он не будет работать во многих ситуациях.
Например, если вы хотите переместить каталог с другими подкаталогами в новое место.
Для этого man-страница содержит идеальную команду:
git filter-branch --index-filter \
'git ls-files -s | sed "s-\t\"*-&NEWSUBDIR/-" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
git update-index --index-info &&
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
Просто замените NEWSUBDIR на нужный новый каталог.
Вы также можете использовать вложенные dirs, такие как dir1/dir2/dir3/- "