Skip to content

Commit e7d7c73

Browse files
newrengitster
authored andcommitted
git-sparse-checkout: clarify interactions with submodules
Ignoring the sparse-checkout feature momentarily, if one has a submodule and creates local branches within it with unpushed changes and maybe adds some untracked files to it, then we would want to avoid accidentally removing such a submodule. So, for example with git.git, if you run git checkout v2.13.0 then the sha1collisiondetection/ submodule is NOT removed even though it did not exist as a submodule until v2.14.0. Similarly, if you only had v2.13.0 checked out previously and ran git checkout v2.14.0 the sha1collisiondetection/ submodule would NOT be automatically initialized despite being part of v2.14.0. In both cases, git requires submodules to be initialized or deinitialized separately. Further, we also have special handling for submodules in other commands such as clean, which requires two --force flags to delete untracked submodules, and some commands have a --recurse-submodules flag. sparse-checkout is very similar to checkout, as evidenced by the similar name -- it adds and removes files from the working copy. However, for the same avoid-data-loss reasons we do not want to remove a submodule from the working copy with checkout, we do not want to do it with sparse-checkout either. So submodules need to be separately initialized or deinitialized; changing sparse-checkout rules should not automatically trigger the removal or vivification of submodules. I believe the previous wording in git-sparse-checkout.txt about submodules was only about this particular issue. Unfortunately, the previous wording could be interpreted to imply that submodules should be considered active regardless of sparsity patterns. Update the wording to avoid making such an implication. It may be helpful to consider two example situations where the differences in wording become important: In the future, we want users to be able to run commands like git clone --sparse=moduleA --recurse-submodules $REPO_URL and have sparsity paths automatically set up and have submodules *within the sparsity paths* be automatically initialized. We do not want all submodules in any path to be automatically initialized with that command. Similarly, we want to be able to do things like git -c sparse.restrictCmds grep --recurse-submodules $REV $PATTERN and search through $REV for $PATTERN within the recorded sparsity patterns. We want it to recurse into submodules within those sparsity patterns, but do not want to recurse into directories that do not match the sparsity patterns in search of a possible submodule. Signed-off-by: Elijah Newren <[email protected]> Reviewed-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 274b9cc commit e7d7c73

File tree

1 file changed

+26
-4
lines changed

1 file changed

+26
-4
lines changed

Documentation/git-sparse-checkout.txt

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,10 +190,32 @@ directory.
190190
SUBMODULES
191191
----------
192192

193-
If your repository contains one or more submodules, then those submodules will
194-
appear based on which you initialized with the `git submodule` command. If
195-
your sparse-checkout patterns exclude an initialized submodule, then that
196-
submodule will still appear in your working directory.
193+
If your repository contains one or more submodules, then submodules
194+
are populated based on interactions with the `git submodule` command.
195+
Specifically, `git submodule init -- <path>` will ensure the submodule
196+
at `<path>` is present, while `git submodule deinit [-f] -- <path>`
197+
will remove the files for the submodule at `<path>` (including any
198+
untracked files, uncommitted changes, and unpushed history). Similar
199+
to how sparse-checkout removes files from the working tree but still
200+
leaves entries in the index, deinitialized submodules are removed from
201+
the working directory but still have an entry in the index.
202+
203+
Since submodules may have unpushed changes or untracked files,
204+
removing them could result in data loss. Thus, changing sparse
205+
inclusion/exclusion rules will not cause an already checked out
206+
submodule to be removed from the working copy. Said another way, just
207+
as `checkout` will not cause submodules to be automatically removed or
208+
initialized even when switching between branches that remove or add
209+
submodules, using `sparse-checkout` to reduce or expand the scope of
210+
"interesting" files will not cause submodules to be automatically
211+
deinitialized or initialized either.
212+
213+
Further, the above facts mean that there are multiple reasons that
214+
"tracked" files might not be present in the working copy: sparsity
215+
pattern application from sparse-checkout, and submodule initialization
216+
state. Thus, commands like `git grep` that work on tracked files in
217+
the working copy may return results that are limited by either or both
218+
of these restrictions.
197219

198220

199221
SEE ALSO

0 commit comments

Comments
 (0)