从 Mercurial 迁移后的奇怪 git 状态
Strange git state after migration from Mercurial
我一直在尝试使用 this answer 中提供的方法将我的 Mercurial 存储库迁移到 git。
存储库头部周围的一切似乎都运行良好。我可以看到我的标签、我的分支等等,一切都很好,而且一切似乎都在正确的地方。但是,在 Sourcetree 中检查它时,我发现了一些奇怪的事情。例如,这是我在存储库底部看到的:
如您所见,有很多分支似乎来自初始提交之前。
我已经探索了其中的一些,当有一个分支 parent 的日期比 child 更早时,问题似乎出现了(不要问我我是如何管理的这样做;我不知道)。这是上图中最右边绿线的示例:
我还发现一些线从图表的底部到合并没有任何提交,因此,在提交中它没有正确显示合并的来源:
这有解释吗?更好的是,在进行转换时有什么办法可以避免它吗?或者以后有什么办法可以解决?
警告:我对 TortoiseHg 及其迁移器一无所知(如您链接到的其他答案中所述),但 Mercurial 和 Git 呈现提交的方式存在显着差异,特别是在如何提交方面他们排序他们。
提交时间戳
... it seems like the problem appears when there is a branch where the parent has an older date than the child (don't ask me how I managed to do that; I have no idea).
这并不像人们想象的那么罕见。
除了明显的(计算机时钟设置错误的时间)之外,还有时区问题(在加利福尼亚进行的提交,比在纽约进行的提交早三个小时)。并非所有转换器都能正确解决这个问题,因为这是一个难题。
Mercurial 标签与 Git 标签
Mercurial 标签存储在一个文件 (.hgtags
) 中,然后将其存储为单独的提交(不幸的副作用是检查标记版本会使标签本身不可见,因为标签是用于具有缺少标记的 .hgtags
的提交)。看起来您的转换器正在将 Mercurial 标记提交存储为 Git 提交:并不特别令人惊讶(这样会更容易)但也不是特别理想(Mercurial 标记可能应该转换为 Git 注释或轻量级标签,如果可能的话)。
正在排序
默认情况下,Mercurial 按照存储库中的绝对提交编号对提交进行排序。 (这对于 hg
命令是正确的;像 TortoiseHg 这样的外部程序是否跟进取决于它们。)这意味着提交的日期戳 与呈现顺序完全无关 。 Mercurial 只能这样做,因为单个存储库中的每个提交在该存储库中都有一个本地唯一的索引号,以及一个在所有克隆中都相同的全局唯一标识符(SHA-1 哈希)。 (本地唯一的数字索引在不同的克隆中不一定相同,即使它们包含相同的提交,因为它取决于这些提交进入所有克隆的顺序。更具体地说,两个克隆开始时相同,但随后如果克隆 A 以该顺序获取提交 a111111 和 a222222,而克隆 B 以 a222222-then-a111111 的顺序获取它们,则这两个提交的索引号将以相反的顺序。)
默认情况下,Git 按日期排序,在较旧的提交之前显示较新的提交。在绘制图表时,这种排序顺序有所修改:在这种情况下 Git 仍然按日期排序,但 adds a topological sort constraint:
--topo-order
Show no parents before all of its children are shown, and avoid showing commits on multiple lines of history intermixed.
For example, in a commit history like this:
---1----2----4----7
\ \
3----5----6----8---
where the numbers denote the order of commit timestamps, git rev-list
and friends with --date-order
show the commits in the timestamp order: 8 7 6 5 4 3 2 1.
With --topo-order
, they would show 8 6 5 3 7 4 2 1 (or 8 7 4 2 6 5
3 1); some older commits are shown before newer ones in order to
avoid showing the commits from two parallel development track mixed
together.
并非所有绘图程序都使用相同的约束:特别是 gitk
进行自己的提交排序(它默默地吃掉 --topo-order
以避免将其传递给 git rev-list
)。
(一个相关的问题是 Mercurial 提交只有一个时间戳,而 Git 提交有两个:作者时间戳和提交者时间戳。由于您正在转换 hg-to-git 方向,不过,我会假设 git-commit-generator 只是将两个时间戳设置为与 Mercurial 时间戳相匹配。如果不是,那也可能会影响它。)
回到您的转换问题
I've also found some of the lines go from the bottom of the graph to a merge without any commits on them ...
这在 Git 中是不可能的,因为只有在合并中至少有两个父提交 ID 才能存在合并,并且父 ID 只有在这些提交对象存在时才有效。无论什么程序正在绘制图形都是错误的(或者只有当您以某种方式指示它不显示这些提交时才正确)。
Is there an explanation to this? An even better, is there any way to avoid it when doing the conversion? Or any way to fix it afterwards?
以上大概就是为什么;至于如何防止或改变它,来自为什么:你需要以某种方式捏造日期,以便它们以所需的顺序出现。
我一直在尝试使用 this answer 中提供的方法将我的 Mercurial 存储库迁移到 git。
存储库头部周围的一切似乎都运行良好。我可以看到我的标签、我的分支等等,一切都很好,而且一切似乎都在正确的地方。但是,在 Sourcetree 中检查它时,我发现了一些奇怪的事情。例如,这是我在存储库底部看到的:
如您所见,有很多分支似乎来自初始提交之前。
我已经探索了其中的一些,当有一个分支 parent 的日期比 child 更早时,问题似乎出现了(不要问我我是如何管理的这样做;我不知道)。这是上图中最右边绿线的示例:
我还发现一些线从图表的底部到合并没有任何提交,因此,在提交中它没有正确显示合并的来源:
这有解释吗?更好的是,在进行转换时有什么办法可以避免它吗?或者以后有什么办法可以解决?
警告:我对 TortoiseHg 及其迁移器一无所知(如您链接到的其他答案中所述),但 Mercurial 和 Git 呈现提交的方式存在显着差异,特别是在如何提交方面他们排序他们。
提交时间戳
... it seems like the problem appears when there is a branch where the parent has an older date than the child (don't ask me how I managed to do that; I have no idea).
这并不像人们想象的那么罕见。
除了明显的(计算机时钟设置错误的时间)之外,还有时区问题(在加利福尼亚进行的提交,比在纽约进行的提交早三个小时)。并非所有转换器都能正确解决这个问题,因为这是一个难题。
Mercurial 标签与 Git 标签
Mercurial 标签存储在一个文件 (.hgtags
) 中,然后将其存储为单独的提交(不幸的副作用是检查标记版本会使标签本身不可见,因为标签是用于具有缺少标记的 .hgtags
的提交)。看起来您的转换器正在将 Mercurial 标记提交存储为 Git 提交:并不特别令人惊讶(这样会更容易)但也不是特别理想(Mercurial 标记可能应该转换为 Git 注释或轻量级标签,如果可能的话)。
正在排序
默认情况下,Mercurial 按照存储库中的绝对提交编号对提交进行排序。 (这对于 hg
命令是正确的;像 TortoiseHg 这样的外部程序是否跟进取决于它们。)这意味着提交的日期戳 与呈现顺序完全无关 。 Mercurial 只能这样做,因为单个存储库中的每个提交在该存储库中都有一个本地唯一的索引号,以及一个在所有克隆中都相同的全局唯一标识符(SHA-1 哈希)。 (本地唯一的数字索引在不同的克隆中不一定相同,即使它们包含相同的提交,因为它取决于这些提交进入所有克隆的顺序。更具体地说,两个克隆开始时相同,但随后如果克隆 A 以该顺序获取提交 a111111 和 a222222,而克隆 B 以 a222222-then-a111111 的顺序获取它们,则这两个提交的索引号将以相反的顺序。)
默认情况下,Git 按日期排序,在较旧的提交之前显示较新的提交。在绘制图表时,这种排序顺序有所修改:在这种情况下 Git 仍然按日期排序,但 adds a topological sort constraint:
--topo-order
Show no parents before all of its children are shown, and avoid showing commits on multiple lines of history intermixed.
For example, in a commit history like this:
---1----2----4----7 \ \ 3----5----6----8---
where the numbers denote the order of commit timestamps,
git rev-list
and friends with--date-order
show the commits in the timestamp order: 8 7 6 5 4 3 2 1.With
--topo-order
, they would show 8 6 5 3 7 4 2 1 (or 8 7 4 2 6 5 3 1); some older commits are shown before newer ones in order to avoid showing the commits from two parallel development track mixed together.
并非所有绘图程序都使用相同的约束:特别是 gitk
进行自己的提交排序(它默默地吃掉 --topo-order
以避免将其传递给 git rev-list
)。
(一个相关的问题是 Mercurial 提交只有一个时间戳,而 Git 提交有两个:作者时间戳和提交者时间戳。由于您正在转换 hg-to-git 方向,不过,我会假设 git-commit-generator 只是将两个时间戳设置为与 Mercurial 时间戳相匹配。如果不是,那也可能会影响它。)
回到您的转换问题
I've also found some of the lines go from the bottom of the graph to a merge without any commits on them ...
这在 Git 中是不可能的,因为只有在合并中至少有两个父提交 ID 才能存在合并,并且父 ID 只有在这些提交对象存在时才有效。无论什么程序正在绘制图形都是错误的(或者只有当您以某种方式指示它不显示这些提交时才正确)。
Is there an explanation to this? An even better, is there any way to avoid it when doing the conversion? Or any way to fix it afterwards?
以上大概就是为什么;至于如何防止或改变它,来自为什么:你需要以某种方式捏造日期,以便它们以所需的顺序出现。