如何在不破坏 Subversion 历史的情况下重命名 Java 包?

Posted

技术标签:

【中文标题】如何在不破坏 Subversion 历史的情况下重命名 Java 包?【英文标题】:How to rename Java packages without breaking Subversion history? 【发布时间】:2011-01-29 23:10:41 【问题描述】:

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

我们使用:Eclipse、TortoiseSVN、Subversion

我发现somewhere 我应该分多个步骤来防止 .svn 文件夹的内容和 java 文件中的包名称不一致:

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

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

我没有那台服务器的密钥,这就是为什么我不会匆忙备份东西并尝试一两件事。我想提出一个不这样做的充分理由,或者一个可行的方法。

感谢您的帮助,

M.乔尼斯


包重命名测试

程序:

    创建一个新包 com.oldname.test.renametest.subpackage。

    在 renametest 下添加一个名为 RenameTest0.java 的新类,其中包含:

    类重命名测试0 
        公共重命名测试0()
            显示消息();
            新的重命名测试1();
        
        公共静态无效showMessage()
            System.out.println("重命名测试0!");
        
        公共静态无效主要(字符串[]参数)
            新的重命名测试0();
        
    

    在 renametest.subpackage 下添加一个新类,包含:

    类重命名测试1 
        公共重命名测试1()
            显示消息();
            重命名Test0.showMessage();
        
        公共静态无效showMessage()
            System.out.println("重命名Test1!");
        
    

    测试 RenameTest0 运行良好。

    提交。 更改两个类的消息。 提交。 再次,更改一个类的消息并提交(只是创建一些历史记录)。 应用上述程序(原始消息中的三个步骤)将包 renametest 重命名为 testrename。 提交。 试运行。 再次修改消息并测试。 提交。 尝试回滚到第一次同时更改两条消息时的版本。 如果到目前为止一切正常,它看起来不错,不是吗?

测试结果:

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

【问题讨论】:

不这样做的一个很好的理由是,这将是大量的工作(包括测试)而没有任何好处。如果您认为有人将开始在 com.oldname 空间中生成与您的库发生冲突的库,那可能是值得的,但域前缀的整个想法是为了保证唯一性,而不是为了满足营销人员。 我必须承认这是一个非常好的观点...... @Don Kirby & @Karussell:我会在今天或明天尝试运行测试,并在此处提供反馈。 刚刚添加了我昨天晚上做的第一个包重命名测试的过程+结果。 【参考方案1】:

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

在你做所有事情之前用一个包测试它只是为了确保你做的所有步骤都是正确的。

【讨论】:

【参考方案2】:

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

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

so:如果历史记录与 subversion 插件一起保存,您是否在 eclipse 中尝试过? (例如,在新的签出副本中以避免失败)

至少您可以使用 NetBeans 完成这项一次性任务...

【讨论】:

+1 :即使问题是关于日食的,这对我有很大帮助。 netbeans 插件对我来说很好用。 (在进行重构之前,请务必使用插件更新代表,而不是使用其他 svn 客户端)【参考方案3】:

可以做到这一点,这并不难 - 获得干净的 SVN 历史记录的最佳选择是分两步完成(可以成为一次提交) - 尽管我建议获得良好的结果使用 CLI 客户端。

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

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

如果您使用的是 Maven 或打包工具,建议您在执行此类操作之前先运行一个版本 - 此外,在此之前立即删除一个标签以防您需要返回旧结构

【讨论】:

【参考方案4】:

您是否考虑过使用Subclipse plugin?根据How do I use Eclipse Refactoring Tools and stay in sync with SVN through Subclipse?,它可能会解决您的问题

【讨论】:

【参考方案5】:

也许它不适合您的确切需求,但 TortoiseSVN 有一个方便的重命名功能。你可以这样做:

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

Repair moves/renames

【讨论】:

但是如果你还安装了像 Subclipse 这样的 Eclipse SVN 插件,这将不起作用,对吧?【参考方案6】:

我发现 subclipse 插件在提交已移至新包(即尚未受源代码控制)的类时给出错误消息“已在版本控制下”并且此包的父级是也是新的

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

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

【讨论】:

【参考方案7】:

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

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

           com -
               |- myOLDcompname -
               |                |- feature1 -
               |                            |- classA.java
               |                            |- classB.java
               |- myNEWcompname -
                                |- feature1
    

    在版本控制下添加新文件夹,以便 svn 可以跟踪它们

    将 Java 类从旧包移到新包。 Eclipse 应该相应地更新所有类的导入和包声明。最重要的是,因为新旧包都在 vcs 下,所以这一步应该保留类的历史记录。 完成后删除旧文件夹 提交!

【讨论】:

以上是关于如何在不破坏 Subversion 历史的情况下重命名 Java 包?的主要内容,如果未能解决你的问题,请参考以下文章

在不破坏现有迁移的情况下重命名 Django 模型

我们如何在不丢失数据的情况下重定向到相同的视图

如何在不丢失当前页面的情况下重绘数据表

如何在不重复的情况下重试芹菜任务 - SQS

如何在不重新加载 HTML 页面的情况下重定向锚标记链接?

如何在不使用 React Native 中的堆栈导航器的情况下重定向到页面?