summaryrefslogtreecommitdiff
path: root/cgit-backup.sh
blob: 066788a6e1e1071b2ace0091e594a1943a8caf51 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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}"