Commit 77cf5aa

Nick Faro committed on
update readme
commit 77cf5aa3fdb9469c5588294ce21a8d87fa3ecffd parent 69bd667
2 changed files +12−95
ModifiedREADME.md +10−93
@@ -1,28 +1,22 @@
1 # dumbforge 1 # dumbforge
2 2
3 `dumbforge` turns an S3-compatible bucket into a static Git host. Authors push 3 Well, everyone's [been talking about GitHub alternatives](https://mitchellh.com/writing/ghostty-leaving-github) lately. I'm pretty sympathetic to that on an ideological level (and just the fundamental problem of it being down all the time), but historically the alternatives kind of suck, and I think still miss the point of Git being decentralized in the first place. Gitea/Forgejo are cool, but require you to set up a server and configure it. Even though it's pretty easy, it's still annoying and requires you to pay for and babysit a VPS or whatever to run the forge program. Codeberg has been a platform of choice for freedom-heads to get away from GitHub, but they recently instituted a no-crypto and no-LLM rule. I respect what they're doing, but I'm pretty AI-pilled so that's not going to work for me.
4 through a Git remote helper; everybody else clones with ordinary Git over dumb
5 HTTP. Each push also publishes a static repository browser at the same URL.
6 4
7 This is an early implementation. It has been exercised against Cloudflare R2, 5 It occurred to me that you don't actually need to run a forge or git daemon at all, since Git supports cloning via the so-called ["dumb" HTTP protocol](https://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols). You could theoretically just throw your git repo into an s3 bucket, and it would be clone-able, no daemon or VPS required. So that's cool, and even more decentralized; but the problem with self-hosting git like that, is that then you don't have the nice landing page, file browser, commit log, etc etc. It's small, but it makes a big difference to have a GitHubby UI for each project. SourceHut and Savannah struggle with this I think, since they're pretty alien to normies.
8 including a full public clone and incremental multi-pack pushes.
9 6
10 ## Install 7 So I slopped `dumbforge` together as a proof of concept; it's a static-site-generator like thing that functions as a git adapter which pushes directly to an s3 bucket, and generates a GitHub-like UI. So you get some really nice advantages:
11 8
12 The planned primary distribution is npm: 9 1. It's super fast to browse, since it's just static HTML. GitLab and GitHub itself are really slow clunky beasts.
10 2. You don't need to administer a git daemon or forge server.
11 3. It's free if you're storing less than 10 gigs, using CloudFlare R2.
12 4. You're decentralized, bro! Well, mostly.
13 13
14 ```sh 14 I'll grant that the implementation could most certainly use some improvement but this is mostly just to show off the idea. I hope it piques your curiosity. 🤔
15 npm install --global dumbforge
16 ```
17 15
18 The npm package selects a native Go binary for the current OS and CPU from an 16 ## Install
19 npm-hosted platform package. It does not run an installer that downloads a
20 GitHub release. Until the first npm release, build locally with Go 1.26 or
21 newer:
22 17
23 ```sh 18 ```sh
24 go build -o dumbforge ./cmd/dumbforge 19 npm install --global dumbforge
25 ln -s dumbforge git-remote-dumbforge
26 ``` 20 ```
27 21
28 Git itself must also be installed. The implementation deliberately asks Git to 22 Git itself must also be installed. The implementation deliberately asks Git to
@@ -68,86 +62,9 @@ git clone https://pub-EXAMPLE.r2.dev/projects/example.git
68 The repository browser is served from that exact URL. Git appends 62 The repository browser is served from that exact URL. Git appends
69 `/info/refs`; browsers receive the HTML object stored at the repository prefix. 63 `/info/refs`; browsers receive the HTML object stored at the repository prefix.
70 64
71 ## How a push works
72
73 1. Acquire an S3 conditional-write lease for the repository.
74 2. Read the currently advertised refs and pack list.
75 3. Validate fast-forward and concurrent-ref constraints.
76 4. Ask local Git for a non-thin pack containing objects reachable from the new
77 tips but not the known remote tips.
78 5. Upload the immutable `.pack` and `.idx`.
79 6. Publish `objects/info/packs`, individual refs, `HEAD`, and finally
80 `info/refs`.
81 7. Generate changed source/raw pages, affected ancestor tree pages, and the
82 branch's commit and repository-summary pages. A compact repository ref
83 manifest and per-branch file index power navigation without rebuilding every
84 existing page.
85
86 Git data is never rebuilt on an ordinary push. Two small commits produce two
87 small packs. The mutable dumb-HTTP indexes are tiny and served with revalidation;
88 content-addressed packfiles are served as immutable objects.
89
90 ## Static browser
91
92 The generated browser includes:
93
94 - repository and directory trees;
95 - per-file latest commit messages linked into branch history;
96 - rendered GitHub-flavored Markdown README files;
97 - syntax highlighting and linked line numbers;
98 - raw file URLs and image previews;
99 - a live branch switcher with branch-aware paths;
100 - a searchable Go-to-file dialog;
101 - full commit history with contributor Gravatars;
102 - top contributors and Linguist-compatible language percentages;
103 - a clone popover with copy confirmation and the public HTTPS URL;
104 - a GitHub Importer shortcut that copies the clone URL before opening the
105 importer, ready to paste into GitHub's source URL field;
106 - an About panel derived from package metadata, the README, and the upstream
107 remote;
108 - incremental regeneration based on `git diff --name-status`.
109
110 GitHub's repository description is not part of Git data. Override the inferred
111 About metadata in the local repository when needed:
112
113 ```sh
114 git config dumbforge.description "A short repository description"
115 git config dumbforge.homepage "https://example.com/project"
116 ```
117
118 Contributor avatars are loaded from Gravatar using the normalized SHA-256 hash
119 of each commit author's email address. Gravatar's generated initials are used
120 when an author has no uploaded image.
121
122 The browser uses [Primer Octicons](https://github.com/primer/octicons), GitHub's
123 MIT-licensed icon set. See `THIRD_PARTY_NOTICES.md` for attribution. The "Fork
124 to GitHub" action uses GitHub Importer; it creates an independent repository and
125 does not add the imported repository to a GitHub fork network.
126
127 ## Current constraints
128
129 - Shallow repositories are rejected because static dumb HTTP has no shallow
130 boundary negotiation.
131 - There is no pack compaction command yet. A future `dumbforge gc` will combine
132 accumulated incremental packs outside the normal push path.
133 - Git LFS is not implemented.
134 - Branch deletion removes Git refs, but full static-page cleanup for a deleted
135 branch is not implemented yet.
136 - The `r2.dev` hostname is intended for development; use an R2 custom domain for
137 production traffic and explicit cache rules.
138
139 ## Development 65 ## Development
140 66
141 ```sh 67 ```sh
142 go test ./... 68 go test ./...
143 go build ./cmd/dumbforge 69 go build ./cmd/dumbforge
144 ``` 70 ```
145
146 Build all npm platform packages with:
147
148 ```sh
149 ./scripts/build-npm-packages.sh 0.1.0
150 ```
151
152 The resulting tarballs are written to `dist/npm`. Publish the six platform
153 packages first and the `dumbforge` launcher package last.
Modifiedpackage.json +2−2
@@ -2,10 +2,10 @@
2 "name": "dumbforge", 2 "name": "dumbforge",
3 "version": "0.1.0", 3 "version": "0.1.0",
4 "description": "Push Git repositories to S3-compatible buckets and clone them over static dumb HTTP", 4 "description": "Push Git repositories to S3-compatible buckets and clone them over static dumb HTTP",
5 "license": "MIT", 5 "license": "AGPLv3",
6 "repository": { 6 "repository": {
7 "type": "git", 7 "type": "git",
8 "url": "git+https://github.com/npfaro/dumbforge.git" 8 "url": "git+https://dumbforge.dev/dumbforge.git"
9 }, 9 },
10 "keywords": [ 10 "keywords": [
11 "git", 11 "git",