all repos

mugit @ v0.3.0

🐮 git server that your cow will love

mugit/README.md (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
setup per repo hooks, 22 days ago
1
# mugit
2
3
A lightweight, self-hosted Git server that your cow will love.
4
5
[See it in action!](https://git.olexsmir.xyz)
6
7
## Features
8
- Web interface — browse repositories, view commits, files, and diffs (no javascript required).
9
- Git Smart HTTP — clone over HTTPS (use SSH for pushing).
10
- Git over SSH — push and clone repos over SSH.
11
- Mirroring — automatically mirror repos from other forges (supports GitHub authentication).
12
- Private repositories — repos accessible only via SSH
13
- CLI — command-line for managing your repositories
14
15
## Quick install & deploy
16
17
```sh
18
# get binary
19
git clone https://git.olexsmir.xyz/mugit.git
20
cd mugit
21
go build
22
# or
23
go install github.com/olexsmir/mugit@latest
24
25
26
# start server
27
mugit serve
28
```
29
30
<details>
31
<summary>Deploy guide</summary>
32
33
  If you're on nixos feel free to use mugit's flake. See [example config](https://git.olexsmir.xyz/dotfiles/blob/master/nix/modules/services/mugit.nix) for a full reference.
34
35
  1. Get a mugit binary.
36
37
  Download it from [github releases](https://github.com/olexsmir/mugit/releases) or build it from source:
38
  ```bash
39
  git clone https://git.olexsmir.xyz/mugit.git
40
  cd mugit
41
  go build -o /usr/local/bin/mugit
42
  ```
43
44
  2. Create a user for mugit, and repo for your repo.
45
  ```bash
46
  useradd -r -d /var/lib/mugit -m -s /bin/sh mugit
47
  mkdir -p /var/lib/mugit
48
  ```
49
50
  3. Configure
51
  ```yaml
52
  # file: /var/lib/mugit/config.yaml
53
  meta:
54
    host: git.example.com
55
  repo:
56
    dir: /var/lib/mugit
57
  ```
58
59
  4. Systemd service
60
  ```bash
61
  cp mugit/mugit.service /etc/systemd/system/mugit.service
62
  systemctl enable --now mugit
63
  ```
64
65
  5. SSH server integration
66
67
  mugit integrates with the system's OpenSSH via `AuthorizedKeysCommand`. Add this to `/etc/ssh/sshd_config`:
68
  ```
69
  Match User mugit
70
    AuthorizedKeysCommand /usr/local/bin/mugit shell keys %f
71
    AuthorizedKeysCommandUser mugit
72
  ```
73
74
  Restart SSH:
75
  ```bash
76
  systemctl restart sshd
77
  ```
78
79
  5. Point reverse proxy to mugit, by default mugit runs on 8080 port.
80
</details>
81
82
83
## Configuration
84
85
mugit uses YAML for configuration. By default the server looks for a configuration file in this order (override with `-c` / `--config`):
86
1. `./config.yaml`
87
2. `/etc/mugit.yaml`
88
3. `/var/lib/mugit/config.yaml`
89
90
91
Durations follow Go's duration syntax (examples: `1h`, `30m`, `5s`). See: [https://pkg.go.dev/time#ParseDuration]
92
93
Minimal configuration example:
94
95
```yaml
96
meta:
97
  host: git.olexsmir.xyz
98
99
repo:
100
  dir: /var/lib/mugit
101
```
102
103
Full example:
104
105
```yaml
106
server:
107
  host: 0.0.0.0 # bind address (0.0.0.0 = all interfaces)
108
  port: 5555    # HTTP port (defaults to 8080 when omitted)
109
  log_file: /var/lib/mugit/mugit.log # where slog output is written (default: <repo.dir>/mugit.log)
110
111
meta:
112
  title: "My Git Server"    # site title shown on index page
113
  description: "A place for my projects"
114
  host: git.example.com     # used for clone URLs and go-import meta tag
115
  modt: "Welcome to my git server!" # message shown on SSH clone/push (empty = disabled)
116
117
repo:
118
  dir: /var/lib/mugit   # directory with repositories
119
  # Default README filenames (applied when omitted):
120
  readmes:
121
    - README.md
122
    - readme.md
123
    - README.html
124
    - readme.html
125
    - README.txt
126
    - readme.txt
127
    - readme
128
129
# ssh: push/clone over SSH
130
ssh:
131
  enable: true
132
  user: "git" # user as which the app operates (default "git")
133
  # Only these public keys can access private repos and push to others.
134
  keys:
135
    - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA......
136
    - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA......
137
138
# mirror: automatic mirrors of external repositories
139
mirror:
140
  enable: true
141
  interval: 1h  # sync frequency
142
  # Tokens can be provided directly, or read from environment/file:
143
  # - literal: "ghp_xxxxxxxxxxxx"
144
  # - from env: "$env:GITHUB_TOKEN" (will read $GITHUB_TOKEN)
145
  # - from file: "$file:/abs/path/to/token.txt"
146
  github_token: "$env:GITHUB_TOKEN"
147
148
cache:
149
  home_page: 5m   # cache index/home page
150
  readme: 1m      # cache rendered README per repo
151
  diff: 15m       # cache computed diffs
152
```
153
154
## CLI
155
156
```sh
157
# start server
158
mugit serve
159
160
# create new public repository
161
mugit repo new myproject
162
163
# create new private repository
164
mugit repo new --private myproject
165
166
# create a mirror of an external repository
167
mugit repo new myproject --mirror https://codeberg.org/user/repo
168
mugit repo new myproject --private --mirror https://github.com/user/repo
169
mugit repo new myproject --description "My awesome project"
170
171
# toggle repository visibility
172
mugit repo private myproject
173
174
# show and set repository description
175
mugit repo description myproject
176
mugit repo description myproject "My awesome project"
177
178
# switch default branch
179
mugit repo set-default myproject main
180
181
# trigger mirror sync
182
mugit repo sync myproject
183
```
184
185
## Per-repo hooks
186
187
mugit creates these server-side hooks per repository: `pre-receive`, `update`, `post-receive`, `post-update`.
188
189
Each hook delegates to executable scripts in: `<repo>.git/hooks/<hook>.d/`
190
191
<details>
192
<summary>Example: golangci-lint as a pre-receive hook</summary>
193
```bash
194
# file: `<repo>.git/hooks/pre-receive.d/golangci-lint.sh`:
195
#!/bin/sh
196
set -eu
197
198
while read oldrev newrev refname; do
199
  tmpdir=$(mktemp -d)
200
  trap 'rm -rf "$tmpdir"' EXIT INT TERM
201
202
  git archive "$newrev" | tar -xC "$tmpdir"
203
204
  if ! (cd "$tmpdir" && golangci-lint run ./...); then
205
    echo "golangci-lint failed for $refname — push rejected" >&2
206
    exit 1
207
  fi
208
done
209
```
210
</details>
211
212
## License
213
214
mugit is licensed under the MIT License.