From 3bb89a967645902bb695aedbaea0103def2b3b16 Mon Sep 17 00:00:00 2001
From: WebX11 SysOp
Date: Thu, 5 Nov 2026 22:32:04 +0100
Subject: feat(git): namespace contrib refs per account
(contrib//)
Done before anyone has a token or a branch, because renaming later breaks every
contributor. The hook compares the middle path segment to REMOTE_USER, so a token
can only write under its own namespace; deletion and cleanup become a prefix
operation instead of a guess.
Verified 4/4: own namespace accepted, neighbour's namespace refused naming the
authenticated user, missing owner segment refused with the correct form, main
refused. Test branch and token removed afterwards; queue back to 0.
---
docs/usage.html | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/docs/usage.html b/docs/usage.html
index 017f6e4..f25a074 100644
--- a/docs/usage.html
+++ b/docs/usage.html
@@ -296,9 +296,9 @@ and read-only.
git remote add push https://push.newos.webx11.duckdns.org/newos4.git
# 2. work on a branch, push it under contrib/
-git switch -c contrib/my-fix
+git switch -c contrib/<your-username>/my-fix
git commit -am "fix(shell): handle an empty command"
-git push push HEAD:refs/heads/contrib/my-fix
+git push push HEAD:refs/heads/contrib/<your-username>/my-fix
Use a credential helper rather than pasting the token into the
URL of a repository you might publish. Git will ask once and can remember it
(git config --global credential.helper store writes it to a plain file — choose
@@ -307,7 +307,7 @@ URL of a repository you might publish. Git will ask once and can remember it
What the server enforces
| Rule | Reason |
- Only refs/heads/contrib/* | main and tags are generated by the publisher; a push there would disappear at the next publish |
+ Only refs/heads/contrib/<you>/* | main and tags are generated by the publisher; a push there would disappear at the next publish. The middle segment must be your own username — the hook compares it to the account that authenticated, so nobody can overwrite a neighbour's branch |
| No credentials in the diff | The repository is public. Every added blob is scanned before it is accepted; a match rejects the whole push with the file name |
| No profile or key files | .user.json, .session, .env, *.pem, id_rsa are refused by path |
| ≤ 200 files, ≤ 2 MB of new content per push | Keeps one push from making the mirror unusable |
@@ -319,8 +319,8 @@ URL of a repository you might publish. Git will ask once and can remember it
touching code is queued for a human with a diff summary, and a branch that breaks a hard rule is deleted.
The queue is visible to the operator; you will hear back on your branch, not in a black hole.
git fetch push 'refs/heads/contrib/*:refs/remotes/contrib/*'
-git log --oneline main..contrib/my-fix # what your branch adds
-git push push --delete contrib/my-fix # withdraw it
+git log --oneline main..contrib//my-fix # what your branch adds
+git push push --delete contrib//my-fix # withdraw it
Updating later
cd newos4
--
cgit v1.2.3