Running your own remote
newgit serve is the newgit remote as one process, built into the newgit
binary: each tracker's Git history on the machine's own disk, project state in
one SQLite database, and the same API newgit.dev answers. A project points at
it the way it points at newgit.dev, and nothing else about using newgit
changes. It needs git on the PATH, and runs on Linux and macOS.
newgit serve --data /var/lib/newgit --listen 0.0.0.0:8484 \
--url https://git.example.com --allow '*' --admin jack \
--github-client-id <oauth app id>
It prints newgit serve: listening on <url> and stays in the foreground;
Ctrl-C stops it, and starting it again on the same --data carries on where
it was.
--data <dir>is everything the remote keeps:server.sqlite, thetoken.keytokens are signed with, and a repository per tracker underhomes/<owner>/<project>/. Back it up as a directory, with the server stopped. There is no online backup yet.--listenis127.0.0.1:8484unless you say otherwise, and127.0.0.1:0picks a free port and prints it.--urlis the address clients reach it at, when that is not the one they asked by. TLS is not the binary's job: put Caddy or nginx in front, and name the public address here.--allowlists the GitHub logins who may log in, or*for anyone. It starts empty, which admits no one.--blockshuts logins out whatever--allowsays,--adminnames who may delete any project and own any number, and--projects-per-login(5) caps everyone else.--github-client-idis a GitHub OAuth app's client id, with device flow enabled on the app, fornewgit login. Without itnewgit loginis refused withthis remote has no GitHub app configured.--git-slots(16) is how manygitprocesses may run at once.
Pointing a project at it
In the project, log in and link it:
newgit login --url https://git.example.com
newgit remote add --url https://git.example.com
remote add creates <you>/<project> on the server, with a repository per
tracker in Git, and writes [remote] to .newgit/config.toml. Commit that
file, and the project's other commands (login, merge, members, a
workspace's git push) use this remote without being told. The owner adds a
teammate with newgit members add <login>, and the teammate then:
newgit login --url https://git.example.com
newgit clone jack/widget --url https://git.example.com
newgit spawn --from-checkpoint auth-refactor/ckpt_003
Plain Git reads it too: git clone https://git.example.com/jack/widget.git
gets the project's own commit ids, composed from the trackers you may read.
The Git password is your newgit token, and the server checks it on every
request, so removing a member takes effect on their next fetch.
To try it on one machine, start it with --dev-login-secret <secret> (or
NEWGIT_SERVE_DEV_LOGIN_SECRET) and no GitHub app. A caller holding the
secret logs in as any login --allow admits:
curl -X POST http://127.0.0.1:8484/v1/dev/login \
-H 'x-dev-login: <secret>' -d '{"login": "jack"}'
The answer holds token and token_id. newgit login cannot use this, since
it is GitHub's device flow, so save them where it would have, in
~/.newgit/auth.toml:
[remotes."http://127.0.0.1:8484"]
login = "jack"
token = "ngt_..."
token_id = "tok_..."
Never give a remote anyone can reach a dev login secret.
Against newgit.dev
The rules are the same: who may read and merge each tracker, members, tokens,
checkpoints, forks, tags, newgit merge, clone, and spawn --from-checkpoint. Policy is read from each tracker's main, as on newgit.dev.
A project moves between them by remote add --url, and a CLI that works
against one works against the other.
What differs is the machinery, and it is the reason to run it:
- It is fast. Without Artifacts, a Durable Object, and a container between a
request and the repository,
remote addtakes about 0.85 s on one machine (9.4 s on newgit.dev), a plaingit clone0.4 s, a merge 1.2 s, andspawn --from-checkpoint1.1 s. Those numbers have no internet round trips in them. - A fork costs nothing. It is a Git namespace inside the tracker's repo, not a copy, except for a private instance's, which gets a repo of its own.
- Two merges begun from the same state conflict even when they are at different anchors, and the second merges again. A merge in flight is kept in memory, so restarting the server tells its merger to start the merge over.
What it does not do yet:
- GitHub webhooks and mirror pulls: a pull request merged on a GitHub mirror
does not land in
mainby itself. - The site: no landing page, no
/install.sh, and no wiki at/docs. - The spend kill switch, backups, and replicas.
- Taking over newgit.dev. That still runs on the Worker, until moving its data across is designed and tested.
docs/design/serve.md
has the layout, the decisions, and the full list.