Skip to content

submodule: option to update without fetching - #2244

Open
jeffro256 wants to merge 2 commits into
gitpython-developers:mainfrom
jeffro256:submodule_update_no_fetch
Open

jeffro256 wants to merge 2 commits into
gitpython-developers:mainfrom
jeffro256:submodule_update_no_fetch

Conversation

@jeffro256

@jeffro256 jeffro256 commented Sep 17, 2026

Copy link
Copy Markdown

Enables behavior similar to git submodule update --no-fetch. Useful for A) builds with "online" then "offline" stages, and B) saving time while performing many checkouts and recursive submodule updates when you know that you have the commits locally.

@jeffro256
jeffro256 force-pushed the submodule_update_no_fetch branch 3 times, most recently from 1c5736d to 1d855b7 Compare September 17, 2026 16:50
@jeffro256

Copy link
Copy Markdown
Author

Force=pushed changes to make the linter happy

@Byron

Byron commented Sep 20, 2026

Copy link
Copy Markdown
Member

Thanks! Seems simple and useful at the same time.

@Byron
Byron force-pushed the submodule_update_no_fetch branch from 1d855b7 to 7140bcc Compare September 20, 2026 10:34
@Byron
Byron force-pushed the submodule_update_no_fetch branch from 7140bcc to f49cc2f Compare September 20, 2026 11:07
- Add tests
- [P2] Disable lazy fetching during no-fetch updates — git/objects/submodule/base.py:865-866
  For a partial-cloned submodule (for example, using `--filter=blob:none`), the
  target commit can be cached while its blobs are missing. Skipping `Remote.fetch`
  does not prevent the later checkout/reset from implicitly fetching those blobs.
  I reproduced `update(no_fetch=True)` spawning `git fetch origin ... --stdin`
  despite this guard. This violates the documented local-only behavior. Disable
  Git's lazy fetching for commands executed in this mode, including checkout and
  restoration.
- [P2] Propagate no_fetch to recursive root-module updates — git/objects/submodule/root.py:442-442
  For repositories with nested submodules,
  `Repo.submodule_update(no_fetch=True)` still fetches nested remotes. The flag
  reaches this immediate `sm.update(recursive=False, ...)`, but the subsequent
  `type(self)(sm.module()).update(...)` call omits it and defaults to `False`.
  Since root updates recurse by default, offline updates fail even when all
  required objects are cached. Forward the flag to the recursive call too.

- [P2] Skip the branch-change fetch loop when no_fetch is set — git/objects/submodule/root.py:90-90
  When `.gitmodules` changes a submodule's configured branch, the branch-change
  handler still unconditionally calls `remote.fetch(...)` for every remote.
  Consequently, even `submodule_update(recursive=False, no_fetch=True)` accesses
  remotes and fails offline, including when the target remote-tracking branch
  already exists locally. Guard that fetch loop with this flag as well.

- [P2] Handle URL changes without requiring freshly fetched refs — git/objects/submodule/root.py:282-283
  When a submodule's URL changes with `no_fetch=True`, the newly created
  `__new_origin__` remote has no refs, so the following `smr.refs` branch check
  raises `ValueError`. This occurs even when switching to an identical mirror with
  all required history cached locally, and leaves the temporary remote behind. The
  no-fetch path must handle the fetch-dependent validation and remote replacement,
  not merely skip this fetch.

- [P2] Allow restoring retained repositories without fetching — git/objects/submodule/base.py:893-896
  After `git submodule deinit`, the retained repository under
`.git/modules/<name>` can already contain the requested commit. This branch has
  validated that repository but now rejects `update(init=True, no_fetch=True)`
  merely because its checkout is empty. Reconnecting the repository and restoring
  cached contents requires no network access; native `git submodule update --init
  --no-fetch` succeeds in this case. Allow restoration and conditionally skip the
  later `fetch_remotes(mrepo)` instead.

Assisted-by: GPT 6.0
Co-authored-by: GPT 6.0 <codex@openai.com>
@Byron
Byron force-pushed the submodule_update_no_fetch branch from f49cc2f to a83262b Compare September 20, 2026 11:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants