Git Submodule
Git Submodule (Git子模块)
What is Submodule
What is Submodule (什么是子模块)
Very often, the code repository depends on the external code from other repositories. You can directly copy and paste the external code into the main repository, or you can use the method of language’s package management system. But these two methods have the downside of not tracking changes to the external repository. Git allows including other Git Repositories called submodules into a single repository. Submodules allow tracking changes in several repositories via one repository. Submodules are repositories included in the parent repository at a specific path in the working directory of the parent repository. They can be located anywhere in the working directory and are configured via the .gitmodules file, which is located at the root of the parent repository. The .gitmodules file contains metadata about the mapping between the submodule project’s URL and local directory. Submodule supports adding, synchronizing, updating, and cloning submodules. Submodules track only specific commits, not the git references and branches.
When to Use Submodules
When to Use Submodules (何时使用子模块)
Working with submodules is tricky, so we suggest some best use cases for them. (使用子模块很棘手,因此我们为它们提出了一些最佳用例。)
If the subproject is changing too fast or upcoming changes will break the API, lock the code to a specific commit for safety. (-如果子项目更改太快或即将发生的更改会破坏API ,请将代码锁定到特定的提交,以确保安全。)
If a component isn’t updated very often, and you want to track it as a vendor dependency. (-如果组件不经常更新,并且您希望将其作为供应商依赖项进行跟踪。)
If you represent a part of the project to a third party, and you want to integrate their work at a particular time (works only when updates are not too frequent). (-如果您向第三方代表项目的一部分,并且您希望在特定时间整合他们的工作(仅在更新不太频繁时才有效)。)
If the technological context allows packaging and formal dependency management, you should use submodules. (-如果技术上下文允许打包和正式的依赖关系管理,则应使用子模块。)
If your codebase is massive and you don’t want to fetch it every time, use submodules so as not to make the collaborators fetch the entire blocks of the codebase. (-如果您的代码库很大,并且您不想每次都获取它,请使用子模块,以免让协作者获取代码库的整个块。)
Commands for Git Submodules
Commands for Git Submodules (Git子模块的命令)
For creating a new submodule to the existing repository, use git submodule add. This sets of command create a new directory, enter it, and initialize it as a new repository:
mkdir git-submodule-demo
cd git-submodule-demo/
git init
Initialized empty Git repository in /Users/example/git-submodule-demo/.git/
To add a submodule to the new repository run the following:
git submodule add https://somehost/example/textexample
Cloning into '/Users/example/git-submodule-demo/textexample'... remote: Counting objects: 8, done. remote: Compressing objects: 100% (6/6), done. remote: Total 8 (delta 1), reused 0 (delta 0) Unpacking objects: 100% (8/8), done.
The git submodule add command uses a URL parameter to point to a git repository. Git immediately clones the textexample submodule. Check the state of the repository by running the git status command:
git status
On branch master No commits yet Changes to be committed: (use "git rm --cached..." to unstage) new file: .gitmodules new file: textexample
Two new files are created in the repository: .gitmodules and the textexample directory. You can commit the files to the original repository with the git commit, and git add commands:
git add .gitmodules textexample/
git commit -m "added submodule"
[master (root-commit) d5002d0] added submodule 2 files changed, 4 insertions(+) (2个文件已更改, 4个插入( + )) create mode 100644 .gitmodules create mode 160000 textexample
Updating Submodules
Updating Submodules (正在更新子模块)
The members of the team should update the submodule code if someone has updated it. We cannot use git pull because it just retrieves the information that the submodule pointing to another commit, not updates the code of it. For updating the code of the submodule run the following:
git submodule update
Cloning Git Submodules
Cloning Git Submodules (克隆Git子模块)
For cloning a project with submodules, you should use the git clone command. It will clone the directories with submodules but not the files within them. You should run git submodule init and git submodule update. The first will update the local .git/config with the mapping from the .gitmodules file, and the latter will fetch the entire data from the submodule project and check out the mapped commit in the parent project.
The -recursive option of the git clone command initializes and updates submodules. Or just run the following:
git clone /url/to/repo/with/submodules
git submodule init
Pulling the Submodule’s Code
Pulling the Submodule’s Code (提取子模块的代码)
When you create a new submodule, the other members of the team should initiate it. To get the information about the submodule, first, you have to get the information about the submodule by executing git pull. If there are new submodules, you’ll see it in the output of git pull. Then you’ll have to initiate them with:
git submodule init
This will pull the code from the submodule and locate it in the directory that it is configured to. (这将从子模块中提取代码,并将其定位在配置的目录中。)
Pushing Updates in Submodule
Pushing Updates in Submodule (在子模块中推送更新)
As the submodule is a separate repository, you can push it like a regular Git repository by executing commands in the submodule’s directory. To make new commits inside the submodule will still point to the old commit. If you want to have the changes in the main repository, too, you should instruct the main repository to use the recent commit of the submodule. When you run git status in the main repository, the submodule will be in the “Changes not staged for commit” with the text “modified content”. This will check out the submodule code on a different commit than the main repository is pointing at. For making the main repository point to the new commit, run the git add command, commit and push it.
Submodules are a good way of keeping the projects in separate repositories, but still, be able to reference them as folders in the working directory of other repositories. However, take into account that for a lot of projects, submodules are not the best practice, and working with them is tricky. (子模块是将项目保存在单独存储库中的好方法,但仍然可以将它们作为其他存储库工作目录中的文件夹进行引用。但是,要考虑到对于许多项目来说,子模块不是最佳实践,使用它们很棘手。)