The short answer is no: The only thing a superproject commit does is refer to some submodule commit by hash ID.
Remember that when using submodules, you're really just using two almost-totally-independent Git repositories. I say almost because the superproject refers to the submodule.
In the superproject, there's some instructions in the .gitmodules
file. These instructions say how the superproject should run git clone
. In particular, git clone
needs a URL, and there is no place to store the URL in the commits:
- A commit has metadata, including a
tree
line. The tree
line refers to the hash ID of some internal tree object.
- An internal tree object consists of "lines" (but in binary format; see
git mktree
and git ls-tree
for the non-binary text formats). Each of these lines represents one record. Each record holds:
- a mode, e.g.,
100644
for a regular non-executable file;
- a hash ID, e.g.,
c592dda681fecfaa6bf64fb3f539eafaf4123ed8
; and
- a pathname component, e.g.,
.clang-format
.
- The mode for a symbolic link is
120000
, and the contents of the symlink are stored as a blob object.
- The mode for a gitlink—a reference to a submodule—is
160000
, and the hash ID in the tree entry is the commit hash ID in the submodule.
So there's only room for the hash ID, not the URL. Hence the URL is stored somewhere else (.gitmodules
and/or your .git/config
) in the superproject.
The name of the submodule is derived from the path, which in turn is derived from the tree
object(s) used to reach the "gitlink" entry: the thing with mode 160000
. That path corresponds to some directory in the superproject. Inside that directory, there should be a Git repository. If there isn't, git submodule init
can use the URL (found wherever) to run git clone
to populate that directory with a Git repository.
Once the repository is in place, the superproject can run:
(cd $path && git checkout $hash)
where $path
is that path, and $hash
is the hash in the gitlink. That hash ID had better be present in the clone! If it's not, the superproject checkout fails (and Git leaves you to clean things up yourself).
So, the superproject Git repository literally can't do anything but run git checkout
, or a few other Git commands, in the submodule Git repository. If there were ways to run git apply
on various patch files, that could do what you want, but that's not built-in to Git.
(Note that there are systems that do this sort of thing. One even uses Git: see guilt
, which is built on quilt, which name came from the idea of stringing lots of patches together.)
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…