Отсоединить подкаталог (который был переименован!) В новый репозиторий - PullRequest
9 голосов
/ 10 июля 2011

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

Ответы [ 2 ]

9 голосов
/ 10 июля 2011

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 голосов
/ 03 марта 2015

Мы (Мэтью Флэтт и я) написали программу для этого: https://github.com/samth/git-slice

...