Design and limitations¶
What LazySubmodules is for, how it stays compatible with Git, and what it deliberately does not do.
The gap in native Git¶
Git can make a submodule follow a branch: set submodule.<name>.branch
and run git submodule update --remote. It has no way to say “this
submodule follows tag v2.3.1” or “this submodule follows the newest
v6.6.* release”. Projects that pin dependencies to releases, such as
firmware, embedded Linux or FPGA designs, update those submodules by
hand: look up the newest tag, check it out, stage the gitlink, and write
a commit message that says what changed.
LazySubmodules automates exactly that, and adds a lock file so that the superproject remembers which tag led to which commit.
Compatible by construction¶
The design goal is that a superproject stays an ordinary Git superproject:
Namespaced keys. The tracking configuration uses the keys
lsm-modeandlsm-refin.gitmodules. Git ignores unknown keys, and the prefix avoids collisions with keys that Git may add later.The native
branchkey is written for branch mode and removed for the other modes, sogit submodule update --remotedoes the right thing for branch-tracking submodules.Ordinary gitlinks. The superproject records submodule commits as usual. A clone works with
git submodule update --initfor anyone who does not use LazySubmodules.Plain files.
.lsm.lockhas the same git-config format as.gitmodules, is read and written withgit config -f, and diffs and merges like any text file.Native keys stay.
update,ignore,shallowand other keys are left as they are.
See Work with plain Git for what this means in practice.
Git compatibility¶
LazySubmodules needs Git 2.39 or later, the version in Debian 12 (bookworm). It uses no Git feature added after 2.39:
Classic
git configoptions. It uses--get,--unset-alland--listrather than the subcommands that Git 2.46 added.Tested on both ends. The test suite runs against Git 2.39.5 and against a current Git, and the demo gives the same transcript on Git 2.39.5 and 2.55.0.
Locale-independent. Every
gitinvocation setsLC_ALL=C, so the output that LazySubmodules parses is always in English.SHA-256 repositories work: commit IDs are 40 or 64 hex digits, and nothing assumes a length.
Git’s own messages, such as clone progress, go to standard error and may differ between Git versions.
Two interfaces over one core¶
The command line is for scripts and for people who prefer commands. Its porcelain format and exit codes are stable.
The terminal interface is for browsing, previewing and updating interactively. It contains no business logic: every action calls the same core as the command line.
Both are one binary, lazysubmodules, with lsm as an optional short
name.
Stable interfaces¶
These are part of the user interface, and the project keeps them unchanged:
Porcelain v1: the header line, the field count, order and meaning, the state names and the quoting rule of
status --porcelain=v1. An incompatible change would come as--porcelain=v2, next to v1. See Porcelain format v1.Exit codes 0 to 5; see Exit codes.
The
.gitmoduleskeyslsm-modeandlsm-ref.The network policy: only
fetch,update --fetchandadduse the network.
Everything else, such as the table layout of status, the wording of
messages and the output of update, is meant for people and may change.
Scope¶
LazySubmodules is deliberately small:
Not a replacement for
repo,west,git subtreeor monorepo tooling. It manages the submodules of one superproject; it does not assemble a workspace from a separate manifest.No credential management. Git uses its configured credential helpers, SSH agent and keys.
No hosting integration. It does not talk to GitHub, GitLab or any other service; it talks to Git remotes through
git.
Known limitations¶
Nested submodules are not managed recursively: submodules inside a managed submodule are neither initialized nor updated. After an update, a nested submodule may stay at a commit other than the one the new commit records. That alone does not make the managed submodule
dirty; modified files inside the nested submodule do. See Nested submodules for a workaround.Linux only, on
amd64andarm64. Windows and macOS are not supported.The remote is always
origin. Branch tracking resolvesrefs/remotes/origin/<branch>, andfetchfetches fromorigin.Local resolution.
status,verifyandupdatewithout--fetchsee only what was fetched before.Git 2.39 or later is required.
No prompts in the terminal interface. Git cannot ask for credentials or host keys there; see Git without a terminal in the TUI.