【问题标题】:I copy/pasted/modified a dependency in my project. This was not a smart dependency management strategy. How do I step back?我在我的项目中复制/粘贴/修改了一个依赖项。这不是一个聪明的依赖管理策略。我该如何退后一步?
【发布时间】:2026-01-29 15:50:01
【问题描述】:

上下文:

MainProject 依赖于仅标头依赖项Module

MainProjectModule 都是:

  • 仍在开发中,可能会修改
  • 现代 CMake 项目
  • Github 上的独立存储库
  • 由我控制

问题:

几个月前,我尝试使用 CMake 和版本控制来管理这种依赖关系,但没有成功。迫于最后期限,我最终选择了“最简单的解决方案”,将项目Module 的标题复制粘贴到MainProject 中。开发MainProject 导致在Module 本地副本 中添加功能和修改接口。现在有两个发散的Module

它是如何工作的

  • 如果Module 非常稳定,它可能会起作用(复制/粘贴标头实际上是我选择稳定且我没有所有权的依赖项的解决方案)。

  • 对于我想要进行的每个修改,我都可以修改/提交/推送/重新复制/重新粘贴 Module 存储库。但我当然没有,因为……时间和期限。

问题

现在我想退出这个解决方案(ie,反映对初始 Module 项目的修改)并选择更好的依赖管理策略。

我能想到的

  • Module git 项目上创建一个新分支update,复制粘贴修改后的版本,提交并使用git diff 检查与分支master 的差异
  • 使用这三种方法中的一种或组合使用(但我不知道如何选择)
    • git 子模块
    • git 子树
    • C++20 模块

【问题讨论】:

    标签: c++ git dependencies git-submodules git-subtree


    【解决方案1】:

    您的Module 项目实际上一个Git 子模块:一个独立更新的历史,您的MainProject 构建使用特定修订。

    开发MainProject 导致在Module 本地副本中添加功能和修改接口。现在有两个发散的Module

    最快:从您当前的MainProject 修订版的干净签出,

    git tag slice $(git commit-tree -m slice @:path/to/Module)
    git rm -rf path/to/Module
    git submodule add u://r/l path/to/Module
    git push path/to/Module slice
    cd path/to/Module
    git read-tree -um slice
    git commit -m 'Module content from MainProject'
    

    现在您的内容和祖先看起来可以使用了,您可以添加标签并将其推送到需要去的任何地方,例如git checkout -b MainProjectModule; git push -u origin MainProjectModule

    如果您的主项目中有很长的 Module 更改历史,并且您想保留在 Module 历史中,这是可行的,甚至相当有效,但您需要适应 @987654321 @ 来实现它,而不是标记 nonce 提交,而是标记命令生成的子模块提交并将其合并,而不是仅仅将其提示内容添加为新提交。

    【讨论】:

    • 感谢您的回答,它为我指明了方向。我不确定我是否遵循 git 命令的顺序以及它们的用途。你介意精确吗?据我了解,您创建一个标签来记住当前状态,然后删除模块文件夹,然后创建子模块。此时它包含天真的远程状态。因此,您以某种方式告诉它检索先前删除的文件夹的状态。我对吗 ?我没有得到git push path/to/Module slicegit read-tree -um slice 命令。再次感谢:)
    • 推送将那个 ref 即标签(只是那棵树的一个无祖先提交的标签)推送到 path 处的(新克隆的)存储库。 git read-tree -um 是底层结账的核心命令,它只改变索引和工作树。
    最近更新 更多