Как переименовать пакеты Java, не нарушая историю Subversion?
Компания, в которой я работаю, начинает свою деятельность, и они меняют свое имя в процессе. Таким образом, мы по-прежнему используем имя пакета com.oldname, потому что боимся нарушить историю изменений файлов, или наследственные связи между версиями, или что-нибудь, что мы можем сломать (я не думаю, что я использую правильные термины, но вы понимаете, что такое).
Мы используем: Eclipse, TortoiseSVN, Subversion
Я нашел где-то, что я должен сделать это в несколько шагов, чтобы предотвратить несоответствие между содержимым папок.svn и именами пакетов в файлах java:
- Сначала используйте TortoiseSVN, чтобы переименовать каталог, обновив каталоги.svn.
- Затем вручную переименуйте каталог обратно в исходное имя.
- Чтобы, наконец, использовать Eclipse для переименования пакетов (рефакторинг) обратно в новое имя, обновите файлы Java.
Это кажется мне хорошим, но мне нужно знать, будут ли родословная, история и все остальное все еще согласованными и будут работать хорошо.
У меня нет ключей от этого сервера, поэтому я не спешу делаю резервные копии и пробую одну или две вещи. Я хотел бы найти вескую причину, чтобы не делать этого, или способ сделать это, который работает.
Спасибо за помощь,
М. Джоанис
Тест на переименование пакета
Процедура:
- Создайте новый пакет com.oldname.test.renametest.subpackage.
Добавьте новый класс в Renametest с именем RenameTest0.java и содержащий:
class RenameTest0 {public RenameTest0 () {showMessage (); новый RenameTest1(); } public static void showMessage() { System.out.println("RenameTest0!"); } public static void main(String[] args) { new RenameTest0(); } }
Добавьте новый класс в renametest.subpackage, содержащий:
class RenameTest1 { public RenameTest1 () { ShowMessage(); RenameTest0.showMessage(); } public static void showMessage() { System.out.println("RenameTest1!"); } }
Проверьте, что RenameTest0 работает нормально.
- Commit.
- Измените сообщения обоих классов.
- Commit.
- Опять же, измените сообщение одного класса и зафиксируйте (просто создав историю).
- Примените процедуру, предложенную выше (три шага в исходном сообщении) для переименования пакета renametest в testrename.
- Commit.
- Тестовый забег.
- Измените сообщения снова и проверьте.
- Commit.
- Попробуйте откатиться до версии, когда оба сообщения были изменены одновременно с первого раза.
- Если до этого момента все работало нормально, это выглядит хорошо, нет?
Результат теста:
- Примечание на шаге 9: Пришлось делать это в обратном порядке (переименовывать Eclipse, затем переименовывать TortoiseSVN.), Иначе это было сложно, так как TSVN создает новую папку / пакет и помечает старую папку для удаления... Так что вы не можете переименуйте в Eclipse, если вы не поместите старый пакет в другое время, чтобы предотвратить потерю папок.svn и т. д. (Примечание для себя: не забудьте поставить галочку для рекурсивного переименования пакетов!)
- Примечание на шаге 14: сработало! Мы можем видеть предыдущие версии; все, что нам нужно сделать, это сказать, чтобы не ломаться при копировании / перемещении, и это нормально. После возврата к версии до переименования имена пакетов не возвращаются к добрым именам, хотя, вероятно, повторный рефакторинг сделает это.
- Конец примечания: я был удивлен, когда мне пришлось делать критические шаги в обратном порядке. Чтобы сделать это прямо в середине этой первой попытки переименования пакета, мне пришлось откатить некоторые TSVN и ручные модификации, что поставило под сомнение повторяемость точных результатов этой процедуры. Мне придется сделать второй тест, чтобы подтвердить его правильность. Подводя итог: выглядит хорошо, но нуждается в дальнейшем тестировании.
7 ответов
Возможно, это не практично для ваших конкретных потребностей, но TortoiseSVN имеет удобную функцию в отношении переименований. Вы могли бы сделать это:
- Используйте функцию рефакторинга вашей IDE, чтобы переименовать материал.
- Запустите диалог "Проверка изменений" от TortoiseSVN.
- Для каждого переименованного элемента вы увидите две записи: отсутствующий элемент "source.java" и неверсионный элемент "target.java". Выделите оба и выберите "Восстановить ход" из контекстного меню.
Рассматривали ли вы использование плагина Subclipse? Это может решить ваши проблемы, в соответствии с тем, Как я могу использовать Eclipse Refactoring Tools и поддерживать синхронизацию с SVN через Subclipse?
Вы уверены, что ведение истории НЕ работает, если вы используете метод рефакторинга, включенный в Eclipse?
С NetNeans я регулярно меняю имена пакетов, и базовый плагин svn будет молча перемещать контент (который сохраняет историю) в новый каталог (после этого произойдет обычный рефакторинг).
Итак: вы пробовали это из затмения, если история хранится с плагином Subversion? (например, в новой проверочной копии, чтобы избежать сбоя)
По крайней мере, вы могли бы использовать NetBeans для выполнения этой разовой задачи...
Я обнаружил, что плагин subclipse выдает сообщение об ошибке "уже находится под контролем версии" при фиксации класса, который был перемещен в новый пакет (т.е. еще не находится под контролем исходного кода), и родительский элемент этого пакета также является новым.
Когда это происходит, я могу зафиксировать изменения, используя TortoiseSVN. После этого мне нужно только обновить проект в Eclipse.
После перемещения класса в новый пакет, родительский объект которого уже находится под контролем исходного кода, subclipse может зафиксировать это изменение без проблем.
Вместо переименования пакетов вы можете сделать это:
создайте новую структуру пакета в вашем проекте. После этого ваш проект должен выглядеть примерно так:
com - |- myOLDcompname - | |- feature1 - | |- classA.java | |- classB.java |- myNEWcompname - |- feature1
добавьте новые папки под контролем версий, чтобы svn мог их отслеживать
- переместите ваши Java-классы из старых пакетов в новые. Eclipse должен обновить все импорты классов и объявления пакетов соответственно. Самое главное, потому что старые и новые пакеты находятся под vcs, этот шаг должен сохранять историю классов.
- когда закончите, удалите старые папки
- совершить!
Вы можете сделать это, и это не так сложно - ваш лучший выбор для получения чистой истории SVN - это сделать это в 2 шага (может стать одним коммитом) - хотя для хороших результатов я рекомендую использовать клиент CLI.
- Используйте SVN MV для перемещения папок / пакетов
- Перейдите в Eclipse или используйте grep из CLI, чтобы исправить пакеты в файлах, чтобы они соответствовали новому имени.
Затем вы можете зафиксировать как набор изменений, и история на уровне файлов должна совпадать.
Если вы используете Maven или инструмент для упаковки, рекомендуйте запустить релиз, прежде чем делать что-то подобное - также стоит сразу обрезать тег, если вам нужно вернуться к старой структуре.
Да, это будет работать. Вы можете установить версию командной строки svn и написать командный файл, который будет выполнять svn. Автоматизация затмения будет немного больше работы, и, вероятно, не стоит, если вы уже не знакомы с API затмения.
Протестируйте его с одним пакетом, прежде чем делать все просто, чтобы убедиться, что вы делаете все правильно.