Context
When JSS auto-inits a repo on first git-receive-pack push (#466/#469), the resulting .git/config has no remotes configured. That's correct for the create-on-push semantics — JSS doesn't know where the client cloned from.
In practice this bites pod operators who later cd into the pod-side install dir and want to track upstream:
$ cd pod-data/public/apps/chrome
$ git pull
fatal: no upstream branch configured
$ git pull origin
fatal: 'origin' does not appear to be a git repository
The user has to manually git remote add origin <upstream> and git branch --set-upstream-to for every installed app.
Proposal
When a push triggers auto-init, optionally read an X-Git-Remote HTTP header from the client. If present, validated, and not already configured on the (just-auto-init'd) repo, run the equivalent of:
git -C <repoAbs> remote add origin <value>
git -C <repoAbs> branch --set-upstream-to=origin/main main # if HEAD is main
so the operator can git pull later without ceremony.
Surface
POST /public/apps/foo/git-receive-pack HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/x-git-receive-pack-request
X-Git-Remote: https://github.com/solid-apps/foo
...
Constraints
- Only on auto-init path. Don't touch
.git/config of a pre-existing repo — that's the operator's territory, surprise-edits there are unacceptable.
- Validate the value. URL must match
^https?://[A-Za-z0-9._/:-]+$. Reject git@, ssh://, file://, anything with shell metacharacters, anything with ... This is the same sort of guard tryAutoInitRepo already needs against symlink shenanigans (called out in its docstring).
- No-op if not present. Header is purely opt-in; existing clients keep working.
- Run after
git init, before the push proceeds. Otherwise the push could race with the config write.
- Use
git remote add and git branch --set-upstream-to via spawnSync — don't hand-roll the config file. git writes the right shape.
Scope
~25 LoC + a test in test/git-auto-init.test.js:
it('configures origin from X-Git-Remote when present on first push', async () => {
const url = `${baseUrl}/public/apps/penny/info/refs?service=git-receive-pack`;
const res = await fetch(url, {
headers: { 'X-Git-Remote': 'https://github.com/solid-apps/penny' }
});
assert.strictEqual(res.status, 200);
const configPath = path.resolve(DATA_DIR, 'public/apps/penny/.git/config');
const cfg = readFileSync(configPath, 'utf8');
assert.ok(cfg.includes('[remote "origin"]'), 'origin should be configured');
assert.ok(cfg.includes('url = https://github.com/solid-apps/penny'));
});
Plus a negative test: malformed URL → header silently ignored, push still succeeds.
Why this is JSS-level (not jspod-level)
- Only JSS knows when auto-init fires (the trigger that "the repo is new and we can safely write config")
- Works for any client (jspod install, raw
git push, future tools), not just the wrapper
- Operators who deploy JSS directly benefit too
Cross-references
Context
When JSS auto-inits a repo on first
git-receive-packpush (#466/#469), the resulting.git/confighas no remotes configured. That's correct for the create-on-push semantics — JSS doesn't know where the client cloned from.In practice this bites pod operators who later
cdinto the pod-side install dir and want to track upstream:The user has to manually
git remote add origin <upstream>andgit branch --set-upstream-tofor every installed app.Proposal
When a push triggers auto-init, optionally read an
X-Git-RemoteHTTP header from the client. If present, validated, and not already configured on the (just-auto-init'd) repo, run the equivalent of:so the operator can
git pulllater without ceremony.Surface
Constraints
.git/configof a pre-existing repo — that's the operator's territory, surprise-edits there are unacceptable.^https?://[A-Za-z0-9._/:-]+$. Rejectgit@,ssh://,file://, anything with shell metacharacters, anything with... This is the same sort of guardtryAutoInitRepoalready needs against symlink shenanigans (called out in its docstring).git init, before the push proceeds. Otherwise the push could race with the config write.git remote addandgit branch --set-upstream-toviaspawnSync— don't hand-roll the config file.gitwrites the right shape.Scope
~25 LoC + a test in
test/git-auto-init.test.js:Plus a negative test: malformed URL → header silently ignored, push still succeeds.
Why this is JSS-level (not jspod-level)
git push, future tools), not just the wrapperCross-references
jspod installonce this lands. Tracked separately as a jspod follow-up.git init -b main) so updateInstead reliably extracts working tree #471 (auto-init default branch) — same surface area; this proposal also benefits from the deterministicmaindefault for thebranch --set-upstream-tostep.