Skip to content

Git over HTTPS

githosted is real Git. Anything git clone, git fetch, git push, git tag, or any other client-side Git invocation can do, you can do against githosted.dev. Auth is HTTP Basic with a gw_ / gr_ token as the password — the SDK and git are two windows into the same repo.

Section titled “The recommended local setup: gho auth login”
Terminal window
curl -fsSL https://githosted.sh | sh
gho auth login

That’s the whole flow. gho auth login opens your browser, runs the OAuth dance, stores the token in your OS keychain, and writes git’s credential-helper config. After that, every git clone / fetch / push against githosted Just Works:

Terminal window
git clone https://githosted.dev/<ws>/<repo>.git

No token in the URL. No extraHeader. No prompt. Same UX as gh auth login + Git Credential Manager.

gho auth logout revokes the token server-side, clears the keychain entry, and unsets the helper config — fully clean.

Open the repo page and click Clone. The dropdown’s HTTPS tab has a copy-paste setup block that wires git’s http.extraHeader against githosted.dev. Paste once into your shell; afterward git clone works the same as the CLI path above.

The rest of this page is the manual reference for environments without a browser handy — CI runners, scripts, headless terminals, Docker build contexts.

https://githosted.dev/<workspace-slug>/<repo-slug>.git

The workspace slug is the human-readable one you see in the dashboard URL, not the ws_… ID. Same for the repo slug.

Both https://githosted.dev/<ws>/<repo>.git and the longer https://api.githosted.dev/git/<ws>/<repo>.git work and resolve to the same repo. The shorter apex form is what we recommend and what the dashboard shows; the api. form is the underlying origin if you ever need to bypass the apex proxy (e.g. debugging).

Git uses HTTP Basic for password-based auth. The server doesn’t care about the username — put anything there, or just put the token:

Terminal window
git clone https://gw_xxxx@githosted.dev/<ws>/<repo>.git

That works. It’s also the wrong way to do it for anything beyond a one-shot clone, because:

  1. The token ends up in ~/.githosted/<repo>/.git/config (Git stores the URL as-is when you use git clone <url>).
  2. The token shows up in your shell history.
  3. Other tools that read git remote -v see the token in plain text.

So clone without the token in the URL, and let Git’s credential helper handle the prompt:

Terminal window
git clone https://githosted.dev/<ws>/<repo>.git
# Username for 'https://githosted.dev': anything
# Password for 'https://anything@githosted.dev': gw_…

Once Git asks for credentials and you give the token, the configured credential helper stores it for next time.

Terminal window
git config --global credential.helper osxkeychain

The token is stored in the macOS Keychain. Subsequent clones, fetches, and pushes don’t prompt.

Terminal window
git config --global credential.helper libsecret

Stores the token in the GNOME Keyring or KDE Wallet via the freedesktop Secret Service.

If libsecret isn’t built in, install Git’s libsecret helper:

Terminal window
sudo apt install libsecret-1-0 libsecret-1-dev
sudo make --directory=/usr/share/doc/git/contrib/credential/libsecret

Git for Windows ships with the manager-core helper out of the box — nothing to configure.

If you’d rather not use a credential helper at all, set Git’s http.extraHeader for the githosted host:

Terminal window
git config --global http.https://githosted.dev/.extraHeader \
"Authorization: Bearer gw_xxxx"

Now any git clone https://githosted.dev/... call sends an Authorization: Bearer … header without needing HTTP Basic. This is what most CI environments end up doing.

In a workflow, the token comes from a secret and gets injected as an extraHeader for the duration of the job:

- name: Clone githosted repo
env:
GITHOSTED_TOKEN: ${{ secrets.GITHOSTED_TOKEN }}
run: |
git -c http.https://githosted.dev/.extraHeader="Authorization: Bearer $GITHOSTED_TOKEN" \
clone https://githosted.dev/<ws>/<repo>.git

Or, if you’re already using the SDK in the same job, skip the git clone entirely and use repo.read / repo.write against the same token via GITHOSTED_TOKEN. The SDK is usually the simpler path inside CI.

The cleanest pattern for a Dockerfile that needs to pull from a githosted repo at build time is BuildKit secrets:

1.7
FROM alpine:3
RUN apk add --no-cache git
RUN --mount=type=secret,id=githosted_token \
GITHOSTED_TOKEN=$(cat /run/secrets/githosted_token) && \
git -c http.https://githosted.dev/.extraHeader="Authorization: Bearer $GITHOSTED_TOKEN" \
clone https://githosted.dev/<ws>/<repo>.git /src

Build with:

Terminal window
docker build --secret id=githosted_token,env=GITHOSTED_TOKEN .

The token never lands in an image layer.

  • git clone, git fetch, git pull, git push
  • Branches, tags, lightweight refs
  • Annotated tags, commit messages, signatures (GPG / SSH-key signing — the server doesn’t validate the signature, but it preserves the signed commit object)
  • Submodules — both directions, as long as both submodule and parent are reachable with the same token / credential helper
  • git lfs — yes, but treat large binaries as the exception, not the rule. See Concepts → Repos for our take
  • SSH access (git@…). Planned and coming. Use HTTPS for now.
  • Anonymous public read. Coming with public repos — see the public-repos plan. Until then every clone needs a token.
  • Read-only mirroring with no token. Same — gated until public repos ship.