Chris Collins

Tools · dev

Git client

A git client in the browser: open a local repository (read-only unless you switch on write mode), see the commit graph, diffs, blame, file history, status and stashes; browse GitHub and GitLab repositories, pull requests and issues; clone over HTTPS through a relay you run.

Added

How to use it

How to use it

Local repository — Open a repository folder… and pick the folder that contains .git (or a bare repository). It needs the File System Access API: Chrome, Edge or Opera on a desktop. The browser grants read access only and nothing leaves your machine — the repository is read in the tab by isomorphic-git (1.38.10, loaded once from jsDelivr) through an adapter over the folder handle. Loose objects, packfiles, packed-refs, the index and the stash reflog all work. Try a demo repository builds a small one in memory, in any browser.

  • History — every branch, tag, remote-tracking branch and stash in one commit graph, newest first by commit date (like git log --all --date-order --graph). The list is virtualised and the graph lanes are laid out in a Web Worker, so 10,000+ commits scroll smoothly; more load as you scroll, or Load all. Arrow keys or j/k move. Search filters the loaded commits: words (message, author, id), author:ada, sha:3f2a, and path:src/app.js lists the commits that changed a file (following renames).

  • Commit details — message, parents (click to jump), author and committer, the files changed against the first parent (renames detected as git’s default -M50% does), and each file’s diff, unified or side by side, with changed words highlighted. Binary files show sizes (and images side by side); files over 1 MB ask before diffing.

  • Files — the tree at any branch, tag or commit; view a file, its History (commits that changed it, following renames, each with its diff), Blame (who last changed every line, across merges), or download it raw.

  • Status — staged, not staged and untracked files (respecting .gitignore), with diffs against the index and HEAD. Read-only, the client does not even refresh the index’s stat cache (real git status would).

  • Branches & tags — local and remote-tracking branches, tags (annotated ones marked), and the stash list.

  • Compare — two refs: their merge base, the commits only on each side, and the files changed since the merge base (like git diff A…​B).

Write mode is off until you tick it for that repository, confirm the warning, and the browser grants write permission. Then you can stage and unstage, commit (author from the repository’s user.name/user.email, or entered), create branches (and switch to one when the working directory is clean), switch branches, and tag HEAD (lightweight, or annotated with a message). Nothing destructive is offered — no reset, no force, no history rewriting, no deleting. It lasts until you reload or switch it off. Work on a copy if you are unsure.

GitHub / GitLab — type owner/repo (or group/project, or paste a URL) and Load: the commit graph per branch (with parents, so merges draw), branches and tags, the file tree, pull/merge requests with their diffs, reviews and review comments, and issues with comments. These are the providers' public REST APIs, which allow cross-origin requests. Without a token GitHub allows 60 requests an hour (shown above the results). A personal access token (read-only, fine-grained, with an expiry, please) is kept in this page’s memory and sent only to the provider in a header; remember on this device stores it in local storage after a warning. It never goes into a link.

Clone via relay — cloning speaks git’s "smart HTTP" protocol (GET …/info/refs?service=git-upload-pack, then POST …/git-upload-pack). GitHub, GitLab and the rest serve it without CORS headers, so a web page may not read the replies — no browser-only git client can clone directly. With the gitwebsite app (or gw serve) running on your computer the page clones through its companion’s git relay (fetch only; github.com, gitlab.com, codeberg.org, bitbucket.org and hosts you add in the app) — nothing to start; from this site press ⚡ Use the gitwebsite app once and approve the code in the app. Not needed if the gitwebsite app is running — otherwise run the relay on your own computer:

curl -O https://geekychris.github.io/tools/git-relay.py
python3 git-relay.py            # http://127.0.0.1:8097, standard library only

It forwards only clone/fetch requests (never pushes, unless you start it with --allow-push) to github.com, gitlab.com, codeberg.org and bitbucket.org (add others with --allow-host), answers only this site and local previews (--allow-origin for others), checks the Host header against DNS rebinding, binds to 127.0.0.1, and is not an open proxy. The page never uses a third-party proxy. The clone (single branch, shallow if you like) lives in memory and is browsed read-only.

Press f or ⛶ Full screen to give the graph and diffs the whole screen; Escape leaves.

Limits

  • Local folders need the File System Access API (desktop Chromium browsers). Safari, Firefox and phones can use the demo, the GitHub/GitLab tab and the relay clone.

  • Symbolic links are invisible to the browser; a .git file (a worktree or submodule) points outside the picked folder, so open the main repository. Submodule contents are not followed.

  • isomorphic-git is fetched from jsDelivr the first time; after that the browser cache serves it, so local repositories work offline only once it has been loaded.

  • History is in commit-date order; with badly skewed clocks a parent can appear above a child. Diffs are git’s Myers algorithm (a port of xdiff, identical to git diff --no-indent-heuristic), so a few hunks may slide differently from git’s default indent heuristic. Blame follows content through all parents but not code moved between files (git blame -C).

  • Big repositories: everything is read in the tab, so a first Load all on 100k commits takes a while and memory; file history and blame walk at most 5,000 commits. Clones are kept in memory.

  • Status hashes changed files to compare them; very large working trees are slow.

  • The REST views show the first page of pull requests and issues (50) and 100 files per commit or pull request; GitHub truncates very large trees and patches.

Tests compare the client with the git CLI on throwaway repositories: refs (including packed-refs and annotated tags), objects from packs and loose files byte for byte, git log --all --date-order on a 3,000-commit history with merges, git status --porcelain, git stash list, git blame, git log --follow, git diff --name-status -M, unified diffs, and git fsck --full --strict after commits, branches and tags made in write mode; plus the relay’s allow-lists.

Linking to an example

Links open the GitHub / GitLab tab on a public repository (never a token, never a local folder):

Parameter Meaning

provider

github (default) or gitlab

repo

owner/repo (GitHub) or group/project (GitLab)

view

commits, branches, files, pulls or issues

Runs entirely in your browser; nothing you type leaves this page.