OwnGit Download

Keep your code at home,
and undo a bad push.

OwnGit is a Git server that runs on your own computer, NAS or home server. When a force-push or a deletion replaces a branch, whether you did it or a coding agent did, OwnGit keeps the old commits so you can restore them from the browser. It is one program with a SQLite file, uses about 45 to 70 MB of memory, and has no accounts to sign up for.

brew install juliankang4/tap/owngit

Every method needs Git with git-http-backend on the host. Homebrew and the Arch package install Git for you.

~/website
$ git push --force origin main
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 274 bytes | 274.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To http://127.0.0.1:18432/git/website.git
 + f744962...dfdad84 main -> main (forced update)
$ 
Real output of a force-push to OwnGit. The replaced commit f744962 stays in kept history.

Why host your own Git

Problems that people who run their own Git server often raise, and how OwnGit handles each one.

  • I don't want my private code on someone else's cloud.

    Your code stays on your machine. Repositories are ordinary bare Git repositories on your computer, NAS or home server. You need no cloud account or subscription, and you can bring existing repositories over from any HTTPS Git host. OwnGit's source is open under the MIT License.

  • I need to undo a force-push or a deleted branch, even one my coding agent made.

    Kept history. OwnGit keeps the branches and tags that a push replaced or deleted. In the browser you see every change first, then restore the whole tree or only the files you pick.

  • I need backups that actually restore.

    Offline backups. owngit backup copies refs and objects, pull request, check and import records, and portable settings, with SHA-256 hashes. owngit restore brings a backup back as a new installation.

  • I don't want to look after another heavy server with its own database.

    One program, about 45 to 70 MB. OwnGit is one Go executable and a SQLite file. There is no database service to run and no Node or Python at runtime. Idle, it uses about 45 MB of memory, or about 70 MB with 1,000 repositories.

  • I'm tired of cleaning up spam sign-ups.

    No sign-up, no accounts. OwnGit has no registration page and no user accounts, so bots have nothing to register. Repositories are either open or protected by one shared password, and a separate administrator password protects security settings.

  • I want to reach it from my laptop without opening a port.

    HTTPS on your tailnet. By default OwnGit accepts connections only from its own computer. Turn on Tailscale Serve in Settings or with owngit tailscale on, or put your own reverse proxy in front.

  • My coding agent needs tools it can call with exact arguments.

    owngit mcp and a JSON command line. The MCP tools cover repositories, pull requests, diffs and checks. Each one states what it changes and returns the same JSON as the matching command, so an agent that prefers the shell can run owngit pr diff directly.

Restore what a force-push replaced

When a push replaces a branch or someone deletes one, OwnGit keeps the old commits in kept history. Open the repository in the browser, review every change a restore would make, then restore the whole tree or only the files you choose. A push from a coding agent is restored the same way.

Kept history is not a backup. It also keeps anything pushed by mistake, such as a secret, so replace a leaked secret instead of trying to remove it with a force-push.

Dashboard
Screen recording of the dashboard: the repository after that push, choosing the kept commit, reviewing every change and restoring. Restoring is done in the dashboard; there is no command for it. Recorded with OwnGit v1.1.0 (9fef945) and sample repositories.

Backups for the day a disk fails

Stop OwnGit and run one command. The backup contains every ref and object, kept history included, plus pull request, check and import records and portable settings, with SHA-256 hashes to detect corruption. owngit restore restores it into a new state directory.

Terminal
~
$ owngit backup --output ~/Backups/owngit-backup
Offline backup written to ~/Backups/owngit-backup. SHA-256 hashes detect
 corruption but do not authenticate a replaced backup.
$ owngit restore --input ~/Backups/owngit-backup --state-dir ~/restored-
state --repository-root ~/restored-repositories
Offline backup restored to ~/restored-state with repositories at ~/resto
red-repositories. Previous sessions, trusted hosts, and network settings
 were not restored.
Real output of owngit backup and owngit restore with OwnGit stopped. Backups and restores run from the terminal only. Recorded with OwnGit v1.1.0 (9fef945) and sample repositories.

One program,
about 45 MB of memory

OwnGit is one Go executable of about 30 MB plus a SQLite file, with no database service to run. These figures were measured on Linux x64, a Raspberry Pi 5, Windows 11 and macOS.

45MB

Idle memory, no repositories

Linux x64, Raspberry Pi 5 and Windows 11

70MB

Idle memory, 1,000 repositories

About 50 MB with 100 repositories. 67 MB on macOS, measured as footprint.

0.07s

Start to first page

Median of fresh starts on Linux x64. 0.2 s on a Raspberry Pi 5.

<1%

Idle CPU (share of one core), 1,000 repositories

Measured 0.15 to 0.64%. Usually 0.1% or less with up to 100 repositories.

Measured with OwnGit 1.1.0 after setup, once memory had settled and nobody was using it, as resident memory (RSS or working set). A clone or push also runs Git, whose memory comes on top and depends on the repository.

Compared with two other self-hosted Git servers
ServerIdle, no repositoriesIdle, 100 repositories
A171.0 MB178.0 MB
B190.9 MB196.4 MB
OwnGit 1.1.045.4 MB50.7 MB

Default installs with SQLite in the same Debian 13 container (2 cores, 2 GB), measured as the server process's RSS after a 6-minute settle. A and B do much more out of the box, such as an issue tracker, wiki, packages and CI, so this compares default installs, not equal work.

Idle memory as repositories are added Linux x64, all bars on one scale
  • No repositories44.8 MB
  • 100 repositories49.8 MB
  • 1,000 repositories69.4 MB

No sign-up page, no open port

OwnGit has no registration page and no user accounts. Repositories are open to your network or protected by one shared password, and a separate administrator password protects security settings.

To use it from your laptop or phone, turn on sharing in Settings or run owngit tailscale on, and OwnGit is served over HTTPS on your tailnet. Before it turns on, OwnGit tells you that the computer and tailnet names will appear in a public certificate log. A reverse proxy also works, and the operations guide has examples for Caddy, nginx and Traefik.

Sample tailnet, no real Tailscale
The Network and Tailscale cards in Settings, and the same steps with owngit network and owngit tailscale, recorded with a sample tailnet and no real Tailscale. Recorded with OwnGit v1.1.0 (9fef945) and sample repositories.

Pull requests in the browser or the terminal

Open a pull request, read the changes and merge exactly the commits you reviewed. The dashboard and owngit pr take the same steps on the same data. Review is optional.

Checks you run on your own machine are recorded for the exact commit they tested. They are advisory and never block a merge.

The same pull request in the dashboard and with owngit pr. The command merges only the commits it names. Recorded with OwnGit v1.1.0 (9fef945) and sample repositories.

Tools for you and your coding agents

owngit mcp is a local MCP server that talks over standard input and output and opens no network port. Its tools read repositories, pull requests, diffs and checks, create and review pull requests, and run the checks committed in your clone. Each returns the same JSON as the matching command. Inside a clone, owngit pr and owngit repo find the server from origin.

~/projectRecorded with Claude Code 2.1.283, model sonnet
 ▐▛███▛█   Claude Code v2.1.283
▝▜██████▀  Sonnet 5 · Claude Max
 ▝▝   ▝▝   ~/project


❯ List the repositories on OwnGit. Open a pull request from feature/sitemap into main titled "Add   
  sitemap" and show its diff stat. Create a check task and run the checks. If they pass, approve    
  the pull request as reviewer "claude-code" and merge it. Reply in two short sentences.            

  Called owngit 3 times (ctrl+o to expand)

⏺ PR #1 diff stat: .owngit/checks.json (+12), sitemap.xml (+2) — 2 files, 14 insertions.

  Called owngit 2 times (ctrl+o to expand)

⏺ Checks passed (clean worktree, tested commit e0e3ec7). Proceeding to approve and merge.

  Called owngit 2 times (ctrl+o to expand)

⏺ OwnGit hosts one repository, "website"; PR #1 "Add sitemap" changed 2 files (+14 lines), passed
  its check (xmllint --noout sitemap.xml), was approved by "claude-code", and merged into main via
  fast-forward.

✻ Cogitated for 53s · done 2:46 PM

────────────────────────────────────────────────────────────────────────────────────────────────────
❯ delete the feature/sitemap branch
────────────────────────────────────────────────────────────────────────────────────────────────────
  ⏵⏵ auto mode on (shift+tab to cycle) · ← for agents

Claude Code, Codex and Pi, each connected with the setup from the coding tools guide, get the same request and work on their own copy of the sample repository. The tools are named only to say what was recorded. Recorded with OwnGit v1.1.0 (9fef945) and sample repositories. The Codex demo was recorded with OwnGit 1.0.3 (4de74df).

Install with one command

Every method needs Git with git-http-backend on the host. Homebrew and the Arch package install Git for you.

brew install juliankang4/tap/owngit

macOS (Apple silicon) and Linux (x64, ARM64).

Start it

The first time you start OwnGit in a terminal, setup runs right there: pick a language, then continue in the terminal or in the browser. After that, create repositories in the dashboard or with owngit repo.

owngit serve
$ owngit serve
2026/09/26 14:44:40 using git version 2.54.0 (Apple Git-157) at /Applica
tions/Xcode.app/Contents/Developer/usr/libexec/git-core/git (found on PA
TH; the Git behind the macOS /usr/bin/git shim, same version)
2026/09/26 14:44:40 OwnGit listening on 127.0.0.1:18432

    ___                   ___  _  _
   / _ \ __ __ __  _ _   / __|(_)| |_
  | (_) |\ V  V / | ' \ | (_ || ||  _|
   \___/  \_/\_/  |_||_| \___||_| \__|

  First-run setup   http://127.0.0.1:18432/

+- Language / 언어 ----------------------------------------------------
|  [1] English
|  [2] 한국어
|
|  Press Enter for the default. You can switch later with L.
|  Enter만 누르면 기본값을 씁니다. 나중에 L 키로 바꿀 수 있습니다.
+----------------------------------------------------------------------
  Choice / 선택 [1]: 1

+- Set up OwnGit ------------------------------------------------------
|  OwnGit is running but has not been set up yet. Choose where to
|  answer the setup questions.
|
|  [1] Continue in this terminal
|      Answer a few questions here. Passwords stay hidden as you
|      type.
|
|  [2] Open the web dashboard
|      Approve your browser here, then continue setup in the
|      browser.
|
|  [L] 한국어
+----------------------------------------------------------------------
  Choice [1]: 1

+- Repository folder ------------------------------------------- 1/5 --
|  OwnGit creates repositories inside this folder and leaves
|  existing files alone.
|
|  Type a full path, or press Enter to use the suggested folder.
+----------------------------------------------------------------------
  Suggested: ~/OwnGit-Repositories
  Folder:
  [ok] OwnGit can use this folder.

+- Who can read and write repositories ------------------------- 2/5 --
|  This covers everyday repository use on your network. Security
|  settings always need the administrator password.
|
|  [1] Anyone on this network
|      No password for reading or pushing. Suitable for a private
|      LAN or a Tailscale network you control.
|
|  [2] People with the shared password
|      One shared password for everyone. There are no individual
|      accounts.
|
|  [L] 한국어
+----------------------------------------------------------------------
  Choice [1]: 1

+- Administrator password -------------------------------------- 3/5 --
|  Required to change security settings from any browser. Keep it
|  separate from the shared password.
|
|  Use 8 to 1024 characters. What you type stays hidden.
+----------------------------------------------------------------------
  Administrator password:
  Type it again:
  [ok] Administrator password entered.

+- Other devices ----------------------------------------------- 4/5 --
|  [ok] Tailscale is running on this computer.
|
|  Tailscale address   100.64.0.10
|  MagicDNS name       sample-host.example-tailnet.ts.net
|
|  To use OwnGit from your other Tailscale devices, save these
|  network settings with the command below, then restart OwnGit
|  after setup. You can change them later in Settings, under
|  Network.
|
|  Tailscale encrypts the connection between devices, but OwnGit
|  still reports plain HTTP because it cannot see that protection.
+----------------------------------------------------------------------

  Command that saves the settings (one line, copy all of it):

owngit network set --listen 100.64.0.10:18432 --base-url http://sample-h
ost.example-tailnet.ts.net:18432

  Saved settings also apply when OwnGit runs as a background service.
  Leave --listen and --base-url out of the service definition, because
  an option there replaces the saved value. See "Options for a
  background service" in the OwnGit docs.

  Press Enter to continue:

+- Review ------------------------------------------------------ 5/5 --
|  Nothing is saved until you choose Finish setup.
|
|  Repository folder        ~/OwnGit-Repositories
|  Access                   Anyone on this network
|  Administrator password   entered
|  Connection               this computer only
|
|  [1] Finish setup
|  [2] Start over
|
|  [L] 한국어
+----------------------------------------------------------------------
  Choice [1]: 1

+- [ok] Setup complete ------------------------------------------------
|  Dashboard   http://127.0.0.1:18432/
|
|  Create your first repository when you are ready.
+----------------------------------------------------------------------
  OwnGit keeps running. The server log continues below.

2026/09/26 14:44:43 setup completed
2026/09/26 14:44:43 OwnGit ready at http://127.0.0.1:18432/
First run in a terminal, then a repository created from the terminal or the dashboard, in a temporary home folder on test port 18432. Recorded with OwnGit v1.1.0 (9fef945) and sample repositories.