This is the fifth day of my participation in the August Wen Challenge.More challenges in August

background

For more complex projects, it is possible to break down the code into different submodules based on function. The main project has dependencies on submodules, but is not concerned with the details of the submodule’s internal development process.

In this case, you don’t usually have all the source code in the same Git repository.

An easy way to do this is to add the submodule folder to the.gitignore file contents in the current working directory so that the main project can ignore the subprojects. The downside of this is that the user of the main project needs to have prior knowledge that a copy of a certain version of the submodule code needs to be placed in the current directory.

There is another way to use Git’s submodule functionality, which is the subject of this article.

In fact, the Submodule function of Git tools establishes dependencies between the current project and the submodule: the submodule path, the remote repository of the submodule, and the version number of the submodule.

Using the process

Suppose we have two projects: project-main and project-sub-1, where project-main represents the main project and project-sub-1 represents the submodule project.

One of the project – the main remote warehouse address for https://github.com/username/project-main.git, The project – sub – 1 remote warehouse address to https://github.com/username/project-sub-1.git.

Next, we want to add project-sub-1 to project-main, while keeping project-sub-1’s own independent version control.

1. Create submodule

You can use git subModule add

to create a submodule in your project.

Enter the project project-main and type:

➜ project-main git:(master) git submodule add github.com/username/pr… Clone to ‘/path/to/project-main/project-sub-1’… remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), Flue 0 (delta 0), Pack-Flue 0 expanded object: 100% (3/3), done.

There are two more files in the project repository:.gitmodules and project-sub-1.

The content of the former is this, in fact, is the information related to the sub-module; The latter file actually stores the version number information of the current version of the submodule.

[submodule “project-sub-1”] path = project-sub-1 URL = github.com/username/pr…

If the.gitModules file already exists in the project, the above three lines will be added to the file contents.

In fact, there will be more information in the.git/config file, and one more in the.git/modules folder.

Git commit -m “add submodule XXX” After submission, the submodule folder is displayed in the main project repository with the version number of the repository in which it resides.

2. Obtain submodule

In the process of creating submodules in the above steps, relevant codes will be automatically cloned to the corresponding path. However, for the subsequent users, the normal Clone operation for the main project will not pull the actual code in the submodule.

The project-main/project-sub-1 folder is empty when the clone is completed:

CD /path/to/temp git clone github.com/username/pr…

\

If you want the submodule code to be available, one way to do this is to clone the main project with a parameter called recurse-subModules, which will recursively pull all the submodules in the project.

CD /path/to/temp2 git clone github.com/username/pr… –recurse-submodules

In this case, the project-main/project-sub-1 folder has contents and is fixed to a Git submitted version.

Another possible way to do this is in the current main project:

git submodule init

git submodule update

The code in the submodule is pulled and updated based on the configuration information of the main project.

\

3. Update the content of submodules

Submodules do not need to be aware of the existence of the main project that references them. On its own, a submodule is a complete Git repository that follows normal Git code management practices.

For the main project, there are usually three situations when the content of a submodule changes:

1) The contents in the sub-module folder of the current project are changed without tracking;

2) The contents in the sub-module folder of the current project have version changes;

3) The contents in the sub-module folder of the current project remain unchanged, but have been updated remotely;

Case 1: The submodule has untracked content changes

In the first case, this is usually caused by directly modifying the code in the submodule folder in a development environment.

Using Git status in the main project can see changes to submodules that have not yet been temporarily stored for commit, but there is nothing you can do about the main project and it will not be affected by using Git add/commit.

➜ project-main git:(master) git status located at branch master your branch is the same as the upstream branch ‘origin/master’. Changes not yet staged for commit: (use “git add < file >…” Update the content to commit using “git checkout — < file >…” Changes: project-sub-1 changes have not been committed (use “git add” and/or “git commit -a”)

In this scenario, it is usually necessary to go into the submodule folder and submit the code according to the internal version control system of the submodule.

When the submission is completed, the state of the main project enters situation 2, that is, the content in the submodule folder of the current project has changed version.

Case 2: The submodule has a version change

When a submodule version changes and you use git status in the main project to check the repository status, you will see a new submodule commit:

➜ project-main git:(master) qualify git status your branch goes onto the ‘origin/master’ branch. Changes not yet staged for commit: (use “git add < file >…” Update the content to commit using “git checkout — < file >…” Discard workspace changes) Changes: project-sub-1 (new commit) Changes have not yet been committed (use “git add” and/or “git commit -a”)

In this case, you can use git add/commit to add it to the code commit of the main project, and the actual change is the version information represented by the submodule file:

git diff HEAD HEAD^ diff –git a/project-sub-1 b/project-sub-1 index ace9770.. 7097c48 160000 — a/project-sub-1 +++ b/project-sub-1 @@ -1 +1 @@ -Subproject commit ace977071f94f4f88935f9bb9a33ac0f8b4ba935 +Subproject commit 7097c4887798b71cee360e99815f7dbd1aa17eb4

Typically, when a subproject is updated and the main project modifies the version on which it depends, a commit message similar to this scenario is generated.

Case 3: There is a remote update to the submodule

In general, the development of the main project and submodules will not happen at exactly the same time. It is usually the responsibility of a submodule to maintain its own version upgrade, push it to a remote repository, and inform the main project that it can update its version dependencies on the submodule.

In this case, the main project is somewhat vacant.

Git subModule Update: Git submodule Update: Git SubModule Update: Git SubModule Update: Git Submodule Update: Git Submodule Update: Git Submodule Update: Git Submodule Update

But in this case, the submodule version recorded by the latter’s current main project has not changed, and everything is fine as far as the main project is concerned.

At this point, the main project needs to take the initiative to enter the sub-module to pull the new version of the code, upgrade operations.

The usual process is:

cd project-sub-1

git pull origin master

The version of the code in the submodule directory will change and go to the flow in case 2 for the main project submission.

Git submodule foreach: git submodule foreach

git submodule foreach ‘git pull origin master’

Case summary

In conclusion, it can be seen that the updating modes of sub-modules in different scenarios are as follows:

  • For submodules, you just need to manage your own version and push it to a remote branch.
  • For the parent module, if the submodule version information is not submitted, you need to update the code in the submodule directory and execute itcommitOperation Submit the submodule version information.
  • For the parent module, this parameter is required if the submodule version information has been submittedgit submodule updateGit automatically updates all submodule directories based on the submodule version information.

4. Delete submodules

Git /config, and.git/modules. Git rm –cached

, rm -rf

, rm. Gitmodules, and git rm –cached.

This is actually a wild practice and is not recommended.

According to the official documentation, you should use the git submodule deinit command to uninstall a submodule. If the –force parameter is added to this command, local changes in the submodule workspace will be removed.

git submodule deinit project-sub-1

git rm project-sub-1

Git submodule deinit project-sub-1 automatically deletes the following contents from.git/config:

[submodule “project-sub-1”] url = github.com/username/pr…

Git rm project-sub-1 removes the project-sub-1 folder and automatically removes the following contents from.gitmodules:

[submodule “project-sub-1”] path = project-sub-1 URL = github.com/username/pr…

At this point, most of the submodule information in the main project has been removed (although there seems to be remnants in the.git/modules directory) :

➜ project-main git:(master) eligible gs your branch corresponds to the upstream branch ‘origin/master’. Git reset HEAD < file >… To cancel temporary storage) modify:.gitmodules delete: project-sub-1

You can submit code:

git commit -m “delete submodule project-sub-1”

The submodule is now deleted.

conclusion

You can use the Git subModule feature when the project is complex and some of the code wants to version control the submodule independently.

With the Git subModule function, the main project repository does not contain the files of submodules, but only the configuration and version information of submodules as part of the main project version management.

This article briefly introduces how to add and remove Git submodules, and how to operate the main project and submodules in different states during project development.