Создайте новый репозиторий git из уже существующего подкаталога REPO

Я хочу создать отдельное репо из уже существующей подпапки repo.

Отсоединить (переместить) подкаталог в отдельный репозиторий Git. НО, я не могу получить чистое репо с ним. В итоге у меня возникли две проблемы с новым репо:

  • История кажется дублированной;
  • Я не могу сохранить историю ветвей.

Вот что я сделал:

$ git clone ssh://.../repo.git
$ cd repo
$ git filter-branch --subdirectory-filter subdirectory HEAD -- --all
$ git reset --hard
$ git gc --aggressive
$ git prune

После этого кажется, что у меня есть оригинальная история репо и новая история. Я печатаю "git log - all --graph" (или gitk --all) Я вижу в качестве первого коммита начальное коммитирование первого репо. Затем график показывает исходную историю репо до последней фиксации. Затем у меня есть ВТОРАЯ история поверх первой, показывающая историю только вложенной папки, которую я хочу. Но в той части истории у меня есть только "хозяин" и никаких ветвей/слияний.

"git log", gitk или gitg все показывают только "сгладить" историю: они не показывают начальную историю репо до того, как вложенная папка сглаживает историю.

Я попытался использовать только команду "фильтр-ветвь", клонируя результирующий репо (с -no-hardlinks), используя:

$ git filter-branch --subdirectory-filter subdirectory -- --all

вместо:

$ git filter-branch --subdirectory-filter subdirectory HEAD -- --all

Но с тем же результатом.

Я делаю что-то неправильно или Git нарушается? У меня действительно нет идей... Используя Git 1.7.6. Спасибо.

EDIT: Я думаю, проблема может возникнуть из-за того, что комманды слияния игнорируются ветвью фильтра, что дает плоскую историю без ветвей или слияния...

Ответ 1

У вас есть две проблемы:

(1) Как указывает Кевин Баллард, вам нужно удалить каталог refs/original в каталоге .git, чтобы избавиться от ложных записей журнала; IIRC это упоминается в вопросе, о котором вы говорили.

(2) Вам нужно преобразовать ветки по одному. Насколько я знаю, это нигде не упоминается, но довольно легко обнаружить эмпирически. A script для этого будет выглядеть примерно так:

for branch in $(git for-each-ref --format='%(refname:short)' refs/remotes/origin | grep -v HEAD); do
  git checkout -b $(basename $branch) $branch
  git filter-branch -f --subdirectory-filter subdirectory HEAD -- --all
done

Обратите внимание, что вам нужен -f или что-то вроде --original $(basename $branch) -original, чтобы заставить git повторно использовать или переименовать пространство имен, в котором хранятся исходные ссылки. Также обратите внимание, что вы можете видеть такие сообщения, как "Не найдено ничего, чтобы переписать", если подкаталог не существует на определенной ветке - вы, вероятно, захотите удалить эти ветки из своего нового репозитория. (Или удалите их перед запуском script.)

Ответ 2

Я думаю, вам нужно удалить свои пульты. например.

git remote rm origin

Я думал то же самое, что и вы, когда я бегал git log --all и gitk --all и видел все коммиты. Затем я понял, что дополнительные коммиты были с удаленного.

Ответ 4

git filter-branch сохраняет все исходные ссылки в собственном пространстве имен (под original/). Похоже, ваш git log --all показывает эти ссылки тоже. Вместо этого вы должны проверить все ссылки, которые вам нужны, и если они выглядят хорошо, вы можете выбросить пространство имен original/.