Blob


1 I've just finished to configure gitolite and cgit to manage some git
2 repos of mine (and friends), so I'm posting here the setup before
3 forgetting the details.
5 The final result is a git server with both a web view, HTTP clone and
6 ssh for you and your users.
8 It requires more work than, say, gitea or gitlab, and has a few
9 moving parts. Nevertheless, it's a modular solution (you can replace
10 cgit with gitweb for instance) and it does not have obnoxious web guis
11 to manage things. The whole gitolite config is itself a git
12 repository, so you can use the tools you're familiar with (a bit of
13 ssh, git and your preferred `$EDITOR`) to build and maintain your own
14 git server.
16 ## gitolite
18 Install gitolite, it's easy. Follow the [installation
19 guide](https://gitolite.com/gitolite/quick_install#distro-package-install).
20 I've done that on a new user called "git". This will create two repos
21 in `~git/repositories`: `gitolite-admin` and `testing`. With the
22 default configuration testing will be read-write for all users (in the
23 gitolite sense).
25 You should import your own ssh public key. Try to clone the
26 `gitolite-admin` repo with `git clone
27 git@your.own.host:gitolite-admin` to test the setup and, eventually,
28 add more users and repos.
30 ## cgit
32 I'm using nginx plus fcgiwrap on a FreeBSD system, but other options
33 are available. (For instance, if you're using OpenBSD than you have
34 httpd and slowcgi already in base.)
36 For reference, my configuration file is `/usr/local/etc/cgit-op.conf`
37 and contains:
38 ```conf
39 css=/mine.css
40 logo=/logo.png
42 head-include=/usr/local/lib/cgit/theme/head.html
44 enable-http-clone=1
45 enable-index-links=1
46 remove-suffix=1
47 enable-commit-graph=1
48 enable-log-filecount=1
49 enable-git-config=1
51 source-filter=/usr/local/lib/cgit/filters/syntax-high.py
52 about-filter=/usr/local/lib/cgit/filters/about-formatting.sh
54 virtual-root=/
55 enable-index-links=1
56 enable-index-owner=0
57 snapshots=tar.gz tar.bz2
58 root-title=Stuff
59 root-desc=some git repos of mine
60 local-time=1
62 # path to the root about file
63 #root-readme=/usr/local/lib/cgit/theme/about.html
65 # search for these files in the root fo the default branch
66 readme=:README.md
67 readme=:readme.md
68 readme=:README.mkd
69 readme=:readme.mkd
70 readme=:README.rst
71 readme=:readme.rst
72 readme=:README.html
73 readme=:readme.html
74 readme=:README.htm
75 readme=:readme.htm
76 readme=:README.txt
77 readme=:readme.txt
78 readme=:README
79 readme=:readme
80 readme=:INSTALL.md
81 readme=:install.md
82 readme=:INSTALL.mkd
83 readme=:install.mkd
84 readme=:INSTALL.rst
85 readme=:install.rst
86 readme=:INSTALL.html
87 readme=:install.html
88 readme=:INSTALL.htm
89 readme=:install.htm
90 readme=:INSTALL.txt
91 readme=:install.txt
92 readme=:INSTALL
93 readme=:install
95 scan-path=/home/git/repositories
96 ```
98 The important bits of all of these are only:
99 ```conf
100 enable-git-config=1
101 ```
102 and
103 ```conf
104 scan-path=/home/git/repositories
105 ```
107 The first let us configure per-repo cgit options via the standard git
108 config file, while the second lets cgit discovers the repos by
109 searching in that path.
111 If you're curious, I used `head-include` to add some `<meta>` tags and
112 modified the default CSS to render the pages *decently* on mobile
113 screens. More work is needed.
115 ### Note about permissions
117 You are probably running cgit with the `www` user and gitolite with
118 the `git` user so you have a permission problem. While you can do
119 fancy stuff with `mount_nullfs`/`mount --bind` and whatnot or by
120 changing the default path for the repositories, I didn't want to.
122 I'm still not sure if this is the best way to handle things, but I
123 made fcgiwrap use the `git` user with
124 ```conf
125 fcgiwrap_user="git"
126 ```
127 in `/etc/rc.conf` plus a manual `chown(8)` on the socket. Now cgit
128 and gitolite are run by the same user. Problem solved.
130 ## hide some repositories!
132 This was the basic setup to have cgit display the repositories managed
133 by gitolite, as well as having both public HTTP and authenticated ssh
134 clone. Pretty neat.
136 But, you have no way (still) to hide some repositories. For instance,
137 the `gitolite-admin` repositorie is public readable (not writable).
138 It may be fine for you, but I wanted a way to have *private*
139 repositories, while still having the repos managed by gitolite.
141 If you set `enable-git-config` in cgit configuration file, now you can
142 control some cgit per-repo options via
143 `~git/repositories/$REPO/config`. You can create a section that looks
144 like this:
145 ```conf
146 [cgit]
147 ignore = 1
148 ```
149 to make cgit ignore that repo. Check the documentation of cgit for
150 the list of parameters you can set.
152 But it's tedious and needs manual work per-repo. That's something
153 that needs to be automatized.
155 Fortunately, gitolite lets us set git configurations via the
156 `gitolite.conf` file. You first need to set `GIT_CONFIG_KEYS` to
157 `'.*'` in `~git/.gitolite.rc`. (`.*` is the broader, probably
158 `cgit.*` is enough, haven't tested tho).
160 Now, in your `gitolite.conf` you can
161 ```conf
162 repo gitolite-admin
163 config cgit.ignore=1
164 ```
165 and BOOM, it's hidden and unreachable via cgit (both via web and http
166 clone).
168 But (there are too many 'but' in this section, hu?) we can do even
169 better:
170 ```conf
171 @hiddenrepos = gitolite-admin
172 @hiddenrepos = private-stuff
173 @hiddenrepos = next-gen-revolutionary-stuff
175 repo @hiddenrepos
176 config cgit.ignore=1
177 ```
178 to bulk-hide repositories.
180 Neat.