aboutsummaryrefslogtreecommitdiff
path: root/nix/per-host/git/git-shell-commands
diff options
context:
space:
mode:
Diffstat (limited to 'nix/per-host/git/git-shell-commands')
-rwxr-xr-xnix/per-host/git/git-shell-commands/create49
-rwxr-xr-xnix/per-host/git/git-shell-commands/desc25
-rwxr-xr-xnix/per-host/git/git-shell-commands/hide19
-rwxr-xr-xnix/per-host/git/git-shell-commands/manage81
-rwxr-xr-xnix/per-host/git/git-shell-commands/publish19
5 files changed, 193 insertions, 0 deletions
diff --git a/nix/per-host/git/git-shell-commands/create b/nix/per-host/git/git-shell-commands/create
new file mode 100755
index 0000000..459f428
--- /dev/null
+++ b/nix/per-host/git/git-shell-commands/create
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+# git-shell-commands(5) subcommand: create a new bare repo.
+# Prompts for each configurable setting: name (if not given as an
+# argument), description, owner and visibility. Pipe </dev/null to accept
+# the defaults (empty description, owner kdam0, private).
+# Run: ssh git@git.kumardamani.net create [name]
+
+name="${1:-}"
+
+if [ -z "$name" ]; then
+ printf 'repo name: '
+ read -r name
+fi
+case "$name" in
+ ""|*[!a-zA-Z0-9._-]*|*..*)
+ echo "error: invalid name '$name' (allowed: a-z 0-9 . _ -)" >&2
+ exit 1
+ ;;
+esac
+repo="/srv/git/$name.git"
+if [ -e "$repo" ]; then
+ echo "error: repo '$name' already exists" >&2
+ exit 1
+fi
+
+printf 'description (optional): '
+read -r desc
+
+printf 'owner [kdam0]: '
+read -r owner
+owner="${owner:-kdam0}"
+
+printf 'publish now? [y/N]: '
+read -r pub
+
+git init --bare --quiet "$repo"
+git -C "$repo" config gitweb.owner "$owner"
+[ -n "$desc" ] && printf '%s\n' "$desc" > "$repo/description"
+
+case "$pub" in
+ y|Y|yes)
+ touch "$repo/git-daemon-export-ok"
+ echo "created public repo '$name': https://git.kumardamani.net/$name"
+ ;;
+ *)
+ echo "created private repo '$name'"
+ echo "publish it with: ssh git@git.kumardamani.net publish $name"
+ ;;
+esac
diff --git a/nix/per-host/git/git-shell-commands/desc b/nix/per-host/git/git-shell-commands/desc
new file mode 100755
index 0000000..cd0e569
--- /dev/null
+++ b/nix/per-host/git/git-shell-commands/desc
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+# git-shell-commands(5) subcommand: set or show a repo's description as
+# displayed in cgit.
+# Run: ssh git@git.kumardamani.net desc <name> [description...]
+
+name="${1:-}"
+case "$name" in
+ ""|*[!a-zA-Z0-9._-]*|*..*)
+ echo "usage: desc <name> [description...]" >&2
+ exit 1
+ ;;
+esac
+repo="/srv/git/$name.git"
+if [ ! -d "$repo" ]; then
+ echo "error: no such repo '$name'" >&2
+ exit 1
+fi
+shift
+if [ $# -eq 0 ]; then
+ cat "$repo/description"
+ exit 0
+fi
+printf '%s\n' "$*" > "$repo/description"
+echo "description for '$name':"
+cat "$repo/description"
diff --git a/nix/per-host/git/git-shell-commands/hide b/nix/per-host/git/git-shell-commands/hide
new file mode 100755
index 0000000..4208e08
--- /dev/null
+++ b/nix/per-host/git/git-shell-commands/hide
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+# git-shell-commands(5) subcommand: make a repo private again by removing
+# the git-daemon-export-ok marker. SSH access is unaffected.
+# Run: ssh git@git.kumardamani.net hide <name>
+
+name="${1:-}"
+case "$name" in
+ ""|*[!a-zA-Z0-9._-]*|*..*)
+ echo "usage: hide <name>" >&2
+ exit 1
+ ;;
+esac
+repo="/srv/git/$name.git"
+if [ ! -d "$repo" ]; then
+ echo "error: no such repo '$name'" >&2
+ exit 1
+fi
+rm -f "$repo/git-daemon-export-ok"
+echo "hidden (private): '$name'"
diff --git a/nix/per-host/git/git-shell-commands/manage b/nix/per-host/git/git-shell-commands/manage
new file mode 100755
index 0000000..01fd52e
--- /dev/null
+++ b/nix/per-host/git/git-shell-commands/manage
@@ -0,0 +1,81 @@
+#!/usr/bin/env bash
+# git-shell-commands(5) subcommand: interactive repo manager.
+# Run: ssh -t git@git.kumardamani.net manage
+# Also symlinked as no-interactive-login, so a bare interactive ssh
+# (ssh -t git@git.kumardamani.net) lands here directly.
+
+cmds=/srv/git/git-shell-commands
+
+valid_name() {
+ case "$1" in
+ ""|*[!a-zA-Z0-9._-]*|*..*) return 1 ;;
+ *) return 0 ;;
+ esac
+}
+
+list_repos() {
+ printf '%-24s %-8s %s\n' REPO STATE DESCRIPTION
+ for repo in /srv/git/*.git; do
+ [ -d "$repo" ] || continue
+ name="${repo##*/}"
+ name="${name%.git}"
+ if [ -f "$repo/git-daemon-export-ok" ]; then
+ state=public
+ else
+ state=private
+ fi
+ desc="$(cat "$repo/description" 2>/dev/null)"
+ case "$desc" in Unnamed*) desc= ;; esac
+ printf '%-24s %-8s %s\n' "$name" "$state" "$desc"
+ done
+}
+
+ask_name() {
+ printf 'repo name: '
+ read -r name
+ if ! valid_name "$name"; then
+ echo "invalid name '$name' (allowed: a-z 0-9 . _ -)" >&2
+ return 1
+ fi
+}
+
+while true; do
+ echo
+ echo "== git repo manager =="
+ echo " l) list repos"
+ echo " c) create repo"
+ echo " p) publish repo"
+ echo " h) hide repo"
+ echo " d) set description"
+ echo " x) delete repo"
+ echo " q) quit"
+ printf '> '
+ read -r choice || break
+ case "$choice" in
+ l) list_repos ;;
+ c) "$cmds/create" ;; # create prompts for name + settings itself
+ p) ask_name && "$cmds/publish" "$name" ;;
+ h) ask_name && "$cmds/hide" "$name" ;;
+ d)
+ ask_name && {
+ printf 'description: '
+ read -r text
+ "$cmds/desc" "$name" "$text"
+ }
+ ;;
+ x)
+ ask_name && [ -d "/srv/git/$name.git" ] && {
+ printf 'type the repo name again to confirm DELETE: '
+ read -r confirm
+ if [ "$confirm" = "$name" ]; then
+ rm -rf "/srv/git/$name.git"
+ echo "deleted '$name'"
+ else
+ echo "aborted"
+ fi
+ }
+ ;;
+ q|quit|exit) break ;;
+ *) echo "unknown choice '$choice'" ;;
+ esac
+done
diff --git a/nix/per-host/git/git-shell-commands/publish b/nix/per-host/git/git-shell-commands/publish
new file mode 100755
index 0000000..54aff26
--- /dev/null
+++ b/nix/per-host/git/git-shell-commands/publish
@@ -0,0 +1,19 @@
+#!/usr/bin/env bash
+# git-shell-commands(5) subcommand: make a repo public (browsable in cgit
+# and cloneable over HTTP) by creating the git-daemon-export-ok marker.
+# Run: ssh git@git.kumardamani.net publish <name>
+
+name="${1:-}"
+case "$name" in
+ ""|*[!a-zA-Z0-9._-]*|*..*)
+ echo "usage: publish <name>" >&2
+ exit 1
+ ;;
+esac
+repo="/srv/git/$name.git"
+if [ ! -d "$repo" ]; then
+ echo "error: no such repo '$name'" >&2
+ exit 1
+fi
+touch "$repo/git-daemon-export-ok"
+echo "published: https://git.kumardamani.net/$name"