Извлеките подкаталог git, сохраняя историю С переименованием - PullRequest
12 голосов
/ 09 марта 2011

Я делю большое дерево исходных текстов на два отдельных компонента и общий подмодуль. Чтобы подготовиться к этому разделению, я сначала переместил общие материалы в один «общий» каталог, обновил все ссылки и сделал коммит. Все идет нормально. Теперь я хотел бы извлечь этот каталог в подмодуль.

Обычно я делаю это с

git filter-branch --subdirectory-filter

Но в этом случае вся интересная история произошла за пределами этого подкаталога, поэтому история теряется.

Я понимаю, что не имеет смысла вести полную историю, так как это вообще не отфильтровывает данные. Но я не собираюсь возвращаться назад во времени и строить, я просто хочу посмотреть коммиты, в которых каждый файл был членом.

Есть ли способ сохранить поведение ветви фильтра при сохранении истории отдельных файлов?

Ответы [ 2 ]

4 голосов
/ 09 марта 2011

Не совсем. --subdirectory-filter представляет собой особый случай, поскольку он на самом деле значительно изменяет содержимое деревьев (поскольку он перемещает объекты на один или несколько уровней вложенности каталогов).

Таким образом, на самом деле нет хорошего отображения между файлами, находящимися вне подкаталог, по которому вы фильтруете, и деревья, которые могут быть сохранены как часть коммитов в результате.

Помните, что filter-branch полностью переписывает вашу историю - вывод представляет собой совершенно новый набор коммитов, и нет никаких "связей" со старыми коммитами, поэтому любая дополнительная информация должна быть выражена как часть новые коммиты.

3 голосов
/ 29 декабря 2011

Вот как я просто решил похожую проблему. Я запустил проект в квази-частном репозитории "misc", переименовал некоторые файлы, а затем я хотел загрузить проект в GitHub со https://github.com/kragen/aikidraw.

$ git clone misc aikidraw
$ cat > aikidraw-wanted
aikidraw.js
aikidraw.html
caposketchra.html
caposketchra.js
jquery-1.2.6.js
^D
$ cd aikidraw
$ git filter-branch --tree-filter 'bash -c "comm -23 <(/bin/ls | sort) <(sort ~/devel/aikidraw-wanted) | xargs rm -rf"' HEAD

Кажется, до сих пор это работало нормально, если не удалять точечные файлы (например, .git, хорошо и .gitignore, плохо), но, очевидно, моя версия Git (1.6.0.4) не имеет git filter-branch --prune-empty , Итак, теперь я клонирую новый репозиторий меньшего размера (чтобы ускорить его копирование по сети) и копирую репо на другой компьютер с Git 1.7.2.5:

$ time git clone aikidraw aikidraw-smaller
$ du -sh aikidraw/.git aikidraw-smaller/.git
8.6M    aikidraw/.git
1.2M    aikidraw-smaller/.git

$ time rsync -Pav aikidraw-smaller panacea.canonical.org:devel/aikidraw/
real    1m23.251s

А потом на panacea.canonical.org:

$ cd ~/devel/aikidraw/aikidraw-smaller  # Oops. I hate rsync sometimes.
$ git checkout  # otherwise I get "Cannot rewrite branch(es) with a dirty working directory."
$ git filter-branch --prune-empty HEAD
$ cd ../..
$ mv aikidraw i-hate-rsync
$ mv i-hate-rsync/aikidraw-smaller/ aikidraw

Затем вернемся на мой нетбук:

$ mv aikidraw aikidraw-big
$ git clone panacea.canonical.org:devel/aikidraw
$ du -sh aikidraw/.git
268K    aikidraw/.git

Теперь, если вы делали это с двумя каталогами, а не с пятью файлами, на этом этапе вы можете переименовать все содержимое оставшегося подкаталога в корень хранилища, используя git mv. В моем случае я уже переименовал.

$ git remote add github git@github.com:kragen/aikidraw.git
$ git push github master

Надеюсь, это поможет!

...