mirror of
https://github.com/git/git
synced 2024-10-30 04:01:21 +00:00
4f73a7f124
* Only mention porcelain commands in examples * Split a sentence for better readability * Add missing apostrophes * Clearly specify the advantages of using submodules * Avoid abbreviations * Use "Git" consistently * Improve readability of certain lines * Clarify when a submodule is considered active Helped-by: Eric Sunshine <sunshine@sunshineco.com> Helped-by: Stefan Beller <sbeller@google.com> Signed-off-by: Kaartic Sivaraam <kaartic.sivaraam@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
279 lines
9.9 KiB
Text
279 lines
9.9 KiB
Text
gitsubmodules(7)
|
||
================
|
||
|
||
NAME
|
||
----
|
||
gitsubmodules - mounting one repository inside another
|
||
|
||
SYNOPSIS
|
||
--------
|
||
.gitmodules, $GIT_DIR/config
|
||
------------------
|
||
git submodule
|
||
git <command> --recurse-submodules
|
||
------------------
|
||
|
||
DESCRIPTION
|
||
-----------
|
||
|
||
A submodule is a repository embedded inside another repository.
|
||
The submodule has its own history; the repository it is embedded
|
||
in is called a superproject.
|
||
|
||
On the filesystem, a submodule usually (but not always - see FORMS below)
|
||
consists of (i) a Git directory located under the `$GIT_DIR/modules/`
|
||
directory of its superproject, (ii) a working directory inside the
|
||
superproject's working directory, and a `.git` file at the root of
|
||
the submodule’s working directory pointing to (i).
|
||
|
||
Assuming the submodule has a Git directory at `$GIT_DIR/modules/foo/`
|
||
and a working directory at `path/to/bar/`, the superproject tracks the
|
||
submodule via a `gitlink` entry in the tree at `path/to/bar` and an entry
|
||
in its `.gitmodules` file (see linkgit:gitmodules[5]) of the form
|
||
`submodule.foo.path = path/to/bar`.
|
||
|
||
The `gitlink` entry contains the object name of the commit that the
|
||
superproject expects the submodule’s working directory to be at.
|
||
|
||
The section `submodule.foo.*` in the `.gitmodules` file gives additional
|
||
hints to Git's porcelain layer. For example, the `submodule.foo.url`
|
||
setting specifies where to obtain the submodule.
|
||
|
||
Submodules can be used for at least two different use cases:
|
||
|
||
1. Using another project while maintaining independent history.
|
||
Submodules allow you to contain the working tree of another project
|
||
within your own working tree while keeping the history of both
|
||
projects separate. Also, since submodules are fixed to an arbitrary
|
||
version, the other project can be independently developed without
|
||
affecting the superproject, allowing the superproject project to
|
||
fix itself to new versions only when desired.
|
||
|
||
2. Splitting a (logically single) project into multiple
|
||
repositories and tying them back together. This can be used to
|
||
overcome current limitations of Git's implementation to have
|
||
finer grained access:
|
||
|
||
* Size of the Git repository:
|
||
In its current form Git scales up poorly for large repositories containing
|
||
content that is not compressed by delta computation between trees.
|
||
For example, you can use submodules to hold large binary assets
|
||
and these repositories can be shallowly cloned such that you do not
|
||
have a large history locally.
|
||
* Transfer size:
|
||
In its current form Git requires the whole working tree present. It
|
||
does not allow partial trees to be transferred in fetch or clone.
|
||
If the project you work on consists of multiple repositories tied
|
||
together as submodules in a superproject, you can avoid fetching the
|
||
working trees of the repositories you are not interested in.
|
||
* Access control:
|
||
By restricting user access to submodules, this can be used to implement
|
||
read/write policies for different users.
|
||
|
||
The configuration of submodules
|
||
-------------------------------
|
||
|
||
Submodule operations can be configured using the following mechanisms
|
||
(from highest to lowest precedence):
|
||
|
||
* The command line for those commands that support taking submodules
|
||
as part of their pathspecs. Most commands have a boolean flag
|
||
`--recurse-submodules` which specify whether to recurse into submodules.
|
||
Examples are `grep` and `checkout`.
|
||
Some commands take enums, such as `fetch` and `push`, where you can
|
||
specify how submodules are affected.
|
||
|
||
* The configuration inside the submodule. This includes `$GIT_DIR/config`
|
||
in the submodule, but also settings in the tree such as a `.gitattributes`
|
||
or `.gitignore` files that specify behavior of commands inside the
|
||
submodule.
|
||
+
|
||
For example an effect from the submodule's `.gitignore` file
|
||
would be observed when you run `git status --ignore-submodules=none` in
|
||
the superproject. This collects information from the submodule's working
|
||
directory by running `status` in the submodule while paying attention
|
||
to the `.gitignore` file of the submodule.
|
||
+
|
||
The submodule's `$GIT_DIR/config` file would come into play when running
|
||
`git push --recurse-submodules=check` in the superproject, as this would
|
||
check if the submodule has any changes not published to any remote. The
|
||
remotes are configured in the submodule as usual in the `$GIT_DIR/config`
|
||
file.
|
||
|
||
* The configuration file `$GIT_DIR/config` in the superproject.
|
||
Git only recurses into active submodules (see "ACTIVE SUBMODULES"
|
||
section below).
|
||
+
|
||
If the submodule is not yet initialized, then the configuration
|
||
inside the submodule does not exist yet, so where to
|
||
obtain the submodule from is configured here for example.
|
||
|
||
* The `.gitmodules` file inside the superproject. A project usually
|
||
uses this file to suggest defaults for the upstream collection
|
||
of repositories for the mapping that is required between a
|
||
submodule's name and its path.
|
||
+
|
||
This file mainly serves as the mapping between the name and path of submodules
|
||
in the superproject, such that the submodule's Git directory can be
|
||
located.
|
||
+
|
||
If the submodule has never been initialized, this is the only place
|
||
where submodule configuration is found. It serves as the last fallback
|
||
to specify where to obtain the submodule from.
|
||
|
||
FORMS
|
||
-----
|
||
|
||
Submodules can take the following forms:
|
||
|
||
* The basic form described in DESCRIPTION with a Git directory,
|
||
a working directory, a `gitlink`, and a `.gitmodules` entry.
|
||
|
||
* "Old-form" submodule: A working directory with an embedded
|
||
`.git` directory, and the tracking `gitlink` and `.gitmodules` entry in
|
||
the superproject. This is typically found in repositories generated
|
||
using older versions of Git.
|
||
+
|
||
It is possible to construct these old form repositories manually.
|
||
+
|
||
When deinitialized or deleted (see below), the submodule’s Git
|
||
directory is automatically moved to `$GIT_DIR/modules/<name>/`
|
||
of the superproject.
|
||
|
||
* Deinitialized submodule: A `gitlink`, and a `.gitmodules` entry,
|
||
but no submodule working directory. The submodule’s Git directory
|
||
may be there as after deinitializing the Git directory is kept around.
|
||
The directory which is supposed to be the working directory is empty instead.
|
||
+
|
||
A submodule can be deinitialized by running `git submodule deinit`.
|
||
Besides emptying the working directory, this command only modifies
|
||
the superproject’s `$GIT_DIR/config` file, so the superproject’s history
|
||
is not affected. This can be undone using `git submodule init`.
|
||
|
||
* Deleted submodule: A submodule can be deleted by running
|
||
`git rm <submodule path> && git commit`. This can be undone
|
||
using `git revert`.
|
||
+
|
||
The deletion removes the superproject’s tracking data, which are
|
||
both the `gitlink` entry and the section in the `.gitmodules` file.
|
||
The submodule’s working directory is removed from the file
|
||
system, but the Git directory is kept around as it to make it
|
||
possible to checkout past commits without requiring fetching
|
||
from another repository.
|
||
+
|
||
To completely remove a submodule, manually delete
|
||
`$GIT_DIR/modules/<name>/`.
|
||
|
||
ACTIVE SUBMODULES
|
||
-----------------
|
||
|
||
A submodule is considered active,
|
||
|
||
(a) if `submodule.<name>.active` is set to `true`
|
||
or
|
||
(b) if the submodule's path matches the pathspec in `submodule.active`
|
||
or
|
||
(c) if `submodule.<name>.url` is set.
|
||
|
||
and these are evaluated in this order.
|
||
|
||
For example:
|
||
|
||
[submodule "foo"]
|
||
active = false
|
||
url = https://example.org/foo
|
||
[submodule "bar"]
|
||
active = true
|
||
url = https://example.org/bar
|
||
[submodule "baz"]
|
||
url = https://example.org/baz
|
||
|
||
In the above config only the submodule 'bar' and 'baz' are active,
|
||
'bar' due to (a) and 'baz' due to (c). 'foo' is inactive because
|
||
(a) takes precedence over (c)
|
||
|
||
Note that (c) is a historical artefact and will be ignored if the
|
||
(a) and (b) specify that the submodule is not active. In other words,
|
||
if we have an `submodule.<name>.active` set to `false` or if the
|
||
submodule's path is excluded in the pathspec in `submodule.active`, the
|
||
url doesn't matter whether it is present or not. This is illustrated in
|
||
the example that follows.
|
||
|
||
[submodule "foo"]
|
||
active = true
|
||
url = https://example.org/foo
|
||
[submodule "bar"]
|
||
url = https://example.org/bar
|
||
[submodule "baz"]
|
||
url = https://example.org/baz
|
||
[submodule "bob"]
|
||
ignore = true
|
||
[submodule]
|
||
active = b*
|
||
active = :(exclude) baz
|
||
|
||
In here all submodules except 'baz' (foo, bar, bob) are active.
|
||
'foo' due to its own active flag and all the others due to the
|
||
submodule active pathspec, which specifies that any submodule
|
||
starting with 'b' except 'baz' are also active, regardless of the
|
||
presence of the .url field.
|
||
|
||
Workflow for a third party library
|
||
----------------------------------
|
||
|
||
# add a submodule
|
||
git submodule add <url> <path>
|
||
|
||
# occasionally update the submodule to a new version:
|
||
git -C <path> checkout <new version>
|
||
git add <path>
|
||
git commit -m "update submodule to new version"
|
||
|
||
# See the list of submodules in a superproject
|
||
git submodule status
|
||
|
||
# See FORMS on removing submodules
|
||
|
||
|
||
Workflow for an artificially split repo
|
||
--------------------------------------
|
||
|
||
# Enable recursion for relevant commands, such that
|
||
# regular commands recurse into submodules by default
|
||
git config --global submodule.recurse true
|
||
|
||
# Unlike the other commands below clone still needs
|
||
# its own recurse flag:
|
||
git clone --recurse <URL> <directory>
|
||
cd <directory>
|
||
|
||
# Get to know the code:
|
||
git grep foo
|
||
git ls-files
|
||
|
||
# Get new code
|
||
git fetch
|
||
git pull --rebase
|
||
|
||
# change worktree
|
||
git checkout
|
||
git reset
|
||
|
||
Implementation details
|
||
----------------------
|
||
|
||
When cloning or pulling a repository containing submodules the submodules
|
||
will not be checked out by default; You can instruct 'clone' to recurse
|
||
into submodules. The 'init' and 'update' subcommands of 'git submodule'
|
||
will maintain submodules checked out and at an appropriate revision in
|
||
your working tree. Alternatively you can set 'submodule.recurse' to have
|
||
'checkout' recursing into submodules.
|
||
|
||
|
||
SEE ALSO
|
||
--------
|
||
linkgit:git-submodule[1], linkgit:gitmodules[5].
|
||
|
||
GIT
|
||
---
|
||
Part of the linkgit:git[1] suite
|