Updated README and changed it to markdown
1 files changed, 274 insertions(+), 0 deletions(-) | |||
---|---|---|---|
A | README.md | +274 | -0 |
1@@ -0,0 +1,274 @@
2+# stagit
3+
4+static git page generator.
5+
6+It generates static HTML pages for a git repository.
7+
8+## Changes
9+This is my personal fork of stagit.
10+It has been modified to fit my needs and some refs points
11+to cli apps on my web-server.
12+
13+* Title of files while viewing is now a link to download the file
14+* The index page now links to the repository directory
15+* md4c has been added to parse markdown files
16+* Added classes and ids to some html tags to easier style them
17+* Changed style.css to a modern looking nord theme as well as markdown styling
18+
19+The link to download the file points to `/raw/?repository=&file=`
20+where file is the full path to the file relative to the repository.
21+It is also possible to specify which branch to fetch the file from.
22+
23+Make necessary changes to the web-server to serve the file
24+
25+To view a file in a bare repository:
26+
27+ $cd path/to/repo
28+ $git show HEAD:path/to/file
29+
30+Simple python cgi to serve the file:
31+
32+```
33+#!/bin/python3
34+
35+import cgi
36+import subprocess
37+import mimetypes
38+import sys
39+
40+def getFile(repo, filepath, branch):
41+ gitcmd = subprocess.run(['git', 'show', f'{branch}:{filepath}'],
42+ cwd=f'/home/pi/repositories/{repo}',
43+ capture_output=True)
44+ return gitcmd.stdout
45+
46+
47+def guessType(filepath, extensions_map):
48+ ext = '.' + filepath.split('.')[-1]
49+ if ext in extensions_map:
50+ return extensions_map[ext]
51+ ext = ext.lower()
52+ if ext in extensions_map:
53+ return extensions_map[ext]
54+ return extensions_map['']
55+
56+
57+if not mimetypes.inited:
58+ mimetypes.init()
59+extensions_map = mimetypes.types_map.copy()
60+extensions_map[''] = 'application/octet-stream'
61+
62+form = cgi.FieldStorage()
63+repo = form.getvalue('repository')
64+filepath = form.getvalue('file')
65+if (form.getvalue('branch')):
66+ branch = form.getvalue('branch')
67+else:
68+ branch = 'HEAD'
69+
70+ctype = guessType(filepath, extensions_map)
71+response = getFile(repo, filepath, branch)
72+
73+if response:
74+ print(f"Content-Type: {ctype}")
75+ print(f"Conent-Length: {str(len(response))}")
76+ print()
77+ sys.stdout.flush()
78+ sys.stdout.buffer.write(response)
79+else:
80+ print("Content-Type: text/plain")
81+ print()
82+ print("404: File not found")
83+
84+```
85+
86+The index page linking to the directory will not change the default
87+behavior of stagit if the html files have been created with the [provided
88+shell script](example_create.sh.html), since log.html is symlinked
89+to index.html.
90+
91+This change was made so that the web-server could check if the
92+request is for a directory. If it is check if there is a file called
93+README.md.html in the sub-directory file, if it exists serve that
94+file instead of log.html.
95+
96+Lighttpd conf to implement this:
97+
98+ url.redirect = ( "^\/stagit\/([a-zA-Z0-9-_.,]\/$" => "/stagit/$1/file/README.md" )
99+ url.rewrite-if-not-file = ( "^\/stagit/([a-zA-Z0-9-_,.]*)\/file\/README.md.html$" => /redirect/$1" )
100+ url.redirect += ( "^\/redirect/\([a-zA-Z0-9-_,.]*)" => "/stagit/$1/log.html" )
101+
102+### md4c
103+md4c is used to parse and convert markdown documents into html. If a file
104+ends with `.md` it will be parsed by md4c rather than the regular way
105+stagit parses plain text files.
106+
107+https://github.com/mity/md4c
108+
109+## Usage
110+
111+Make files per repository:
112+
113+ $ mkdir -p htmldir && cd htmldir
114+ $ stagit path-to-repo
115+
116+Make index file for repositories:
117+
118+ $ stagit-index repodir1 repodir2 repodir3 > index.html
119+
120+
121+## Build and install
122+
123+ $ make
124+ # make install
125+
126+
127+## Dependencies
128+
129+- C compiler (C99).
130+- libc (tested with OpenBSD, FreeBSD, NetBSD, Linux: glibc and musl).
131+- libgit2 (v0.22+).
132+- POSIX make (optional).
133+- md4c (markdown parsing to html)
134+
135+## Documentation
136+
137+See man pages: stagit(1) and stagit-index(1).
138+
139+
140+### Building a static binary
141+
142+It may be useful to build static binaries, for example to run in a chroot.
143+
144+It can be done like this at the time of writing (v0.24):
145+
146+ cd libgit2-src
147+
148+ # change the options in the CMake file: CMakeLists.txt
149+ BUILD_SHARED_LIBS to OFF (static)
150+ CURL to OFF (not needed)
151+ USE_SSH OFF (not needed)
152+ THREADSAFE OFF (not needed)
153+ USE_OPENSSL OFF (not needed, use builtin)
154+
155+ mkdir -p build && cd build
156+ cmake ../
157+ make
158+ make install
159+
160+
161+### Extract owner field from git config
162+
163+A way to extract the gitweb owner for example in the format:
164+
165+ [gitweb]
166+ owner = Name here
167+
168+Script:
169+
170+ #!/bin/sh
171+ awk '/^[ ]*owner[ ]=/ {
172+ sub(/^[^=]*=[ ]*/, "");
173+ print $0;
174+ }'
175+
176+
177+### Set clone url for a directory of repos
178+
179+ #!/bin/sh
180+ cd "$dir"
181+ for i in *; do
182+ test -d "$i" && echo "git://git.codemadness.org/$i" > "$i/url"
183+ done
184+
185+
186+### Update files on git push
187+
188+Using a post-receive hook the static files can be automatically updated.
189+Keep in mind git push -f can change the history and the commits may need
190+to be recreated. This is because stagit checks if a commit file already
191+exists. It also has a cache (-c) option which can conflict with the new
192+history. See stagit(1).
193+
194+git post-receive hook (repo/.git/hooks/post-receive):
195+
196+ #!/bin/sh
197+ # detect git push -f
198+ force=0
199+ while read -r old new ref; do
200+ hasrevs=$(git rev-list "$old" "^$new" | sed 1q)
201+ if test -n "$hasrevs"; then
202+ force=1
203+ break
204+ fi
205+ done
206+
207+ # remove commits and .cache on git push -f
208+ #if test "$force" = "1"; then
209+ # ...
210+ #fi
211+
212+ # see example_create.sh for normal creation of the files.
213+
214+
215+### Create .tar.gz archives by tag
216+
217+ #!/bin/sh
218+ name="stagit"
219+ mkdir -p archives
220+ git tag -l | while read -r t; do
221+ f="archives/${name}-$(echo "${t}" | tr '/' '_').tar.gz"
222+ test -f "${f}" && continue
223+ git archive \
224+ --format tar.gz \
225+ --prefix "${t}/" \
226+ -o "${f}" \
227+ -- \
228+ "${t}"
229+ done
230+
231+
232+## Features
233+
234+- Log of all commits from HEAD.
235+- Log and diffstat per commit.
236+- Show file tree with linkable line numbers.
237+- Show references: local branches and tags.
238+- Detect README and LICENSE file from HEAD and link it as a webpage.
239+- Detect submodules (.gitmodules file) from HEAD and link it as a webpage.
240+- Atom feed log (atom.xml).
241+- Make index page for multiple repositories with stagit-index.
242+- After generating the pages (relatively slow) serving the files is very fast,
243+ simple and requires little resources (because the content is static), only
244+ a HTTP file server is required.
245+- Usable with text-browsers such as dillo, links, lynx and w3m.
246+
247+
248+## Cons
249+
250+- Not suitable for large repositories (2000+ commits), because diffstats are
251+an expensive operation, the cache (-c flag) is a workaround for this in
252+some cases.
253+- Not suitable for large repositories with many files, because all files
254+are written for each execution of stagit. This is because stagit shows the
255+lines of textfiles and there is no "cache" for file metadata
256+(this would add more complexity to the code).
257+- Not suitable for repositories with many branches, a quite linear
258+history is assumed (from HEAD).
259+
260+ In these cases it is better to just use cgit or possibly change stagit to
261+ run as a CGI program.
262+
263+- Relatively slow to run the first time (about 3 seconds for sbase,
264+1500+ commits), incremental updates are faster.
265+- Does not support some of the dynamic features cgit has, like:
266+ - Snapshot tarballs per commit.
267+ - File tree per commit.
268+ - History log of branches diverged from HEAD.
269+ - Stats (git shortlog -s).
270+
271+ This is by design, just use git locally.
272+- After adding md4c for markdown rendering the stagit-index links are pointed
273+ to /file/README.md.html instead of log.html this in turn requires every repo
274+ to contain a README file in md. (Not really an issue for my personal use case).
275+