Как сохранить историю SVN в Git при перемещении соединительной линии?
Я пытаюсь использовать svn2git для переноса проекта SVN на git. Однако у меня проблемы с сохранением всей истории. Причины, по-видимому, состоят в том, что багажник был перемещен в прошлом. Используемая мной команда:
$ svn2git http://mysvnserver.com/myproject/iPhone/ --no-minimize-url --authors ../authors.txt
Но это только дает мне историю, восходящую к 2011 году. Проект действительно начался в 2010 году. Проецирование началось следующим образом:
myproject
trunk
branches
tags
Но в 2011 году это было изменено на следующее:
myproject
iPhone
trunk
branches
tags
Android
trunk
branches
tags
Старый багажник и ветки попали под каталог iPhone. История, с которой я начинаю, когда это было сделано. Если я делаю svn log
в каталоге iPhone, я получаю сокращенную историю. Но если я cd trunk; svn log
, то я получаю полную историю.
Я понятия не имею, как получить эту историю. Моя идея состояла в том, чтобы каким-то образом создать репозиторий git с только историей магистрали, идущей вплоть до 2010 года. Тогда я позже потянул бы это как ветку в моем основном репо и сделаю перестановку, чтобы получить правильную историю, Но мне не удавалось создать это репо только для туловища. Я пробовал:
$ svn2git http://mysvnserver.com/myproject/ --rootistrunk --authors ../authors.txt
и
$ svn2git http://mysvnserver.com/myproject/ --rootistrunk -no-minimize-url --authors ../authors.txt
без каких-либо успехов.
Ответы
Ответ 1
У меня была такая же проблема. Вот как я это решил.
Клонировать оба РЕПО отдельно.
git svn clone -s [original-svn-location] [original-clone-directory]
git svn clone -s [new-svn-location] [new-clone-directory]
Добавьте старые клонированные данные в новое репо.
cd [new-clone-directory]
git remote add oldstuff ../[original-clone-directory]
git fetch oldstuff
Теперь сложная часть... Do git log
of master
и oldstuff/master
(или, возможно, trunk
и olstuff/trunk
- как бы вы ее не установили) и запишите первую команду commit sha из новый клон и последний фиксатор sha из старого клона (непосредственно перед переходом).
git replace [first-commit-sha-from-new-clone] [last-commit-sha-from-old-clone]
И переписать хэши SHA, чтобы все было кошерно, и вам больше не нужна замена ref...
git filter-branch
И теперь, чтобы очистить ненужные ссылки.
git remote rm oldstuff
rm -rf .git/refs/replace
Вы потеряете первую фиксацию из своей истории, но поскольку это должно быть начальное движение (то есть: фактическое содержимое файла не изменилось), это, вероятно, не имеет значения для вас.
Теперь вся история должна быть сохранена, а отчеты git blame
запоминают старую историю репо, давая вам точную информацию снова.
Вы должны быть в состоянии повторять это как можно чаще (в зависимости от того, сколько раз ваш проект изменил свое корневое местоположение и/или сколько ветвей совершил с обеих сторон перемещения).
PS - Это решение, которое я адаптировал для своих нужд от одного, я нашел здесь (я не мог заставить его подход трансплантата работать для моих репозиториев - но использование замены, похоже, прекрасно работает).
Ответ 2
Вы можете использовать SubGit для преобразования вашего репозитория SVN.
К сожалению, версия 1.0 не поддерживает сложный макет, как тот, который у вас есть. Но там 1.1 версия EAP, которая хорошо ее обрабатывает. Обе версии 1.0 и 1.1 работают с локальным репозиторием SVN, поэтому вы должны иметь административный доступ к репозиторию SVN.
Для преобразования репозитория SVN в Git выполните следующие действия:
-
Создайте начальную конфигурацию.
$ subgit configure SVN_REPO
-
Скорее всего, SubGit обнаружит два проекта внутри этого репозитория. AFAIU, вам нужен только один репозиторий Git. Таким образом, вы должны сохранить только один раздел git 'в файле конфигурации. Укажите все ветки, которые вам нужно преобразовать.
$ EDITOR SVN_REPO/conf/subgit.conf
[core]
...
[git "default"]
repository = .git
...
trunk = trunk:refs/heads/master
branches = branches/*:refs/heads/*
tags = tags/*:refs/tags/*
shelves = shelves/*:refs/shelves/*
branches = iPhone/trunk:refs/heads/iPhone/master
branches = iPhone/branches/*:refs/heads/iPhone/*
tags = iPhone/tags/*:refs/tags/iPhone/*
branches = Android/trunk:refs/heads/Android/master
branches = Android/branches/*:refs/heads/Android/*
tags = Android/tags/*:refs/tags/Android/*
...
[daemon]
...
-
Преобразование SVN в Git.
$ subgit install SVN_REPO
-
В данный момент SubGit преобразует все изменения из SVN в Git. Вы можете найти преобразованный репозиторий Git в SVN_REPO/.git. Кроме того, SubGit сохраняет синхронизацию SVN и Git, для достижения этого устанавливаются специальные перехватчики. При необходимости избавиться от этих крючков.
$ subgit uninstall --purge SVN_REPO
Это все. Теперь вы преобразовали репозиторий Git со всей сохраненной историей.
Обратите внимание, что SubGit - это коммерческий продукт, но этот одноразовый конверт является бесплатным. Надеюсь, это сработает для вас.