Skip to content

Git auto-init: pin the default branch name (git init -b main) so updateInstead reliably extracts working tree #471

Description

@melvincarvalho

Context

Follow-up to #469 (auto-init regular repos). The auto-init path now creates a non-bare repo with a working tree, and the existing handler sets receive.denyCurrentBranch updateInstead so pushed content extracts on each push. End-to-end test against Hub confirmed this works when the push targets the server-side HEAD's branch.

But there's a UX wart that bites in practice: git init (no explicit -b) sets HEAD to whatever init.defaultBranch is configured to in the server's git environmentmain on most modern installs, master on older ones, and anything a system admin has configured. updateInstead only extracts the working tree when the incoming push targets the branch HEAD points at.

Repro

Server with init.defaultBranch=gh-pages (legitimate config for users hosting on GitHub Pages):

git clone https://github.com/solid-apps/hub.git
cd hub
git remote add pod http://localhost:5444/public/apps/hub
git push pod HEAD:main          # most users will do this
# → succeeds: * [new branch] HEAD -> main
# BUT working tree NOT extracted because server's HEAD points at gh-pages, not main
# Result: pod-data/public/apps/hub/.git/refs/heads/main exists, but no index.html etc.

curl http://localhost:5444/public/apps/hub/index.html
# → 404 — files only live in pack objects on the gh-pages branch (empty)

To make it work today, the user has to know the server's init.defaultBranch and push to that name. That's invisible at the protocol layer.

Proposed fix

Pass -b <name> to git init in tryAutoInitRepo so the auto-init'd HEAD is deterministic regardless of server config:

const result = spawnSync('git', ['init', '-b', 'main', repoAbs], { ... });

Choice of main is the modern convention (default in git since 2.28 with newer configs, GitHub default, GitLab default).

Trade-offs

  • Predictable for users: git push pod HEAD:main always works regardless of where the server's deployed.
  • Compat with master/gh-pages/etc: users who push a different branch name would have their refs accepted but working tree not extracted (same behaviour as today, just predictable now). Documented in the wrapper's docs as "push to main for the auto-extract to fire."
  • Doesn't honour init.defaultBranch: a feature, not a bug — the auto-init path is a public protocol concern, not an admin-config one. Operators who explicitly want a different default could be served by an additional CLI flag in a follow-up.

Optional follow-up

A --git-default-branch <name> server flag (defaulting to main) would let operators override without an explicit per-request mechanism. Worth filing separately if anyone asks.

Diff size

1 LoC in src/handlers/git.js. Test for it: 1 LoC reading .git/HEAD and asserting the symbolic ref points at refs/heads/main. Total ~5 LoC.

Cross-references

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions