Skip to main content

Module fixsub

Module fixsub 

Source
Expand description

Fix submodule metadata over an existing tree — a generalized port of the zsh fixSubModuleMeta. Applied recursively to every initialized submodule:

  1. Un-detach (branch reconcile): git submodule update --init checks out the pinned commit in detached HEAD (the gitlink is a SHA, not a branch). fixsub switches a submodule onto its declared .gitmodules branch only when it is in detached HEAD — the genuine post-clone case. A submodule deliberately on a named branch (active feature work) is left alone and the divergence is reported, never silently switched. Every outcome is printed per submodule (no swallowed git switch — gkit’s “every side effect is visible” rule). There is deliberately no --force/--switch-all: bulk-yanking feature branches is the footgun we removed from stmb; to move one submodule by hand, git switch in it.
  2. Identity inherit (set-if-unset): a submodule added after gkit clone misses the identity stamp. fixsub copies the root repo’s local user.name/user.email into each submodule that has no local identity — never clobbering a deliberately- different one.

(Optionally direnv allow each submodule with an .envrc, after the branch reconcile re-points the working tree.)

Project-specific config (e.g. core.hooksPath) is intentionally NOT here — that belongs in the conf’s post-clone, re-applied by gkit stamp. fixsub only does universal git/submodule hygiene. (Note: clone still uses clone::SUBMODULE_SWITCH to un-detach right after submodule update --init, where everything is detached and a switch is unambiguously correct — that path is unchanged.)

Structs§

FixsubReport

Enums§

Outcome
SwitchPlan
What to do with one submodule’s checkout, decided purely from its current branch (None = detached HEAD) and its declared .gitmodules branch. This is the whole “un-detach only, never yank a named branch” policy in one testable function.

Functions§

decide_switch
Decide the branch action for a submodule. Only an un-detach (detached → configured) ever mutates; a named branch is kept (if it matches) or reported as diverged (if it doesn’t) — fixsub never moves a named branch.
fixsub
Un-detach + identity-inherit (+ optional direnv allow) over the submodule tree rooted at root. Prints a per-submodule outcome for the branch reconcile and the git commands it runs; idempotent. dry_run prints the plan and mutates nothing.
inherit_identity_cmd
The submodule foreach body that inherits the root’s identity only where the submodule lacks its own — for each of user.name/user.email that the root has, emit git config --local user.X >/dev/null 2>&1 || git config user.X '<val>' (values single-quoted via [sh_squote]). None when the root has no identity to inherit (nothing to do).