Как я могу переписать историю так, чтобы все файлы, кроме тех, которые я уже переместил, были в подкаталоге?
У меня есть проект под git
, Однажды я переместил все файлы проекта из текущего каталога в foo/bar/
по проекту. Я сделал это используя git mv
, Затем я добавил еще несколько файлов и внес некоторые изменения в уже существующие файлы.
В результате, теперь, когда я смотрю на историю foo/bar/file.c
, Я вижу только те изменения, которые я сделал после перемещения файла.
Я пытался исправить это по-разному (filter-branch
с фильтром подкаталога и т. д.), но ничего не помогло, так что я здесь довольно сложен. Я буду признателен за любую помощь, которую вы можете оказать мне. Спасибо!
3 ответа
Чтобы переписать историю с перемещенными файлами:
Если вы хотите, чтобы история проекта выглядела так, как будто все файлы всегда были в каталоге foo/bar
, тогда вам нужно сделать небольшую операцию. использование git filter-branch
с "фильтром дерева", чтобы переписать коммиты так, чтобы где угодно foo/bar
не существует, он создан и все файлы перемещены в него:
git filter-branch --prune-empty --tree-filter '
if [ ! -e foo/bar ]; then
mkdir -p foo/bar
git ls-tree --name-only $GIT_COMMIT | xargs -I files mv files foo/bar
fi'
Теперь история будет записываться так, как если бы все файлы всегда находились в foo/bar
,
Чтобы просмотреть историю перемещенного файла:
Если вы просто хотите посмотреть историю файла, который был перемещен или переименован в какой-то момент в прошлом, просто используйте --follow
возможность git log
:
git log --follow foo/bar/file.c
Чтобы подвести итог, вот краткое резюме того, что я сделал. Команда, которая работала для меня, была:
if [ ! -e foo/bar ]; then mkdir -p foo/bar; git ls-tree --name-only $GIT_COMMIT | grep -v ^foo$ | xargs -I files mv files foo/bar || echo ""; fi
Команда echo, которую я добавил в конце, гарантировала, что даже при сбое mv вся команда продолжит работать. Он не перемещал содержимое foo/bar/foo, но я могу с этим смириться.
Большое спасибо Дэну Молдингу (!!!) и Джефроми за помощь.
Установите git-filter-repo:
git clone https://github.com/newren/git-filter-repo/
Добавьте исполняемый файл git-filter-repo в $PATH (другие параметры см. в INSTALL.MD ):
# this is just an example, you probably want to edit bashrc,
# or add a symlink to ~/bin or /usr/local/bin
PATH=$PATH:${PWD}/git-filter-repo
В настоящее время
cd
в репозиторий git, который вы хотите изменить, и запустите:
git filter-repo --to-subdirectory-filter foo/bar