修改一个 Git 子模块并保留更改。

43
我已将我的一个库的git子模块克隆到我正在开发的项目中。问题在于,克隆后,我需要更改克隆的子模块中的一些行,但我不想将这些更改推送到原始仓库中。

我希望这些更改保留在超级项目中。这可能吗?我该如何实现?

编辑:如@GoZoner所说,基本上是:

  1. Git克隆 foo;
  2. cd foo;
  3. git submodule init;
  4. git submodule update;
  5. cd path/to/submodule;
  6. git checkout master;
  7. 更改子模块
  8. git commit -am“Something”;
  9. git push origin(超级项目);

然后,当我在另一台计算机上克隆超级项目(执行前4个步骤),我希望这些更改被保存在超级项目中。


当你说“我希望这些更改保留在超级项目中”时,你的意思是:当有人执行“git clone <superproject> foo; cd foo; git submodule init; git submodule update”时,他们应该拥有一个包含我对克隆子模块所做更改的工作目录? - GoZoner
@GoZoner 是的 - 但是子模块中的更改不应该被推送到其原始存储库。我会根据您的评论重新构建问题。 - AeroCross
正确,这就是我认为你在询问的内容,但我认为这是不可能的。Git会特别标记包含子模块的目录,并且不会在该目录之外查找“本地”更改。 - GoZoner
可能是Git-如何跟踪未跟踪的内容?的重复问题。 - user2486953
2个回答

14

我认为你需要放松对“不允许提交子模块”的限制。有两个选项:

  1. 将您的子模块更改提交到子模块分支中。这是您的团队分支,也是您的团队放置子模块更改的地方。当某人克隆超级项目并更新子模块时,他们会获得您的团队分支的内容。
  2. 在您的超级项目存储库旁边“克隆”子模块存储库,并初始化子模块以指向您的克隆。然后,当您提交对子模块的更改时,它们将提交到您的克隆。任何克隆超级项目的人都可以从您的子模块克隆获取子模块内容。

否则,我看不到实现您的愿望的方法。


1
这些其实是不错的替代方案。我不能实现我__真正__想做的事情,但这些是可行的选择。我想要对这些文件进行路径更改,这很基础,但在某些情况下知道该怎么做还是很好的。我认为将来我可能能够使用选项2和一些差异工具。谢谢! - AeroCross
我不明白“right next to”的意思。你能再详细解释一下吗?谢谢。 - ywu
1
@ywu 他可能是指在同一目录中克隆这两个存储库。 - Mit94
1
感谢 @Mit94 的回复。我理解为在超级项目仓库中拥有子模块仓库的副本(克隆)并将其带在身边。这不再是子模块,因为选项2中对该仓库所做的更改需要保存在超级项目仓库中。 - ywu
1
@ywu 看起来他很可能建议你将子模块 fork 到你们团队的版本控制中。它仍然是超级项目的子模块,但是 fork 的仓库现在是特定于超级项目的,你可以随意更改它。如果你的团队不拥有子模块仓库,这将是创建子模块分支的替代方法。但是,如果你想从主仓库拉取更新,仍然需要解决冲突问题。 - Jon Hieb
@JonHieb 是的,fork是可行的方法。如果我理解正确,fork的repo是独立托管在其他地方,而“超级项目”通过.gitmodules引用它。不确定这是否是GoZoner的意思,因为关键词“fork”不在其中。 - ywu

0
你可以为你的更改检出一个单独的分支。不要将该分支推到远程仓库。如果你想要推送的更改,那么就在原始分支之一上进行。然后将该分支合并到你不会推送的特殊分支中。不要在你的特殊分支上执行任何其他工作,否则你将不得不反向合并。虽然你可以这样做,但会变得更复杂。

1
如果我检出一个不会推送到原分支的不同分支,然后在那里提交,当我克隆存储库并初始化子模块时,引用将丢失。这是我发布之前尝试过的。除非我遗漏了什么,否则会出现缺失引用错误,我会回到起点。 - AeroCross
您需要使用确切的结构更新您的问题。抱歉。 - Adam Dymitruk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接