You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If an upstream repository contains a gitlink (mode 160000) that is not registered in .gitmodules, dfetch update fails outright with
fatal: No url found for submodule path '<path>' in .gitmodules
The project is not fetched at all. This happens even when the offending path lies entirely outside the project's src, and even when the upstream has no .gitmodules file whatsoever.
Such a repository is malformed, but it is not rare: it is what you get when someone commits a git worktree directory, or git adds a nested checkout by accident. The upstream I vendor from has done it twice in two months, in two different directories, and the consumer has no way to ask the producer to hurry. Right now the only remedies are to pin to an older revision that predates the mistake, or to shim git on PATH — both disproportionate to a probe that is incidental to the fetch being requested.
Reproduction
Fully self-contained; no network needed.
# 1. An upstream with a stray gitlink and no .gitmodules.
mkdir -p /tmp/dfetch-repro/upstream &&cd /tmp/dfetch-repro/upstream
git init -q -b main
mkdir vendored &&echo hello > vendored/file.txt
git add -A && git commit -qm "initial"
git update-index --add --cacheinfo 160000,"$(git rev-parse HEAD)",some/worktree
git commit -qm "commit a gitlink with no .gitmodules entry"# 2. A consumer that vendors only `vendored/` — nowhere near the gitlink.
mkdir -p /tmp/dfetch-repro/consumer &&cd /tmp/dfetch-repro/consumer
cat > dfetch.yaml <<'EOF'manifest: version: '0.0' remotes: - name: local url-base: file:///tmp/dfetch-repro/ projects: - name: demo remote: local repo-path: upstream branch: main src: vendored dst: vendoredEOF
dfetch update
Expected:vendored/file.txt is fetched. The gitlink is outside src and declares no submodule, so there is nothing to do about it.
Actual:
Dfetch (0.14.0)
demo:
>>>git submodule update --init --recursive<<< returned 128:
fatal: No url found for submodule path 'some/worktree' in .gitmodules
Diagnosis
GitLocalRepo.checkout_version in dfetch/vcs/git.py runs two submodule commands unconditionally on the freshly fetched clone:
Both consult the index for gitlinks and both look each one up in .gitmodules, so both exit 128 on a gitlink that is not declared there. run_on_cmdline raises, and the fetch dies.
Three things make this hard to work around from the consumer side:
Sparse checkout does not help. The gitlinks are index entries; _configure_sparse_checkout only marks them skip-worktree. A project with src: vendored still trips over some/worktree.
src/ignore filtering happens too late._apply_src_and_ignore — which since fix: exclude submodules outside src folder when src is specified #1256 correctly drops submodules outside src — runs aftersubmodules(), so it never gets the chance. The filter's own premise, that submodules outside src are not this fetch's business, applies equally to the failure being reported here.
No git config silences both.submodule.active=':!*' turns submodule update into a no-op, but submodule foreach still aborts. And there is no .gitmodules to point a submodule.<name>.url at.
Environment
DFetch
0.14.0. Reproduced there; main carries the identical call sequence — unconditional submodule update --init --recursive at dfetch/vcs/git.py:529, then submodules(), with _apply_src_and_ignore still running after both.
Summary
If an upstream repository contains a gitlink (mode
160000) that is not registered in.gitmodules,dfetch updatefails outright withThe project is not fetched at all. This happens even when the offending path lies entirely outside the project's
src, and even when the upstream has no.gitmodulesfile whatsoever.Such a repository is malformed, but it is not rare: it is what you get when someone commits a
git worktreedirectory, orgit adds a nested checkout by accident. The upstream I vendor from has done it twice in two months, in two different directories, and the consumer has no way to ask the producer to hurry. Right now the only remedies are to pin to an older revision that predates the mistake, or to shimgitonPATH— both disproportionate to a probe that is incidental to the fetch being requested.Reproduction
Fully self-contained; no network needed.
Expected:
vendored/file.txtis fetched. The gitlink is outsidesrcand declares no submodule, so there is nothing to do about it.Actual:
Diagnosis
GitLocalRepo.checkout_versionindfetch/vcs/git.pyruns two submodule commands unconditionally on the freshly fetched clone:and
submodules()runsBoth consult the index for gitlinks and both look each one up in
.gitmodules, so both exit 128 on a gitlink that is not declared there.run_on_cmdlineraises, and the fetch dies.Three things make this hard to work around from the consumer side:
_configure_sparse_checkoutonly marks them skip-worktree. A project withsrc: vendoredstill trips oversome/worktree.src/ignorefiltering happens too late._apply_src_and_ignore— which since fix: exclude submodules outside src folder when src is specified #1256 correctly drops submodules outsidesrc— runs aftersubmodules(), so it never gets the chance. The filter's own premise, that submodules outsidesrcare not this fetch's business, applies equally to the failure being reported here.submodule.active=':!*'turnssubmodule updateinto a no-op, butsubmodule foreachstill aborts. And there is no.gitmodulesto point asubmodule.<name>.urlat.Environment
maincarries the identical call sequence — unconditionalsubmodule update --init --recursiveatdfetch/vcs/git.py:529, thensubmodules(), with_apply_src_and_ignorestill running after both.