Repositories / gitweb2.git
gitweb2.git
Clone (read-only): git clone http://git.guha-anderson.com/git/gitweb2.git
@@ -34,6 +34,12 @@ Options: dune exec gitweb2 -- ~/repos --host 127.0.0.1 --port 8080 --pygments "uv run --with pygments pygmentize" ``` +Use `--public-url` when the public address differs from the bind address (e.g. behind a port-forward or reverse proxy). It sets the base used in the displayed clone URL and overrides the request `Host` header: + +```sh +dune exec gitweb2 -- ~/repos --host 0.0.0.0 --port 8002 --public-url https://git.example.com +``` + Press `Ctrl+C` to stop the server. ## systemd (homebox) @@ -66,3 +72,24 @@ binary must be on `PATH`. Push is not supported. ```sh git clone http://<host>:<port>/git/<repo> ``` + +## Hooks: do you need `post-update`? + +No. Smart HTTP via `git http-backend` reads refs and packs from the live +repository on every request, so the `info/refs` and `objects/info/packs` +files are not consulted and there is nothing to refresh after a push. +The traditional `post-update` hook is only needed for **dumb** HTTP, where +the client fetches static files out of `.git/`. + +If you ever do want to expose a bare repo over dumb HTTP (or another tool +expects up-to-date `info/` files), enable the sample hook git ships: + +```sh +cd /path/to/repo.git +mv hooks/post-update.sample hooks/post-update +chmod +x hooks/post-update +git update-server-info # one-off, to seed the files +``` + +That hook just runs `git update-server-info` after each push. With gitweb2's +smart HTTP route this is unnecessary.
@@ -26,4 +26,9 @@ For a repository with key `<repo>`, the URLs on this host are: - HTML viewer: `http://homebox:8002/repo/<repo>` - Read-only clone: `git clone http://homebox:8002/git/<repo>` +If the service is reached publicly through a port-forward or reverse proxy at +a different host or scheme, append `--public-url <url>` to the `ExecStart` +line so the clone command shown on each repo page reflects the public URL +(e.g. `--public-url https://git.example.com`). + Without [lingering](https://www.freedesktop.org/software/systemd/man/latest/loginctl.html), the user service stops when you log out (`loginctl enable-linger "$USER"` to keep it).
@@ -15,6 +15,7 @@ type config = { host : string; port : int; pygments_command : string; + public_url : string option; } type repo_info = { @@ -562,8 +563,17 @@ let start (config : config) : unit = let query = Uri.verbatim_query uri |> Option.value ~default:"" in let req_headers = Cohttp.Request.headers request in let header value = Cohttp.Header.get req_headers value |> Option.value ~default:"" in - let host = header "host" in - let clone_base = if host = "" then None else Some ("http://" ^ host) in + let strip_trailing_slash s = + let n = String.length s in + if n > 0 && s.[n - 1] = '/' then String.sub s 0 (n - 1) else s + in + let clone_base = + match config.public_url with + | Some url -> Some (strip_trailing_slash url) + | None -> + let host = header "host" in + if host = "" then None else Some ("http://" ^ host) + in let response = if String.starts_with ~prefix:"/git/" path then let request_body = @@ -595,24 +605,27 @@ let start (config : config) : unit = Cohttp_eio.Server.run socket server ~on_error:(fun exn -> Logs.err (fun m -> m "%s" (Printexc.to_string exn))) -let usage : string = "usage: gitweb2 <repo-root> [--host 127.0.0.1] [--port 8080] [--pygments pygmentize]" +let usage : string = + "usage: gitweb2 <repo-root> [--host 127.0.0.1] [--port 8080] [--pygments pygmentize] [--public-url \ + https://git.example.com]" let parse_args (argv : string array) : (config, string) result = let args = Array.to_list argv |> List.tl in match args with | [] | ("-h" | "--help") :: _ -> Error usage | root :: rest -> - let rec loop host port pygments = function - | [] -> Ok { root; host; port; pygments_command = pygments } - | "--host" :: value :: tail -> loop value port pygments tail + let rec loop host port pygments public_url = function + | [] -> Ok { root; host; port; pygments_command = pygments; public_url } + | "--host" :: value :: tail -> loop value port pygments public_url tail | "--port" :: value :: tail -> ( match int_of_string_opt value with - | Some port -> loop host port pygments tail + | Some port -> loop host port pygments public_url tail | None -> Error "missing or invalid --port value") - | "--pygments" :: value :: tail -> loop host port value tail + | "--pygments" :: value :: tail -> loop host port value public_url tail + | "--public-url" :: value :: tail -> loop host port pygments (Some value) tail | flag :: _ -> Error ("unknown argument " ^ flag) in - loop default_host default_port default_pygments_command rest + loop default_host default_port default_pygments_command None rest let run (argv : string array) : unit = match parse_args argv with
@@ -9,6 +9,7 @@ type config = { host : string; port : int; pygments_command : string; + public_url : string option; } val default_host : string