summaryrefslogtreecommitdiff
path: root/git_mirror.sh
blob: 365354e1ebfb46920485337a65baf1acdc1ce245 (plain) (blame)
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
75
#!/usr/bin/env bash

# Disable blocking for authentication and invalid repository URLs
export GIT_TERMINAL_PROMPT=0

# Record of errors encountered during execution
errors=0

# Fail if not enough arguments
if [[ $# < 1 ]]; then
    echo "usage: $(basename $0) {config}"
    exit 1
fi

# Obtain configuration file path
config="$1"
if [[ ! -f "$config" ]]; then
    echo "'$config' does not exist" >&2
    exit 1
fi

# Load configuration
source "$config"
repositories_len=${#repositories[@]}

# Check configuration sanity
if [[ -z "$dest" ]]; then
    echo "$config: 'dest' path undefined" >&2
    exit 1
fi

if (( ! repositories_len )); then
    echo "$config: 'repositories' array undefined or empty" >&2
    exit 1
fi

# Check destination sanity
if [[ ! -d "$dest" ]]; then
    mkdir -p "$dest" || exit 1
fi

if [[ ! -w "$dest" ]]; then
    echo "$dest: insufficient permission to write to destination directory" >&2
    exit 1
fi

# Begin
echo "---"
for repo in "${repositories[@]}"; do
    # Normalize repository output name to include '.git', because '--mirror' appends
    # it automatically to the destination directory
    name="$(basename $repo)"
    if [[ ! $name =~ .*\.git$ ]]; then
        name="${name}.git"
    fi

    # Update a mirrored repo, or clone it
    output="$dest/$name"
    if git --git-dir="$output" rev-parse &>/dev/null || [[ -d "${output}/.git" ]]; then
        echo "Updating: $output"
        pushd "$output" &>/dev/null
        git fetch --all || (( errors++ ))
        popd &>/dev/null
    else
        echo "Mirroring: $repo"
        git clone --mirror "$repo" "$output" || (( errors++ ))
    fi
    echo "---"
done

if (( errors )); then
    echo "done, with $errors error(s)!"
else
    echo "done!"
fi