2011-10-28 29 views
6

我真的很沮丧使用git的子模块功能。要么我仍然没有把它做好,否则就不能正常工作,因为我期待着这一点。以下项目情况给予:Git submodule mess:如何将git子模块与不熟悉git的开发者一起使用?

Project 
    | .git 
    | projsrc 
    | source (submodule) 
    | proj.sln 

在这种情况下指向容纳我们所有的项目共源数据的另一个仓库。在以及projsrc之下有很多发展。不幸的是项目指向源子模块的一些提交而不是它的实际HEAD。就我所知,这是通常的git行为。

我已经发现了

git submodule update 

刚刚获得其与主体工程同时COMMITED子模块的版本。但是,我真的希望始终与子模块开发保持同步,但是没有任何真正的线索如何做到这一点。因此,我的问题是:

是否有可能在项目连接到子模块的HEAD, reagardless的事实,这是否会打破项目或不汇编。 我只是不想总是进入子模块 目录,并做git拉那里。因为我认为我可以在子模块目录中删除我的更改 ,因为它简单地附加到 提交,而不是真的到任何分支左右。

请考虑以下限制

  • 开发者在我们的小组是不是熟悉周围的所有VCS。我们之前习惯使用真正庞大的svn仓库,根本没有任何外部回购功能。
  • 我们正在努力在Windows
  • 一个click'n'forget解决方案是最好的,因为大多数项目成员通过使用命令行界面:)
+1

另请参阅http://stackoverflow.com/questions/1979167/git-submodule-update/1979194#1979194和http://stackoverflow.com/questions/3131912/为什么是git-submodules-incompatible -with-svn-externals/3132221#3132221 – VonC

+0

“我可以放弃在submodule目录中完成的更改,因为它很简单地附加到承诺,而不是真的任何分支“这不是真的!总是有一个分支。当你处于独立状态时,你不会失去你的改变。 – Vanuan

回答

7

的原因,而害怕,为什么一个子模块点对特定的修订很重要。如果你指向一个HEAD,版本将是不可复制的。即如果您昨天签出了该项目的一个版本,则永远不会知道source @ HEAD昨天的确切版本。

这就是为什么它总是存储特定的修订版本。

拉你可以使用Easy way pull latest of all submodules

+0

我完全同意他们会打破,但我对这种情况确定。我只是很烦恼地解释每个在我的**项目上合作的非熟悉的开发人员**,子模块**源代码**不能像预期的那样工作。对于那里的任何变化,他们总是承诺/推动源头。更重要的是,如果他们只是在项目中执行_git子模块update_,那么他们会放弃对_source_所做的所有更改,因为它们被该特定修订覆盖。 – cgart

+0

'submodule update'不会删除任何更改,因为我知道它只是检出引用的修订版本。所做的更改仍然处于回购状态,您可以检出它们,然后更新** Project **以引用修订版并将子模块修订版引用提交到主项目。 – kan

+0

如果您还没有提交并推送它们,也会删除您的更改(因为还没有推送父级更改)。由于源/是具有分离HEAD的子模块(默认行为),git子模块更新总是会使源/目录处于父存储库指向的状态。在我看来,这是非常糟糕的git行为,因为它甚至没有通知我我的本地更改会被覆盖(git 1.7.7) – cgart

2

我不擅长Git和子模块的所有子模块。但我认为一些简单的规则会非常有帮助。

  1. 从子目录提交并推送。
  2. 返回到项目的根目录,如果需要提交并再次推送,请检查状态。

当拉。可以尝试使用脚本将“拉/子模块更新”捆绑在一起。只有在你的项目的根源才能做到。

2

考虑一下:

  1. 源指向HEAD(正如您希望)。
  2. 你对你内部的源进行了更改项目(你提交但不推送它们)
  3. 现在你有两个HEAD:一个在你的项目源中,另一个在你的公共源中。

当您进行子模块更新时,您希望出现在您的项目中的哪一个?

在你的情况下git的问题(和主要特征)是你认为承诺和推动原子操作。事实并非如此。 Git是分散的。没有常见的HEAD。你可能有多个仓库和不同的HEAD。

考虑一下:

  1. 你有3个开发(A,B和C)用Git项目。
  2. 他们都拉一个项目的HEAD。
  3. 每个开发人员已经对项目
  4. 进行了更改,现在他们每个人都有3个头:头,B头和C头。

你认为哪个HEAD“HEAD”?

所以,回答你的问题:如果你想共同的源子模块总是与中央存储库同步,git不是你的选择。可能没有任何VCS可以帮助你。

你应该把git的子模块作为一个第三方库,它应该手动与这两个步骤进行更新:

  1. 拉你的子模块(“下载第三方库”)
  2. 与更新子模块提交您的项目(”第三方库的新版本放置到您的项目“)

如果你想更改子模块,你应该做同样以相反的顺序:

  1. 提交你的子模块(“进行更改到第三方库”)
  2. 把你的子模块(“送你更改第三方库的维护者”)
  3. 与更新子模块提交您的项目(“放置新版本的第三方库到您的项目“)
+0

感谢Vanuan。是的,我知道我有git的想法。你可能是对的,它可能不是正确的选择。问题在于,与以前使用的svn相比,花了很长时间才能理解git实际上在做什么。我已经非常害怕向我的合作开发人员解释这一点......不过,我认为我已经发现我的工作流使用了git。 – cgart

+0

不要害怕解释。 Git和分布式版本控制一样简单。你的合作开发者必须明白的一件事是每个git repo副本都是自包含的本地“svn-server”。 “服务器”之间同步的需求是git无法实现某些功能的原因。 – Vanuan