vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Merge change request 01M70WES5ZZDJ6RP226WB11BBZ: Let people rename and remove their own passkeys
keenan · 18m ago
4b8c9e1d
| 1 | # LFS and file locking |
| 2 | |
| 3 | Large files should not force you onto a hosted service. With Git LFS, Git keeps a |
| 4 | small pointer file and Vole stores the actual file on infrastructure you control. |
| 5 | Repositories share one storage pool, so the same file is kept only once even if |
| 6 | several repositories use it. |
| 7 | |
| 8 | ## Using LFS |
| 9 | |
| 10 | ```sh |
| 11 | git lfs install # once per machine |
| 12 | git lfs track "*.psd" |
| 13 | git add .gitattributes art/hero.psd |
| 14 | git commit -m "add the hero art" |
| 15 | git push origin main |
| 16 | |
| 17 | git clone http://host/demo.git # LFS files come through the same URL |
| 18 | ``` |
| 19 | |
| 20 | Writes use the SSH key you already push with. Reads use the normal HTTP clone URL. |
| 21 | There is no token to create and no second server to configure. |
| 22 | |
| 23 | A repository can only download the files it actually uses. Knowing the file's hash |
| 24 | is not enough, because each repository has its own view of the shared storage. |
| 25 | |
| 26 | ## Limits and warnings |
| 27 | |
| 28 | ```toml |
| 29 | lfs_object_max_bytes = 2147483648 # one file; larger files are refused |
| 30 | lfs_warn_bytes = 5242880 # warn about raw binaries this big |
| 31 | ``` |
| 32 | |
| 33 | - If you commit a binary larger than `lfs_warn_bytes` without LFS, Vole accepts |
| 34 | the push but warns you and shows the `git lfs track` command. |
| 35 | - If you push a pointer whose file was never uploaded, Vole refuses the push, |
| 36 | because nobody would be able to check out that commit. |
| 37 | - Set `lfs_warn_bytes = 0` to turn the warning off. |
| 38 | |
| 39 | ## Cleaning up |
| 40 | |
| 41 | ```sh |
| 42 | vole admin gc --dry-run # show what is unused |
| 43 | vole admin gc # remove it |
| 44 | ``` |
| 45 | |
| 46 | `vole admin gc` keeps files that are still reachable from a repository, an archived CI |
| 47 | log, or a published build artifact. It also repairs each repository's links into |
| 48 | the shared store. Files newer than `--grace` (one hour by default) are kept, |
| 49 | because an upload that has not been pushed yet is not garbage. |
| 50 | |
| 51 | See [Operations](operations.md#clean-up-stored-files) for recovery and scheduling |
| 52 | notes. |
| 53 | |
| 54 | ## Locking files |
| 55 | |
| 56 | Some files cannot be merged by Git: art, audio, models, levels. You can reserve |
| 57 | one before editing it. Locking uses the same SSH connection as everything else. |
| 58 | |
| 59 | ```sh |
| 60 | git lfs lock art/hero.psd # nobody else's push can change this path |
| 61 | git lfs unlock art/hero.psd # release it |
| 62 | git lfs locks # show who holds what |
| 63 | ``` |
| 64 | |
| 65 | While a file is locked, Vole refuses any push that changes it. The server enforces |
| 66 | this, so it works even for a plain `git push` without a client-side hook. |
| 67 | |
| 68 | An admin can push past a lock. That override is recorded in `data/audit.log`; |
| 69 | otherwise a lock held by someone who has left would block the file forever. The |
| 70 | `/<repo>/locks` page shows current locks. |
| 71 | |
| 72 | Locks are not part of a clone. They live beside the account list in |
| 73 | `data/users.db`, because they are temporary state and should not come back from |
| 74 | history. |
| 75 |