|
| 1 | +# git-remote-sqlite |
| 2 | + |
| 3 | +- [Latest release](https://github.com/chrislloyd/git-remote-sqlite/releases/latest) |
| 4 | +- [Latest changes](https://github.com/chrislloyd/git-remote-sqlite/commits/main) |
| 5 | +- [Source code](https://github.com/chrislloyd/git-remote-sqlite) |
| 6 | + |
| 7 | +--- |
| 8 | + |
| 9 | +**git-remote-sqlite(1)** is a [Git protocol helper](https://git-scm.com/docs/gitremote-helpers) that helps you store a Git repository in a [SQLite](https://www.sqlite.org) database. Why would you want to do this? |
| 10 | + |
| 11 | +1. **Simple Git hosting**. Hosting git repositories typically involves using a third-party forge like GitHub or Sourcehut. These provide value by automating hosting NFS mounts and providing a web interface for collaboration. |
| 12 | +2. **Self-contained application bundle**. It serves as both a Git repository hosting alternative and enables Lisp/Smalltalk-style development images where code and its runtime state coexist. |
| 13 | +3. **(Advanced) More control over automation**. Leveraging Git hooks lets you transactionally automate tasks like migrations. |
| 14 | +4. **(Advanced) Build your own workflows**. An application can be built that is self-updating - you don't need to rely on pull-requests or emails etc. to update your application, you can easily build updating itself into your application. |
| 15 | + |
| 16 | +## Installation |
| 17 | + |
| 18 | +### Prerequisites |
| 19 | + |
| 20 | +- Git (version 2.25+) |
| 21 | +- SQLite (version 3.30+) |
| 22 | +- Zig (version 0.14.0) - only needed if building from source |
| 23 | + |
| 24 | +### Using Pre-built Binaries (Recommended) |
| 25 | + |
| 26 | +1. Download the latest release for your platform: |
| 27 | + |
| 28 | + ```bash |
| 29 | + # macOS |
| 30 | + curl -L https://github.com/chrislloyd/git-remote-sqlite/releases/latest/download/git-remote-sqlite-macos -o git-remote-sqlite |
| 31 | + |
| 32 | + # Linux |
| 33 | + curl -L https://github.com/chrislloyd/git-remote-sqlite/releases/latest/download/git-remote-sqlite-linux -o git-remote-sqlite |
| 34 | + ``` |
| 35 | + |
| 36 | +2. Make the binary executable: |
| 37 | + |
| 38 | + ```bash |
| 39 | + chmod +x git-remote-sqlite |
| 40 | + ``` |
| 41 | + |
| 42 | +3. Move the binary to your `$PATH`: |
| 43 | + |
| 44 | + ```bash |
| 45 | + sudo mv git-remote-sqlite /usr/local/bin/ |
| 46 | + ``` |
| 47 | + |
| 48 | +4. The installation is complete. The binary functions as both a standalone command and as a Git remote helper. |
| 49 | + |
| 50 | +### Building from Source |
| 51 | + |
| 52 | +1. Clone the repository: |
| 53 | + |
| 54 | + ```bash |
| 55 | + git clone https://github.com/chrislloyd/git-remote-sqlite.git |
| 56 | + cd git-remote-sqlite |
| 57 | + ``` |
| 58 | + |
| 59 | +2. Build the binary using Zig: |
| 60 | + |
| 61 | + ```bash |
| 62 | + zig build |
| 63 | + ``` |
| 64 | + |
| 65 | +3. Copy the binary to your path: |
| 66 | + |
| 67 | + ```bash |
| 68 | + sudo cp zig-out/bin/git-remote-sqlite /usr/local/bin/ |
| 69 | + ``` |
| 70 | + |
| 71 | +4. The installation is complete. The binary functions as both a standalone command and as a Git remote helper. |
| 72 | + |
| 73 | +## Basic Usage |
| 74 | + |
| 75 | +### 1. Configure Repository Settings |
| 76 | + |
| 77 | +You can configure server-side git settings stored in the SQLite database: |
| 78 | + |
| 79 | +```bash |
| 80 | +# Set configuration variables (similar to editing server-side git config) |
| 81 | +git-remote-sqlite config myapp.db receive.denyDeletes true |
| 82 | +git-remote-sqlite config myapp.db receive.denyNonFastForwards true |
| 83 | + |
| 84 | +# List all configured settings |
| 85 | +git-remote-sqlite config myapp.db --list |
| 86 | + |
| 87 | +# Get a specific setting value |
| 88 | +git-remote-sqlite config myapp.db --get receive.denyDeletes |
| 89 | + |
| 90 | +# Remove a setting |
| 91 | +git-remote-sqlite config myapp.db --unset receive.denyDeletes |
| 92 | +``` |
| 93 | + |
| 94 | +These settings are stored in the `git_config` table and affect how git operations are processed when interacting with the SQLite repository. |
| 95 | + |
| 96 | +### 2. Push Code to the Database (Coming Soon) |
| 97 | + |
| 98 | +Push your code to the SQLite database: |
| 99 | + |
| 100 | +```bash |
| 101 | +git push sqlite://myapp.db main |
| 102 | +``` |
| 103 | + |
| 104 | +### 3. Use as a Git Remote (Coming Soon) |
| 105 | + |
| 106 | +Add the database as a git remote: |
| 107 | + |
| 108 | +```bash |
| 109 | +# In your existing git repository |
| 110 | +git remote add origin sqlite://myapp.db |
| 111 | + |
| 112 | +# Note: 'origin' is just a name for the remote - you can use any name you prefer |
| 113 | +``` |
| 114 | + |
| 115 | +### 4. Checkout Code from the Database (Coming Soon) |
| 116 | + |
| 117 | +Checkout a specific commit from the database: |
| 118 | + |
| 119 | +```bash |
| 120 | +git checkout sqlite://myapp.db main |
| 121 | +``` |
| 122 | + |
| 123 | +This will extract the specified commit to the current directory. |
| 124 | + |
| 125 | +## Development Status |
| 126 | + |
| 127 | +Currently implemented: |
| 128 | +- [x] Configuration management (set, get, list, unset) |
| 129 | +- [ ] Git remote helper protocol (push/pull functionality) |
| 130 | +- [ ] Git hooks |
| 131 | +- [ ] Pack file management (tables defined but not yet implemented) |
| 132 | + |
| 133 | +## Database Schema |
| 134 | + |
| 135 | +**git_objects**: Stores git objects (blobs, trees, commits, tags) |
| 136 | + |
| 137 | +| Column | Type | Constraints | Description | |
| 138 | +|--|--|--|--| |
| 139 | +| `sha` | TEXT | PRIMARY KEY, CHECK(length(sha) = 40 AND sha GLOB '[0-9a-f]*') | Object SHA hash | |
| 140 | +| `type` | TEXT | NOT NULL, CHECK(type IN ('blob', 'tree', 'commit', 'tag')) | Object type (blob, tree, commit, tag) | |
| 141 | +| `data` | BLOB | NOT NULL | Object content | |
| 142 | + |
| 143 | +*Indexes:* |
| 144 | +- `CREATE INDEX idx_git_objects_type ON git_objects(type);` - For efficient queries by object type |
| 145 | + |
| 146 | +**git_refs**: Stores git references |
| 147 | + |
| 148 | +| Column | Type | Constraints | Description | |
| 149 | +|--|--|--|--| |
| 150 | +| `name` | TEXT | PRIMARY KEY, CHECK(name GLOB 'refs/*') | Reference name (e.g., 'refs/heads/main') | |
| 151 | +| `sha` | TEXT | NOT NULL, FOREIGN KEY REFERENCES git_objects(sha) | Commit SHA the ref points to | |
| 152 | +| `type` | TEXT | NOT NULL, CHECK(type IN ('branch', 'tag', 'remote')) | Reference type (branch, tag, remote) | |
| 153 | + |
| 154 | +*Indexes:* |
| 155 | +- `CREATE INDEX idx_git_refs_sha ON git_refs(sha);` - For finding all refs pointing to a specific commit |
| 156 | + |
| 157 | +**git_symbolic_refs**: Stores symbolic references (like HEAD) |
| 158 | + |
| 159 | +| Column | Type | Constraints | Description | |
| 160 | +|--|--|--|--| |
| 161 | +| `name` | TEXT | PRIMARY KEY | Symbolic reference name (e.g., 'HEAD') | |
| 162 | +| `target` | TEXT | NOT NULL, FOREIGN KEY REFERENCES git_refs(name) | Target reference path | |
| 163 | + |
| 164 | +**git_packs**: Stores git pack files *(pending implementation)* |
| 165 | + |
| 166 | +| Column | Type | Constraints | Description | |
| 167 | +|--|--|--|--| |
| 168 | +| `id` | INTEGER | PRIMARY KEY | Unique pack identifier | |
| 169 | +| `name` | TEXT | NOT NULL, UNIQUE | Pack name/identifier | |
| 170 | +| `data` | BLOB | NOT NULL | Pack file binary data | |
| 171 | +| `index_data` | BLOB | NOT NULL | Pack index binary data | |
| 172 | + |
| 173 | +*Indexes:* |
| 174 | +- `CREATE INDEX idx_git_packs_name ON git_packs(name);` - For efficient lookups by pack name |
| 175 | + |
| 176 | +**git_pack_entries**: Maps objects to packs for faster lookups *(pending implementation)* |
| 177 | + |
| 178 | +| Column | Type | Constraints | Description | |
| 179 | +|--|--|--|--| |
| 180 | +| `pack_id` | INTEGER | NOT NULL, FOREIGN KEY REFERENCES git_packs(id) | Reference to the pack | |
| 181 | +| `sha` | TEXT | NOT NULL, FOREIGN KEY REFERENCES git_objects(sha) | Object SHA contained in the pack | |
| 182 | +| `offset` | INTEGER | NOT NULL | Offset position within the pack | |
| 183 | +| PRIMARY KEY | | (pack_id, sha) | Composite primary key | |
| 184 | + |
| 185 | +*Indexes:* |
| 186 | +- `CREATE INDEX idx_git_pack_entries_sha ON git_pack_entries(sha);` - For finding which pack contains a specific object |
| 187 | + |
| 188 | + |
| 189 | +**git_config**: Stores git configuration settings |
| 190 | + |
| 191 | +| Column | Type | Constraints | Description | |
| 192 | +|--|--|--|--| |
| 193 | +| `key` | TEXT | PRIMARY KEY | Configuration key | |
| 194 | +| `value` | TEXT | NOT NULL | Configuration value | |
| 195 | + |
| 196 | +## Contributing |
| 197 | + |
| 198 | +Contributions are welcome! Please feel free to submit a Pull Request. |
0 commit comments