如何解决涉及分支的Mercurial案例折叠碰撞?

时间:2017-12-30 18:21:01

标签: merge mercurial case-sensitive

今天我将一个分支合并回一个旧分支,并告诉我由于案例折叠碰撞而无法更新到原始分支。

我的回购看起来有点像这样:

  • 默认分支,修订版1:添加大多数文件。
  • 默认分支,修订版2:添加文件xyzXYZ。据推测是在Linux机器上完成的。这是在2008年。
  • 默认分支修订3-35:各种其他更改,没有问题
  • 修订版36:添加了新功能分支
  • 功能分支,修订版71:Windows上的通知,Sourcetree报告xyz已被删除,所以我提交了,这就变成......
  • 功能分支,修订版72:这是明确删除BOTH xyzXYZ
  • 的更改

此时,我想将功能分支合并回默认值,但是当xyz不在回购时,它不会让我更新回版本71或除版本1之外的任何其他版本所有。显然,从2到71的每个变化都被污染了#39;使用这两个文件,我只能在Windows和Mac计算机上查看为1。

通常建议的解决方案 - https://www.mercurial-scm.org/wiki/FixingCaseCollisions - 不起作用:它说" hg状态应该显示处于状态的麻烦文件' R'状态''" 中的所有其他文件,但是当我按照步骤操作时,它实际上显示了状态' M'中的所有其他文件,这是显然不是我想要的,并暗示如果我继续进行会发生一些数据丢失。

此外,我怀疑我永远无法在Windows或MacOS上执行所需的合并,因为我需要修订版35才能处于可用状态,然后才能将任何内容添加到其中。

我有什么办法可以解决这个问题吗?我的所有文件都是安全的,我也愿意丢失xyz文件中的所有数据和修订版本以使这个repo再次运行,但我真的不想完全丢失repo和changelog。

3 个答案:

答案 0 :(得分:0)

我找不到合适的解决办法,所以我不得不借用一个Linux机箱来获得区分大小写的文件系统。然后修复是:

  1. 将整个存储库复制到安装了Mercurial的Linux计算机上。
  2. 恢复/更新到默认分支上的最新修订版,该分支在工作副本中包含具有冲突名称的2个文件,并hg rename将它们更改为未冲突的名称。从那时起重新应用任何其他更改。
  3. 更新到另一个分支的修订版,做同样的事情。
  4. 正常执行合并。
  5. 将repo和工作目录复制回Windows。
  6. 删除/重命名/修改2个重命名的文件,以便只剩下1个,无论名称是什么。
  7. 步骤4和5可能已按任何顺序完成。

答案 1 :(得分:0)

如OP所述,管理所述类型案件冲突的指导的主要资源是https://www.mercurial-scm.org/wiki/FixingCaseCollisions

那里给出的指示可能不尽如人意,所以这里有一个基于其中一个程序的带注释的成绩单。

我们从名为“repo”的存储库开始,该存储库有两个文件:a.txtA.txt。在远程计算机上:

REMOTE_MACHINE $ hg files
A.txt
a.txt

现在让我们假设repo已经以某种方式被克隆到本地机器(发生案例折叠问题的计算机)上。这可能是使用如下命令完成的:

$ hg clone --noupdate "ssh://REMOTE/DIRECTORY/repo" # illustrative

如果您不想在本地计算机上更改repo,那么您可以(例如)克隆它,如下所示:

$ hg clone --noupdate repo xrepo  # illustrative and optional 

现在cd进入要修改的存储库的目录,例如

$ cd repo   # or perhaps: cd xrepo

您可能想要验证存储库的完整性:

$ hg verify

接下来是两行黑魔法:

$ hg debugsetparents tip 
$ hg debugrebuildstate

此时,Mercurial会认为你签了tip, 并且所有文件都丢失了(状态'!')。在我们的案例中:

$ hg st -dram
! A.txt
! a.txt

现在我们将运行一些普通的hg命令来解决大小写折叠问题。让我们首先手动提取感兴趣的文件:

$ hg cat a.txt > lc.a.txt
$ hg cat A.txt > uc.A.txt

现在从repo中删除两个有问题的文件:

$ hg -v remove --after a.txt A.txt
removing A.txt
removing a.txt

(上面的--after选项指示Mercurial处理被删除的文件(来自存储库)不在磁盘上的事实。)

现在我们恢复正常了。我们可能想要检入我们的重命名文件:

$ hg -v add lc.a.txt uc.A.txt
adding lc.a.txt
adding uc.A.txt

$ hg st -dram
A lc.a.txt
A uc.A.txt
R A.txt
R a.txt

$ hg commit --message "renamed a.txt to lc.a.txt and A.txt to uc.A.txt"
$ hg files
lc.a.txt
uc.A.txt

$ cat lc.a.txt
lowercase a
$ cat uc.A.txt
uppercase A
$

# Verify that the original files are still there:
$ hg files --rev 0
A.txt
a.txt

此时,要检出所有其他文件,您可以运行:hg revert --all

答案 2 :(得分:0)

我暂时没有这样做,但我过去使用过转换扩展程序来清理Windows上的案例折叠。

注意:我假设这是一个基本上私有存储库,您可以独占访问。如果是这种情况,那么这种方法就可以了。 (即使不是这种情况,这仍然可以在技术上有效,但您必须将其作为新的回购发布给其他人,因为下面描述的转换将生成所有新的变更集ID。)

您可以使用转换扩展程序Mercurial和filemap选项。

来执行此操作
  

转换可以...在转换过程中重命名文件   通过--filemap选项为它提供映射。

     

filemap是一个文件,指定要包含哪些文件,   重命名或省略。

     

每一行都可以包含以下指令之一:   ...

rename from/file to/file
     

...

     

重命名指令重命名文件或目录。要重命名   子目录进入存储库的根目录,使用。作为通往   重命名为。

执行此操作的命令行将类似于:

hg convert --filehmap filemap.txt path\to\source\repo path\to\converted\repo

filemap.txt必须包含以下内容:

rename path\to\XYZ path\to\xyz_which_was_uppercase

转换过程应该在所有分支上重命名XYZ的所有“实例”,因此我认为涉及分支的事实变得无关紧要。

Documentation.