来自 Github 的 hg-git 克隆给出“中止:存储库不相关”

2024-04-06

我有一个项目,其主要 (Mercurial) 存储库位于 SourceForge 上,但在 Bitbucket (Mercurial) 和 Github (Git) 上有克隆。

现在我一直在使用hg-git https://bitbucket.org/durin42/hg-git将 Mercurial 存储库推送到 Github,据我了解该过程,一些元数据在此过程中保存在 Mercurial 存储库中。

现在,当重新克隆 Bitbucket 存储库并重新克隆 Github 存储库时,如果我发出hg pull ../github-repo I get:

pulling from ../github-repo
searching for changes
abort: repository is unrelated

为什么会这样?我怎样才能让 Mercurial 相信它们确实是相关的?或者我是否必须依赖我最初推送到 Github 的原始存储库?我仍然拥有它,但假设我失去了它,除了手动变更集移植之外,我还有什么选择?


注意:由于拉取请求,Github 存储库已更改(新变更集)。但 SourceForge 和 Bitbucket 存储库仍然认为彼此相关。现在的任务是将变更集从 Github Git 存储库拉取到本地,并将它们分别推送回 SourceForge 和 Bitbucket。


相关或不相关位基本上来自两个存储库是否共享公共根,即初始变更集。

为了强行拉动,你可以对移植物或移植延伸物做一些邪恶的事情,但这可能会产生连锁反应,而且你似乎反对这样的解决方案 - 我也会!

要了解出现问题的原因,您需要了解一些 Hg-Git 的工作原理。

Hg-Git 的工作原理

Tl;dr

真正的问题是 Hg-Git 基本上是动态创建一个新的存储库。因此,这两个存储库不相关,原因与hg convert some-existing-hg-repo与原始存储库无关。到目前为止您还没有注意到它,因为 Hg-Git 也在另一个方向上执行此操作 - 当您从 Mercurial 存储库启动时,它会创建必要的 Git 存储库。当您第一次开始克隆到 GitHub 时,您在其服务器上创建了一个裸 Git 存储库,该存储库出于所有意图和目的与每个存储库相关。因此,您的推送由 Hg-Git 创建的新 Git 存储库是相关的,并且一切正常,没有问题。之后,您从同一个存储库进行推送,所以再次没有问题 – Hg-Git 跟踪本地 Git 和 Hg 存储库之间的关系,因此您的关系得以维持。但是,当您重新开始时,您创建了一个新的 Git 和/或 Hg 存储库(取决于您要进入的方向),并且对应关系被破坏。

稍微不那么过于简单化

Hg-Git 的工作原理是创建一个隐藏的 Git 存储库,并在 Git 和 Hg 存储库的提交之间建立对应关系。 Hg-Git 是一个双向桥梁,也就是说,它能够获取 Git 提交并生成 Hg 提交,反之亦然。 Hg-Git 通过使用用 Python 编写的 Git 库来实现双语(dulwich https://www.samba.org/%7Ejelmer/dulwich/)并作为扩展链接到 Mercurial。这意味着Hg-Git 无需安装即可读取和写入 Git 存储库git二进制 / 安装的 Git 参考实现。然而,Hg-Git 是一个 Mercurial 扩展,因此依赖于 Mercurial 系统来实现 Mercurial 交易端以及用户界面。这就是为什么有人努力创建反向接口(Git-Hg等),以便Git用户可以使用Git与Mercurial交互。

现在,是否创建 Git 或 Hg 存储库取决于混合存储库最初是如何创建的。由于您来自规范的 Mercurial 方面,因此我们将从这里开始。

当您在 GitHub 或 Bitbucket 上创建存储库时,它最初是裸露的且无提交的,因此与每个存储库相关 - 这是在存储库创建时默认不进行初始提交的部分动机。 (对于 Git 和 Mercurial 都是如此。)存储库相关性基于根节点。因此,任何存储库都可以推送到这个新存储库。当你跑步时hg push ssh+git://[email protected] /cdn-cgi/l/email-protection/user/some-git-repoHg-Git 第一次在本地文件夹中创建一个新的隐藏 Git 存储库,然后使用 Git 协议进行通信并将更改推送到远程。从此,两个存储库之间的通信应该没有问题了——从根节点和父子关系的初始转换,就可以实现两个存储库的变更集之间的一对一映射。 (这并不是 100% 正确,特别是如果您使用 Git 或 Mercurial 的更高级、更惯用的功能,但现在就足够了。)我很确定 Hg-Git 跟踪的信息比这多一点,如果没有其他原因,只是为了通过连续的推拉来加快速度。因此,当您从 Mercurial 克隆开始时,您的“原始根”就是 Mercurial 根,并且会根据需要创建和维护 Git 存储库。

现在,如果您不是从本地 Mercurial 克隆开始,而是从远程 Git 克隆开始,那么您实际上会结束从 Git 克隆创建一个 Mercurial– “proto-root”是 Git 根。更准确地说,当你跑步时hg clone ssh+git://[email protected] /cdn-cgi/l/email-protection/user/some-git-repo,Mercurial 启动,检查以确保它可以与远程连接(可以在 Hg-Git 的帮助下实现),然后创建目录并调用必要的扩展,即 Hg-Git。然后 Hg-Git 创建一个隐藏的.git文件夹在你的.hg文件夹,执行 Git 克隆,然后将 Git 存储库转换为 Mercurial 存储库;一旦克隆完成,它就会调用hg update,它直接在 Mercurial 存储库上运行,而无需完全了解 Git 存储库。

我怀疑这就是你的案例中出现的问题。当您从 GitHub 进行新克隆时,您实际上创建了一个新的 Mercurial 存储库,这当然与您的原始存储库无关 - 与hg convert与原作无关,即使变异的提交不包括最初的提交。 (这有点像当你将某些内容翻译成另一种语言并再次翻译回来时,你并不总是能得到原始形式。)出于各种原因,我怀疑 Hg-Git 以与时间无关且确定性的方式执行其转换(几乎肯定是后者,但它可能会添加有关转换本身的额外元数据,这意味着不是前者)。如果是这种情况,那么您应该能够从规范的 Hg 克隆开始并重新创建与 Git 存储库的连接。 (是的,初始转换的方向性会产生影响,这有点问题,但是最好与开发人员自己讨论导致这种情况的设计决策的利弊。)

回到混合 Hg-Git 存储库的结构。这里有两件有趣的事情:

  1. Mercurial 或多或少完全忽略了与 Git 远程通信时发生的额外翻译,

  2. 有一个完整的 Git 存储库隐藏在视图之外,偶尔会同步到 Mercurial 存储库。

重要的是,您实际上可以通过系统 Git 直接操作隐藏的 Git 存储库。如果您使用 Hg-Git,则 Git 存储库仅在向远程 Git 克隆推送和拉取时同步,这意味着那些本地直接 Git 更改将与 Mercurial 存储库不同步 - 在最坏的情况下,您提交了一个几次提交到 Git,然后在不同步的情况下提交到 Mercurial,并有效地创建两个单独的分支,因为 Hg 提交和 Git 提交共享一个共同的祖先,但并不相互构建。然而,Hg-Git 提供了一种通过以下方式手动强制存储库之间同步的机制:hg gimport [git-repo-to-import-from-if-not-local-hidden] and hg gexport(默认导出到本地隐藏副本,如果需要则创建它)。强制此同步还应该为您提供一种处理您注意到的问题的方法。您可以使用 Git 来拉取(或者用 Git 术语来说,fetchgit pull相当于hg pull --update; git fetch is hg pull,这使得 Mercurial fetch 扩展的名字真的很不幸)将新的变更集放入 Git 存储库中,然后使用hg gimport将这些变更集导入到 Mercurial 存储库中。

现在,如果您做了类似编辑历史记录之类的事情,那么所有的赌注都会被取消。我不确定 Hg-Git 将如何处理这个问题 - 我怀疑它最终会创建双打。 Mercurial 克隆中的新提交将添加到 Git,但已删除的变更集仍在 Git 存储库中,并且可能会被导入回 Mercurial 存储库。 (这是 Hg-Git 离线同步变更集的方法的直接结果。)在这种情况下,我建议选择一个规范存储库,擦除所有克隆,然后进行新的推送,并向每个因这次混乱而使克隆失效的人道歉。 。 (顺便说一句,这也是 Mercurial 社区对编辑历史如此谨慎的部分原因。)

潜在的解决方案

  1. @EmilSit 建议你跑步hg pull git+ssh://github.com/you/githubrepo.git直接来自规范(非 GitHub 克隆)Mercurial 存储库。假设 Hg-Git 创建初始 Git 克隆的方法完全与时间无关且具有确定性,那么这很有可能起作用。 (后者几乎肯定是正确的,但我不确定前者,请参阅上面的文字了解更多详细信息。)

  2. 您可以执行此操作的本地变体:使用git clone ssh://github.com/you/githubrepo.git获取本地纯 Git 克隆,然后执行hg pull ../githubrepo。 (这要求您安装了 Git。)Hg-Git 应该会自动启动并进行转换。该转换还依赖于 Hg-Git 以确定性、与时间无关的方式进行转换。

  3. 您可以直接对原始混合存储库中隐藏的Git存储库进行操作。使用git fetch(您可能首先必须cd进入.git文件夹隐藏在.hg首先是文件夹)。然后运行hg gimport && hg update从 Git 存储库导入更改并更新。 (您可能已指定路径gimport- 任何一个.或隐藏的 Git 存储库的路径。我怀疑你也可以指定 GitHub 路径。)

  4. 您可以使用各种哑移植方法(导出补丁系列等)并手动提交它们。如果您想在手动提交时给予其他开发人员信用,那么您可以使用-u选项以每次提交为基础设置用户。

  5. 您可以使用以下任一方式进行智能移植graft http://www.selenic.com/hg/help/graft or 移植 https://mercurial-scm.org/wiki/TransplantExtension扩展。首先,使用 Hg-Git 对 GitHub 存储库进行新的 Mercurial 克隆。然后使用这些扩展之一将两个 Mercurial 存储库合并在一起。

至少一种非移植方法should之所以有效,是因为除非 Hg-Git 的魔力依赖于时间,否则应该有可能找到一个共同的根。即使找到了共同的根,您也可能会得到两个基本上重复的(未命名的)分支,然后您必须将它们合并在一起。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

来自 Github 的 hg-git 克隆给出“中止:存储库不相关” 的相关文章

  • 如何使用 .gitattributes 避免在 git root 中包含文件夹,但在 zip 的 dist 文件夹中包含同名文件夹

    我有一个名为lib在存储库的根目录和另一个名为lib在 dist 文件夹中 我正在尝试使用 gitattributes文件排除除 dist 之外的所有文件夹和文件 以便任何下载为 zip 或 tarball 的人都只会 git 分发文件 我
  • vscode通过SSH连接gitlab的问题

    我在尝试通过 SSH 连接到 GitLab 远程存储库时遇到问题 这里是迄今为止完成的步骤 成功生成 SSH 密钥 管理人员将密钥添加到存储库中 因此当我访问 GitLab 网站时 我可以提交和发布分支 我无法从 VSCODE 发布分支并收
  • DVCS命令的统一

    当处理多个 开源 项目时 多个版本控制系统开始出现问题 虽然它们共享共同的操作 但我经常在输入时犯错误hg add反而git add 我记得前段时间看到过一个项目 通过提供基本命令以统一的方式访问不同的源代码控制软件提交 ci add等在外
  • 运行“git apply”时出错

    当我尝试时 您能否告诉我如何解决 补丁不适用 错误 git 应用补丁 git apply 0001 my patch error patch failed test xml 114 error text xml patch does not
  • 无法使用 git 配置文件进行 ssh

    我知道它被问了很多次 但我无法得到我的问题的答案 我正在尝试使用配置文件 ssh 到系统 配置文件是 Host qa HostName 10 218 70 345 User user IdentityFile C Users bean ss
  • Jenkins git 插件 - 有时太慢

    以下内容摘自 Jenkins 日志 00 00 03 135 gt git fetch tags progress email protected cdn cgi l email protection some org some repo
  • SSH 到 Openshift 服务器失败

    我正在 openshift 服务器上使用 jboss catridge 我希望与其他人共享此实例并添加其他用户的公钥 id rsa pub 当其他人尝试访问该实例时 他会收到以下错误 我在他的实例中尝试了同样的方法 但看到了同样的错误 与
  • 代表 Git 存储库的数学结构是什么

    我正在学习 Git 如果我能描述一下代表 Git 存储库的数学结构 那就太好了 例如 它是一个有向无环图 它的节点代表提交 它的节点有代表分支等的标签 每个节点最多一个标签 没有标签使用两次 我知道这个描述不正确 我只是想解释我正在寻找的内
  • 远程测试时如何搭建git开发环境

    这似乎是一个愚蠢的问题 但我觉得我对 GIT 相当了解 但我似乎无法按照我的意愿设置我的开发环境 我要么错过了一些非常简单的东西 要么我做错了 我在我的服务器上初始化了一个裸 git 存储库 将其克隆到我的本地计算机 提交我的文件并推送到原
  • git pull,忽略深度,如何不拉取整个历史记录?

    我们有一个巨大的多 GB git 存储库 主要是二进制对象 克隆需要几天时间 实际的主分支 没有历史记录 只有大约 20MB 所以我想 深度为 1 的 git 克隆就是解决办法 然而 现在我需要将某人的更新拉到主服务器 我们没有分支 当我拉
  • 在 github 上的 fork 中跟踪上游的最佳实践

    摘要 对于要维护一组本地更改的上游存储库 处理长期运行跟踪的最佳实践是什么 我想让 github 上的 fork 与上游保持同步 但仍然允许清晰跟踪 fork 特有的更改 对于本次讨论 假设upstream指向主项目存储库并且origin指
  • 有谁知道类似于 SVN Time-Lapse View 的 Git 工具 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 SVN Time Lapse View 是一个跨平台查看器 可以下载文件的所有修订版本 并允许您通过拖
  • 如何正确使用“mvn release:prepare”?

    我尝试了这个命令 用dryrun在我的 Maven 项目上进行测试 mvn release clean release prepare DdryRun true DgenerateBackupPoms false Dtag solocal
  • `git ls-files -s` 输出中不同字段的含义是什么?

    在 Git 中 命令返回的典型结果行git ls files s好像 100755 be2c2e9b0966253096472d4b482c458bc892e493 0 gitignore 这些字段是什么意思 不用再犹豫了git ls fi
  • git reset 命令中的 ~1 是什么意思?

    git 重置 HEAD 1 我的印象是 1 的意思是 从 HEAD 开始 遵循 1 链接 并将 HEAD 标签设置为新的提交节点 我正期待着 git 重置 HEAD 2 跟随 2 个链接 然后设置 HEAD 标签 但是 如果我尝试它 我会收
  • git 匹配多个单词的标签

    我们可以得到最后一个 git 标签 它以一个单词 例如 TEST 开头 如下所示 git describe tag dirty match TEST 我想知道如何获得最后一个以 word1 开头的标签orword2 例如测试OR跑步 我尝试
  • 如何合并两个连续的 git 存储库

    我有一个相当独特的情况 我有一个名为 Project1 的存储库 我在其中工作了一些时间 几个月 一年后 我创建了存储库 Project1 Again 从 Project1 停止的地方开始 现在 我希望修订历史记录是连续的 因此我希望它们合
  • git config --global user.email 重新安装后不会让我更改电子邮件

    嘿 我完全重新安装了 Github 删除了所有文件 现在我再次安装了它 但是当我尝试设置它时 我遇到了一些问题 git config global user email 电子邮件受保护 cdn cgi l email protection
  • git 别名中的 AWK 语句

    我正在尝试创建一个 git 别名来以特定格式打印日志中的所有拉取请求 但是 我在使用 AWK 删除双空格时遇到问题 这是使用以下命令的 git log 的输出 git log merges grep pull request pretty
  • 我可以直接从我的谷歌云端硬盘在线推送/拉取吗?

    有一些方法可以通过谷歌驱动器同步 Windows 应用程序将我的本地 git 存储库同步到我的谷歌驱动器 但我想知道我是否可以完全绕过它的需要 Fro eg git remote add origin https drive google

随机推荐