编辑自http://git-scm.com/book/en/Git-Tools-Submodules
在这种情况下会出现一个常见问题:您希望能够将每个项目视为单独的项目,但仍然能够在另一个项目中使用其中一个。包含该库的问题在于,很难以任何方式自定义该库,而且通常更难以部署它,因为您需要确保每个客户端都有该库可用。将代码供应到您自己的项目中的问题是,当上游更改可用时,您所做的任何自定义更改都难以合并。Git 使用子模块解决了这个问题。子模块允许您将 Git 存储库保留为另一个 Git 存储库的子目录。这使您可以将另一个存储库克隆到您的项目中并保持您的提交分开。
您应该做的第一件事是将外部存储库克隆到您的子目录中。您可以使用以下命令将外部项目添加为子模块:
git submodule add
您可以进入该子目录、进行更改、添加自己的可写远程存储库以将更改推送到、从原始存储库获取和合并等等。如果您在添加子模块后立即运行 git status,您会看到两件事:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: .gitmodules
# new file: <name_of_cloned_repo>
#
首先你注意到 .gitmodules 文件。这是一个配置文件,用于存储项目 URL 和您将其拉入的本地子目录之间的映射:
$ cat .gitmodules
[submodule "rack"]
path = rack
url = git://github.com/chneukirchen/rack.git
尽管它是您工作目录中的一个子目录,但 Git 将其视为一个子模块,并且当您不在该目录中时,它不会跟踪其内容。相反,Git 将其记录为来自该存储库的特定提交。当您在该子目录中进行更改并提交时,超级项目会注意到那里的 HEAD 已更改并记录您当前正在处理的确切提交;这样,当其他人克隆这个项目时,他们可以准确地重新创建环境。
这是子模块的重要一点:您将它们记录为它们所在的确切提交。您不能在 master 或其他一些符号引用处记录子模块。
您可以将该目录视为一个单独的项目,然后使用指向该子项目中最新提交的指针不时更新您的超级项目。所有 Git 命令在两个目录中独立工作......