Skip to content

fix(git): auto-init regular (non-bare) repos so pushed files are served#469

Merged
melvincarvalho merged 1 commit into
gh-pagesfrom
fix-git-auto-init-regular-repo
May 16, 2026
Merged

fix(git): auto-init regular (non-bare) repos so pushed files are served#469
melvincarvalho merged 1 commit into
gh-pagesfrom
fix-git-auto-init-regular-repo

Conversation

@melvincarvalho

Copy link
Copy Markdown
Contributor

Resolves #468. Follow-up to #466.

Problem

#466 chose git init --bare for auto-init. That works for "pod is a git remote" (clone / fetch / push all work) but breaks "install an app via git push" — the original motivation in #465 + #464. Pushed files land in pack objects with no working tree, so a pushed index.html isn't servable as an HTTP static resource.

Repro: pushing Hub into a pod with the current auto-init succeeds at the protocol level but curl http://localhost:5444/public/apps/hub/ returns the LDP container listing of bare-repo internals (HEAD, objects/, refs/), not Hub's index.html.

Fix

Switch auto-init to non-bare. The existing handler already runs git config receive.denyCurrentBranch updateInstead for non-bare repos on every push — that config auto-extracts the working tree, so pushed files appear at the corresponding URL.

Diff size

  • src/handlers/git.js: drop --bare from one spawnSync arg list. Rename tryAutoInitBareRepotryAutoInitRepo. Refresh JSDoc + handler comment to explain why non-bare is the right choice for the "apps live in pods" pattern.
  • test/git-auto-init.test.js: assert the regular-repo shape (.git/HEAD, .git/objects, .git/refs) instead of bare-repo files at the root.

Tests

All 6 git-auto-init tests pass:

  • ✅ auto-inits a regular repo on push to non-existent path
  • ✅ auto-inits a regular repo when target dir exists but is empty
  • ✅ refuses to auto-init when target dir contains user content
  • ✅ does NOT auto-init on a fetch (git-upload-pack)
  • ✅ refuses auto-init when ACL Write is not granted (unauthenticated)
  • ✅ subsequent pushes use the existing repo (no re-init)

Full JSS suite: 876 / 876 passing.

Compatibility

Operators who manually pre-create bare repos at pod paths (the workflow that existed before #466) keep working — findGitDir handles both shapes, only the auto-init path changes. No published surface broken.

Trade-off acknowledged

A regular repo has both .git/ history and the checked-out working tree, so disk footprint is ~2× a bare repo for equivalent content. Acceptable: it's the price of having the pushed files be reachable as HTTP resources, which is the whole point.

Refs #466 (parent), #465 (original init issue), #464, jspod#25, jspod#26

Resolves #468. Follow-up to #466.

#466 chose `git init --bare` for auto-init, which is correct for the
"pod is a git remote" use case (clone / fetch / push all work) but
breaks the symmetrical "install an app via git push" use case (the
original motivation in #465 + #464): pushed files end up in pack
objects, with no working tree on disk, so a pushed `index.html` is
not servable as an HTTP static resource.

Switch auto-init to non-bare. The existing handler already runs
`git config receive.denyCurrentBranch updateInstead` for non-bare
repos on every push, which auto-extracts the working tree. Pushed
files now appear at the corresponding pod URL — `git push pod
main` becomes a working app deploy.

Code change is minimal: drop `--bare` from one `spawnSync` arg
list. The helper is renamed `tryAutoInitBareRepo` →
`tryAutoInitRepo` and its JSDoc + nearby handler comment updated
to describe the new semantics (and why non-bare is the right
choice for the "apps live in pods" pattern).

Tests updated to assert the regular-repo shape (`.git/HEAD`,
`.git/objects`, `.git/refs`) instead of bare-repo files at the
root. The negative test that ensures no auto-init happens on a
non-empty directory now also asserts `.git/` doesn't appear.
Full suite (876 tests) passes.

Repro that motivated this PR — pushing Hub from
https://github.com/solid-apps/hub.git:

  git push pod HEAD:main  # succeeds: * [new branch] HEAD -> main

After this fix, `curl http://localhost:5444/public/apps/hub/`
returns Hub's actual content instead of the LDP container listing
for a bare repo's internals.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Git auto-init: use regular (non-bare) repo so pushed files are served as static resources

1 participant