summaryrefslogtreecommitdiff
path: root/git-shell-commands
diff options
context:
space:
mode:
Diffstat (limited to 'git-shell-commands')
-rwxr-xr-xgit-shell-commands/create-mirror53
-rwxr-xr-xgit-shell-commands/create-repo59
2 files changed, 112 insertions, 0 deletions
diff --git a/git-shell-commands/create-mirror b/git-shell-commands/create-mirror
new file mode 100755
index 0000000..8d2129c
--- /dev/null
+++ b/git-shell-commands/create-mirror
@@ -0,0 +1,53 @@
+#!/bin/bash
+
+set -e
+
+if test "${#}" -ne 1; then
+ printf "%s\n" "usage: $(basename $0) https://url/repo"
+ exit 1
+fi
+
+REPO="${1}"
+REPO_NAME=$(basename "${REPO}")
+REPO_DIR="/srv/git/repos/${REPO_NAME}.git"
+
+if test -d "${REPO_DIR}"; then
+ printf "%s\n" "[err] repository ${REPO_NAME}.git already exists at ${REPO_DIR}"
+ exit 1
+fi
+
+TMP_DIR=$(mktemp -d -p /tmp)
+trap 'rm -rf "$TMP_DIR"' EXIT
+
+printf "%s\n" "[inf] cloning upstream repo"
+git clone --mirror --quiet "${REPO}" "${TMP_DIR}"
+
+printf "%s\n" "[inf] creating bare fork repository"
+mkdir -p "${REPO_DIR}"
+git init --bare --quiet "${REPO_DIR}"
+
+cat > "${REPO_DIR}/hooks/post-receive" << "EOL"
+#!/bin/sh
+
+agefile="$(git rev-parse --git-dir)"/info/web/last-modified
+
+mkdir -p "$(dirname "$agefile")" &&
+git for-each-ref \
+ --sort=-authordate --count=1 \
+ --format='%(authordate:iso8601)' \
+ >"$agefile"
+EOL
+chmod +x "${REPO_DIR}/hooks/post-receive"
+
+printf "%s\n" "[inf] pushing to bare repo"
+git --git-dir="${TMP_DIR}" push --mirror --quiet "${REPO_DIR}"
+
+printf "%s\n" "[inf] configuring bare repo"
+git --git-dir="${REPO_DIR}" config core.logallrefupdates true
+git --git-dir="${REPO_DIR}" config cgit.section "03. mirrors"
+git --git-dir="${REPO_DIR}" remote add upstream "${REPO}"
+
+chown -R git:git "${REPO_DIR}"
+chmod -R g-w "${REPO_DIR}"
+
+printf "%s\n" "[inf] mirrored ${REPO}"
diff --git a/git-shell-commands/create-repo b/git-shell-commands/create-repo
new file mode 100755
index 0000000..b5c6262
--- /dev/null
+++ b/git-shell-commands/create-repo
@@ -0,0 +1,59 @@
+#!/bin/bash
+
+set -e
+
+if test "${#}" -lt 1 || test "${#}" -gt 2; then
+ printf "%s\n" "usage: $(basename $0) <reponame> [section]"
+ exit 1
+fi
+
+REPO_NAME="${1}"
+REPO_SECTION="${2:-uncategorized}"
+REPO_DIR="/srv/git/repos/${REPO_NAME}.git"
+
+if ! [[ "${REPO_NAME}" =~ ^[a-zA-Z0-9_-]+$ ]]; then
+ printf "%s\n" "[err] repository name can only contain letters, numbers, underscores, and hyphens"
+ exit 1
+fi
+
+if test -d "${REPO_DIR}"; then
+ printf "%s\n" "[err] repository ${REPO_NAME}.git already exists at ${REPO_DIR}"
+ exit 1
+fi
+
+mkdir -p "${REPO_DIR}" &>/dev/null
+(
+ cd "${REPO_DIR}"
+ if git init --bare &>/dev/null; then
+ printf "%s\n" "[inf] created bare repository at ${REPO_DIR}"
+ else
+ printf "%s\n" "[err] failed to create bare repository at ${REPO_DIR}"
+ fi
+
+ git config core.logallrefupdates true
+
+ EMPTY_TREE=$(git hash-object -t tree /dev/null)
+ COMMIT=$(printf "%s\n" "initial commit" | git commit-tree "${EMPTY_TREE}")
+ git update-ref refs/heads/main "${COMMIT}"
+ git symbolic-ref HEAD refs/heads/main
+ git update-server-info
+ git config cgit.section "${REPO_SECTION}"
+
+ cat > hooks/post-receive << "EOL"
+#!/bin/sh
+
+agefile="$(git rev-parse --git-dir)"/info/web/last-modified
+
+mkdir -p "$(dirname "$agefile")" &&
+git for-each-ref \
+ --sort=-authordate --count=1 \
+ --format='%(authordate:iso8601)' \
+ >"$agefile"
+EOL
+ chmod +x hooks/post-receive
+)
+
+chown -R git:git "${REPO_DIR}"
+chmod -R g-w "${REPO_DIR}"
+
+printf "%s\n" "[inf] clone with git clone https://cgit.heqnx.com/${REPO_NAME}"