{"id":51239882,"url":"https://github.com/matixandr/git-lan","last_synced_at":"2026-06-28T23:31:54.278Z","repository":{"id":367583008,"uuid":"789387073","full_name":"matixandr/git-lan","owner":"matixandr","description":"Zero-config, end-to-end encrypted peer-to-peer git collaboration on your LAN. No server, no internet, no accounts.","archived":false,"fork":false,"pushed_at":"2026-06-26T15:12:52.000Z","size":192,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2026-06-26T17:02:54.995Z","etag":null,"topics":["cli","cross-platform","decentralized","encryption","end-to-end-encryption","git","golang","hackathon","lan","mdns","networking","p2p","peer-to-peer","zero-config","zeroconf"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/matixandr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-04-20T12:02:14.000Z","updated_at":"2026-06-26T15:13:01.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/matixandr/git-lan","commit_stats":null,"previous_names":["matixandr/git-lan"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/matixandr/git-lan","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matixandr%2Fgit-lan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matixandr%2Fgit-lan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matixandr%2Fgit-lan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matixandr%2Fgit-lan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/matixandr","download_url":"https://codeload.github.com/matixandr/git-lan/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/matixandr%2Fgit-lan/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34907985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","cross-platform","decentralized","encryption","end-to-end-encryption","git","golang","hackathon","lan","mdns","networking","p2p","peer-to-peer","zero-config","zeroconf"],"created_at":"2026-06-28T23:31:52.836Z","updated_at":"2026-06-28T23:31:54.269Z","avatar_url":"https://github.com/matixandr.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/image.svg\" alt=\"git-lan\" width=\"560\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003egit-lan\u003c/h1\u003e\n\n[![Go](https://img.shields.io/badge/Go-1.26-00ADD8?logo=go\u0026logoColor=white)](https://go.dev)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Platforms](https://img.shields.io/badge/platforms-Linux%20%7C%20macOS%20%7C%20Windows-blue)](#installation)\n[![E2E](https://img.shields.io/badge/transport-end--to--end%20encrypted-success)](SECURITY.md)\n\n**Share git repositories with people on the same network - no server, no\naccount, no GitHub, no configuration.** Start a session, and colleagues discover\nyou over mDNS and can clone, push, and pull instantly. Every byte between peers\nis end-to-end encrypted.\n\n```console\n$ git lan session create --name hackathon\n✓ session \"hackathon\" is live\n  port:        9418 (encrypted)\n  fingerprint: SHA256:Hk9s2…\n\n# on a colleague's machine, on the same Wi-Fi:\n$ git lan list\n● maciek-laptop  main  abc1234  just now   hackathon\n$ git lan clone maciek-laptop/project\n```\n\n\u003e **Nerd Fonts - optional but recommended**\n\u003e\n\u003e git-lan auto-detects whether your terminal supports Nerd Fonts glyphs and\n\u003e remembers the result per terminal profile. Nothing to configure. Install a\n\u003e patched font from [nerdfonts.com](https://www.nerdfonts.com) for the nicest\n\u003e output; plain terminals fall back to clean ASCII automatically.\n\n---\n\n## Why\n\nSometimes the network *is* the room you're in.\n\n- **Hackathons** - share a repo with your team in seconds, even when the venue\n  Wi-Fi has no internet.\n- **Classrooms \u0026 workshops** - an instructor shares starter code; students clone\n  without accounts.\n- **Game jams** - push builds to a teammate across the table.\n- **CTF / airgapped labs** - collaborate where there is deliberately no internet.\n- **Anywhere GitHub is overkill** - you just want to hand someone a repo.\n\nNo central server means nothing to set up, nothing to trust but the people in\nthe room, and nothing that stops working when the internet does.\n\n## Features\n\n- **Zero-config discovery** - peers appear automatically over mDNS/DNS-SD.\n- **End-to-end encryption** - X25519 handshake, ChaCha20-Poly1305, per-direction\n  keys, anti-replay. No plaintext ever crosses the wire.\n- **Trust on first use** - pin peer fingerprints; loud man-in-the-middle\n  warning on mismatch.\n- **Sessions** - name a share, optionally password-protect it (Argon2id), mint\n  one-time invite tokens.\n- **Live presence** - see who is online, coding, or idle, with branch and HEAD.\n- **Conflict early-warning** - find out *before* you push that a teammate has\n  uncommitted work.\n- **Nerd Fonts auto-detection** - cached per terminal profile, no flags needed.\n- **Cross-platform** - Linux, macOS (Intel + Apple Silicon), Windows.\n\n## Quick Start\n\n```console\n# 1. In a git repo, start sharing it:\ngit lan session create --name demo\n\n# 2. On another machine on the same LAN, see who's around:\ngit lan list\n\n# 3. Clone their repo over the encrypted transport:\ngit lan clone \u003cpeer\u003e/demo\n\n# 4. Watch the room live:\ngit lan status\n```\n\nThat's it - there is no step 5.\n\n## Command reference\n\n| Command | What it does |\n| --- | --- |\n| `git lan list` | List peers on the LAN with branch, HEAD, presence. Also shows your own active session (a host is filtered out of its own mDNS results). |\n| `git lan status` | Live dashboard, refreshes every 5s (Ctrl+C to exit). Includes your own active session. |\n| `git lan clone \u003cpeer\u003e[/repo] [dir]` | Clone a peer's repo over E2E transport. |\n| `git lan pull \u003cpeer\u003e[/repo] [branch]` | Pull from a peer into the current repo. |\n| `git lan push \u003cpeer\u003e[/repo] [branch]` | Push to a peer (peer approves). |\n| `git lan session create` | Share the current repo. `--name`, `--password`, `--allow-push`. |\n| `git lan session join \u003cpeer\u003e[/repo]` | Join a session. `--password`, `--token`. |\n| `git lan session invite` | Mint a one-time, expiring join token. |\n| `git lan session leave` | Clear active session state. |\n| `git lan trust add \u003chost\u003e \u003cfingerprint\u003e` | Pin a peer's fingerprint. |\n| `git lan trust remove \u003chost\u003e` | Remove a pin. |\n| `git lan trust list` | List trusted peers. |\n| `git lan config` | Show resolved config and paths. |\n| `git lan config --detect-fonts` | Re-probe Nerd Fonts for this terminal. |\n| `git lan completion \u003cshell\u003e` | Shell completion (bash/zsh/fish/powershell). |\n\nGlobal flags: `--no-nerd-fonts`, `--no-color`, `--verbose`, `--version`.\n\n### Examples\n\n```console\n# Share with a password and allow pushes back:\ngit lan session create --name sprint --password hunter2 --allow-push\n\n# Invite someone without telling them the password:\ngit lan session invite --ttl 30m\n\n# Join a locked session:\ngit lan session join bartek-pc/sprint --password hunter2\n# ...or with a one-time token:\ngit lan session join bartek-pc/sprint --token 3xK9mQ2…\n\n# Pin a colleague after verifying their fingerprint out of band:\ngit lan trust add maciek-laptop SHA256:Hk9s2…\n```\n\n## Architecture\n\n```\n   [Peer A]                         [Peer B]\n      │                                │\n      ├── mDNS broadcast ─────────────\u003e│  discovery layer\n      │\u003c── mDNS broadcast ─────────────┤  (_gitlan._tcp, TXT metadata)\n      │                                │\n      ├── TCP connect ────────────────\u003e│\n      ├── X25519 ephemeral handshake -\u003e│  E2E encryption\n      │\u003c── X25519 ephemeral handshake ─┤  directional session keys established\n      │                                │\n      ╔════════════════════════════════╗\n      ║  ChaCha20-Poly1305 encrypted   ║\n      ╠════════════════════════════════╣\n      ║  git push / pull / clone       ║  transport layer\n      ╚════════════════════════════════╝\n```\n\ngit itself never sees the network: on the serving side a one-shot\n`git daemon --inetd` reads and writes the *decrypted* stream; on the client side\ngit talks to a loopback bridge that encrypts before anything leaves the machine.\n\n## Security model\n\nEvery peer connection is end-to-end encrypted before a single git byte flows:\nephemeral X25519 for forward secrecy, long-term identity keys mixed in to defeat\nman-in-the-middle, HKDF-derived per-direction ChaCha20-Poly1305 keys, and strict\nnonce anti-replay. Sessions add Argon2id passwords and one-time HMAC invite\ntokens. Peer fingerprints are pinned; a mismatch aborts loudly.\n\nmDNS TXT records are broadcast in the clear **by design** and contain only\nharmless metadata (repo name, branch, short HEAD, modified count, session name,\nlock flag, presence) - never keys, passwords, or file contents.\n\nSee **[SECURITY.md](SECURITY.md)** for the full threat model and details.\n\n## Nerd Fonts\n\ngit-lan detects Nerd Fonts support **per terminal profile** and caches the\nresult, so it probes at most once per terminal.\n\n1. It builds a stable key for your terminal (Windows Terminal profile GUID,\n   `TERM_PROGRAM`, `TERM`, etc.).\n2. It checks `terminal_profiles.toml` for a cached result.\n3. On a cache miss in a real TTY, it draws a glyph and measures cursor movement\n   with ANSI cursor-position queries to decide if the font rendered it.\n4. It caches the answer under your terminal's profile key.\n\nOverride order (highest first):\n\n1. `--no-nerd-fonts` flag\n2. `nerd_fonts = true|false` in `config.toml`\n3. cached per-profile result\n4. live TTY probe\n5. non-TTY → plain icons\n\nForce a re-probe (e.g. after switching fonts):\n\n```console\ngit lan config --detect-fonts\n```\n\n### `terminal_profiles.toml`\n\nStored in the config directory; one entry per terminal profile:\n\n```toml\n[profiles.\"windows-terminal:{2c4de342-38b7-51cf-b940-2309a097f518}\"]\nnerd_fonts = true\ndetected_at = \"2025-04-10T18:22:00\"\n\n[profiles.\"vscode:\"]\nnerd_fonts = false\ndetected_at = \"2025-04-10T18:25:13\"\n```\n\n## Installation\n\n### Quick install (any platform)\n\n```console\ngo install github.com/matixandr/git-lan@latest\n```\n\n`git` resolves `git lan` to any `git-lan` executable on your `PATH`, so once it's\ninstalled the subcommand just works. The binary lands in `$(go env GOPATH)/bin` -\nmake sure that directory is on your `PATH`. Requires **Go 1.26+**.\n\n### From source\n\n```console\ngit clone https://github.com/matixandr/git-lan\ncd git-lan\n# Unix:\n./scripts/install.sh\n# Windows (PowerShell):\n./scripts/install.ps1\n```\n\n### Cross-compiled binaries\n\n```console\nmake dist     # builds dist/git-lan-\u003cos\u003e-\u003carch\u003e for all supported platforms\n```\n\n### Requirements\n\n- **git** in your `PATH` (git-lan shells out to it).\n- **Go 1.26+** to build from source.\n- **mDNS** on the network. Linux typically uses Avahi; macOS has Bonjour\n  built in; on **Windows**, install **Bonjour** (bundled with iTunes or the\n  Bonjour Print Services package) if peer discovery comes up empty.\n\n### Config directory\n\n| Platform | Location |\n| --- | --- |\n| Linux | `$XDG_CONFIG_HOME/gitlan` or `~/.gitlan` |\n| macOS | `~/.gitlan` |\n| Windows | `%APPDATA%\\gitlan` |\n\nHolds `config.toml`, `identity.key` (0600), `sessions.json`,\n`trusted_peers.json`, and `terminal_profiles.toml`.\n\n## Known limitations\n\n- **LAN only, by design.** git-lan does no NAT traversal and is not meant to\n  reach across the internet. That's the point.\n- **No web UI.** It's a CLI.\n- **Discovery needs working mDNS.** Some corporate networks block multicast;\n  there is nothing git-lan can do about that.\n- **Not audited.** The cryptography is conventional and carefully built, but this\n  is a hobby project - don't guard state secrets with it.\n\n## Contributing\n\nIssues and pull requests welcome. Keep changes focused, run `go vet ./...` and\n`go test ./...` before submitting, and match the existing style. The codebase is\nsmall and organized by concern under `internal/` - start with the package whose\nname matches what you're touching.\n\n## License\n\nMIT © matixandr - see [LICENSE](LICENSE).\n\nGit logo by Jason Long, licensed under [CC BY 3.0](https://creativecommons.org/licenses/by/3.0/) ([git-scm.com/downloads/logos](https://git-scm.com/downloads/logos)).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatixandr%2Fgit-lan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatixandr%2Fgit-lan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatixandr%2Fgit-lan/lists"}