diff options
-rw-r--r-- | cgit-backup.sh | 74 | ||||
-rwxr-xr-x | git-shell-commands/create-mirror | 12 | ||||
-rwxr-xr-x | git-shell-commands/create-repo | 10 |
3 files changed, 92 insertions, 4 deletions
diff --git a/cgit-backup.sh b/cgit-backup.sh new file mode 100644 index 0000000..066788a --- /dev/null +++ b/cgit-backup.sh @@ -0,0 +1,74 @@ +#!/bin/bash +# stages: +# - backup +# +# backup_cgit: +# stage: backup +# image: alpine:latest +# before_script: +# - apk add --no-cache bash curl git +# - git config --global user.name "GitLab CI" +# - git config --global user.email "ci@gitlab.com" +# - git remote set-url origin "https://oauth2:${TOKEN}@gitlab.com/user/repo.git" +# script: +# - /bin/bash cgit-backup.sh +# - git checkout main || git checkout -b main +# - git add repos/ +# - git commit -m "Backup cgit repositories $(date -u +'%Y-%m-%d %H:%M:%S UTC')" || true +# - git push origin main -o ci.skip +# only: +# - schedules +# variables: +# GIT_STRATEGY: clone + +#!/bin/bash + +cgit="https://cgit.heqnx.com" + +mkdir -p repos + +repos=$(curl -sSL "${cgit}" || { printf "%s\n" "[err] failed to fetch repository list"; exit 1; }) +repos=$(printf "%s\n" "$repos" | grep -o "<a href='/[^']*/'>" | sed -E "s/^<a href='([^']*)'>/\1/" | sort -u) + +while IFS= read -r repo_path; do + repo_name=$(basename "${repo_path}") + repo_url="${cgit}${repo_path}" + repo_dir="repos/${repo_name}" + + printf "%s\n" "[inf] processing ${repo_url}" + + if test -d "${repo_dir}"; then + if test -d "${repo_dir}/.git.bak"; then + printf "%s\n" "[inf] restoring .git from .git.bak for ${repo_name}" + mv "${repo_dir}/.git.bak" "${repo_dir}/.git" + fi + + printf "%s\n" "[inf] fetching updates for ${repo_name}" + default_branch=$(git -C "${repo_dir}" remote show origin | grep "HEAD branch" | awk '{print $NF}' || true) + if [ -z "$default_branch" ] || [ "$default_branch" = "(unknown)" ]; then + printf "%s\n" "[wrn] could not determine default branch for ${repo_name}, trying 'main' or 'master'" + default_branch=$(git -C "${repo_dir}" ls-remote --heads origin | grep -E 'refs/heads/(main|master)$' | head -1 | awk -F'/' '{print $NF}' || true) + default_branch=${default_branch:-main} + fi + printf "%s\n" "[inf] using default branch: ${default_branch}" + git -C "${repo_dir}" fetch origin + git -C "${repo_dir}" reset --hard "origin/${default_branch}" + else + printf "%s\n" "[inf] cloning ${repo_name}" + git -C repos clone "${repo_url}" + default_branch=$(git -C "${repo_dir}" remote show origin | grep "HEAD branch" | awk '{print $NF}' || true) + if [ -z "$default_branch" ] || [ "$default_branch" = "(unknown)" ]; then + printf "%s\n" "[wrn] could not determine default branch for ${repo_name}, trying 'main' or 'master'" + default_branch=$(git -C "${repo_dir}" ls-remote --heads origin | grep -E 'refs/heads/(main|master)$' | head -1 | awk -F'/' '{print $NF}' || true) + default_branch=${default_branch:-main} + fi + printf "%s\n" "[inf] using default branch: ${default_branch}" + git -C "${repo_dir}" checkout "${default_branch}" + fi + + if test -d "${repo_dir}/.git"; then + printf "%s\n" "[inf] moving .git to .git.bak for ${repo_name}" + mv "${repo_dir}/.git" "${repo_dir}/.git.bak" + fi +done <<< "${repos}" + diff --git a/git-shell-commands/create-mirror b/git-shell-commands/create-mirror index 8d2129c..2b1b1dc 100755 --- a/git-shell-commands/create-mirror +++ b/git-shell-commands/create-mirror @@ -8,14 +8,24 @@ if test "${#}" -ne 1; then fi REPO="${1}" +if ! [[ "${REPO}" =~ ^https://[a-zA-Z0-9.-]+/[a-zA-Z0-9_/.-]+$ ]]; then + printf "%s\n" "[err] invalid repository URL" + exit 1 +fi + REPO_NAME=$(basename "${REPO}") -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 +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 diff --git a/git-shell-commands/create-repo b/git-shell-commands/create-repo index b5c6262..3a85514 100755 --- a/git-shell-commands/create-repo +++ b/git-shell-commands/create-repo @@ -8,14 +8,18 @@ if test "${#}" -lt 1 || test "${#}" -gt 2; then 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 +REPO_SECTION="${2:-uncategorized}" +if ! [[ "${REPO_SECTION}" =~ ^[a-zA-Z0-9_-]+$ ]]; then + printf "%s\n" "[err] section can only contain letters, numbers, underscores, and hyphens" + exit 1 +fi + +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 |