如何重命名Java包而不破坏Subversion历史记录?

我正在为之工作的公司正在启动,他们在此过程中改名。 因此我们仍然使用包名com.oldname,因为我们害怕打破文件更改历史记录,或者版本之间的祖先链接,或者我们可以破坏的任何东西(我不认为我使用正确的术语,但你得到了概念)。

我们使用:Eclipse,TortoiseSVN,Subversion

我发现我应该在很多步骤中执行此操作,以防止.svn文件夹的内容与java文件中的包名称之间的不一致:

  • 首先使用TortoiseSVN重命名目录,更新.svn目录。
  • 然后,手动将目录重命名为原始名称。
  • 最后使用Eclipse将包(refactor)重命名为新名称,更新java文件。

这对我来说似乎很好,但我需要知道祖先和历史以及其他一切是否仍然是连贯的并且运作良好。

我没有那个服务器的密钥,这就是为什么我不急着备份东西并尝试一两件事。 我想提出一个很好的理由不去做,或者做一个有效的方法。

谢谢您的帮助,

M. Joanis


包重命名测试

程序:

  1. 创建一个新包com.oldname.test.renametest.subpackage。
  2. 在renametest下添加一个名为RenameTest0.java的新类,其中包含:

      class RenameTest0 {
         public RenameTest0(){
             showMessage();
             new RenameTest1();
         }
         public static void showMessage(){
            的System.out.println( “RenameTest0!”);
         }
         public static void main(String [] args){
             new RenameTest0();
         }
     } 
  3. 在renametest.subpackage下添加一个新类,其中包含:

     class RenameTest1 {public RenameTest1(){showMessage();  RenameTest0.showMessage();  public static void showMessage(){System.out.println(“RenameTest1!”);  }} 
  4. 测试RenameTest0运行正常。

  5. 承诺。
  6. 更改两个类的消息。
  7. 承诺。
  8. 再次,更改一个类的消息并提交(只创建一些历史记录)。
  9. 应用上面提出的程序(原始消息中的三个步骤)将包重命名重命名为testrename。
  10. 承诺。
  11. 测试运行。
  12. 再次修改消息并进行测试。
  13. 承诺。
  14. 第一次同时更改两条消息时,尝试回滚到该版本。
  15. 如果到目前为止一切正常,它看起来不错,不是吗?

测试结果:

  • 关于步骤9的注意事项:必须以相反的顺序执行 (Eclipse重命名为THEN TortoiseSVN重命名。),否则它变得复杂,因为TSVN创建了一个新的文件夹/包并标记旧的删除…所以你不能重命名为Eclipse,除非你在此期间将旧包放在其他地方以防止丢失.svn文件夹等。使用此方法进一步看起来不是一个好主意。 (请注意:不要忘记勾选递归包重命名的复选框!)
  • 注意步骤14:工作! 我们可以看到以前的版本; 我们所要做的就是告诉不要打破复制/移动,这没关系。 一旦恢复到重命名之前的版本, 包名称就不会回到好名字了 ,可能再次重构它就可以了。
  • 结束注释:我很惊讶必须以相反的顺序执行关键步骤。 为了在第一个包重命名尝试中做到这一点,我不得不回滚一些TSVN和手动修改,对这个过程的确切结果的可重复性质产生一点怀疑。 我将不得不做第二次测试以证实它的有效性。 总结一下:它看起来不错,但需要进一步测试。

也许这对你的确切需求并不实际,但TortoiseSVN有一个关于重命名的便利function。 你可以这样做:

  1. 使用IDE的重构function重命名内容。
  2. 启动TortoiseSVN的“检查修改”对话框。
  3. 对于每个重命名的项目,您将看到两个条目:缺少“source.java”项和未版本化的“target.java”项。 突出显示两者并从上下文菜单中选择“修复移动”。

修复移动/重命名

你考虑过使用Subclipse插件吗? 根据我如何使用Eclipse重构工具并通过Subclipse与SVN保持同步,它可以解决您的问题?

如果您使用eclipse中包含的重构方法,您确定保持历史记录不起作用吗?

使用NetNeans,我会定期更改软件包名称,底层的“svn插件”会默默地内容(保存历史记录)移动到新目录中(之后将进行正常的重构)。

所以:如果历史记录与subversion插件一起保存,你是否已经在eclipse中尝试过它? (例如,在新的结账副本中,以避免失败)

至少你可以使用NetBeans来完成这个一次性任务……

是的,它会起作用。 您可以安装svn的命令行版本并编写一个将执行svn的批处理文件。 自动化eclipse的东西会有点多工作,除非你已经熟悉eclipse API,否则可能不值得。

在你做所有事情之前用一个包测试它,以确保你正确地完成所有步骤。

可以做到这一点,并不是那么难 – 获得一个干净的SVN历史记录的最好方法是分两步完成(可以成为一个提交) – 虽然为了获得好的结果,我建议使用CLI客户端。

  1. 使用svn mv移动文件夹/包
  2. 进入Eclipse,或使用CLI中的grep修复文件中的包以匹配新名称

然后,您可以作为更改集提交,并且文件级别的历史记录应该匹配。

如果你正在使用Maven或包装工具,建议你在做这样的事情之前运行一个版本 – 如果你需要回到旧的结构,也应该在此之前立即剪标签。

我发现subclipse插件在提交已移动到新包(即尚未在源代码管理下)的类时提供错误消息“已经在版本控制下”, 并且此包的父级也是新的

发生这种情况时,我可以使用TortoiseSVN提交更改。 之后我只需要在Eclipse中刷新项目。

将类移动到其父级已在源代码管理下的新包后,subclipse可以毫无问题地提交此更改。

而不是重命名包,你可以这样做:

  1. 在项目中创建新的包结构。 完成后,您的项目应如下所示:

    com - |- myOLDcompname - | |- feature1 - | |- classA.java | |- classB.java |- myNEWcompname - |- feature1 
  2. 在版本控制下添加新文件夹,以便svn可以跟踪它们

  3. 将您的java类从旧包移动到新包。 Eclipse应该相应地更新所有类的import和package声明。 最重要的是因为旧的和新的包都在vcs下这一步应该保留类的历史。
  4. 完成后删除旧文件夹
  5. 承诺!