2011-07-09 7 views
8

У меня есть репозиторий, и я хотел бы отделить один из его каталогов в новое репо. This - идеальное место для начала работы, есть одно предостережение: директория, которую я хочу отделить, была переименована в какой-то момент. И если я последую за решением этой должности с новым именем каталога, то кажется, что я теряю историю перед повторным именем. Любые идеи о том, как заставить его работать в этой ситуации?Отсоединить подкаталог (который был переименован!) В новый репо

ответ

9

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 

Если эта процедура не работает для вас, то есть, вероятно, будет что-то другое нечетное о вашей истории репозитория, которую вы не описали, например, о другом переименовании, скрывающемся в истории.

+0

Хм, я попробовал ваш метод с трансплантатами (что я ничего не знаю о), и это не работает для меня. После обработки один из «до» коммитов стал пустым, другие файлы были перемещены в корень репо; Я не могу понять это. Я думал раньше, используя древовидный фильтр, но не имею никакого опыта с этим; не могли бы вы уточнить, покажите мне несколько указателей? – akoprowski

+0

Вы уверены, что перед фиксацией использовался правильный subdir? Можете ли вы опубликовать свой git-репо где-нибудь? – bdonlan

+0

Yup, переименование было на фиксации, которая переименовала и предварительно переименовала непосредственно перед этим. Репо огромно и частично частно, поэтому я не могу его опубликовать нигде: | – akoprowski

 Смежные вопросы

  • Нет связанных вопросов^_^