Add bare git repository support with configurable source, destination, and bare flag

This commit is contained in:
James Coleman 2026-06-16 11:09:03 -05:00
parent 3fc2257751
commit 4d800e21b4
2 changed files with 71 additions and 5 deletions

View file

@ -111,18 +111,38 @@ Each repo has at bare minimum the following configurations:
- dusum - Path to a file to store disk usage summary results of the repository directory.
### git
Synchronizes a git repository via git pull. To use this method, you need to have the git package installed.
Synchronizes a git repository. To use this method, you need to have the git package installed.
If the destination (`repo`) does not yet contain a git repository, it is cloned from the configured `source`. Otherwise it is updated in place. Bare repositories have no working tree, so they cannot be updated with `git pull`; instead the script clones them with `git clone --mirror` and updates them with `git remote update --prune`, which honors the repository's configured fetch refspec.
Whether a repository is bare can be set explicitly with the `bare` configuration, otherwise existing repositories are auto-detected.
#### source
The git URL to clone the repository from. Required when the destination does not already contain a git repository.
#### bare
Set to `true` to treat the repository as bare. When cloning, this clones with `git clone --mirror`. When updating, this forces use of `git remote update --prune`. If unset, existing repositories are auto-detected.
#### options
Extra options appended to `git pull`.
Extra options appended to the git command (`git clone` when cloning, `git pull` when updating a working-tree repository, or `git remote update --prune` when updating a bare repository).
#### Example
```bash
example_sync_method="git"
example_source="https://github.com/example/example.git"
example_repo="/home/mirror/http/example"
example_timestamp="/home/mirror/timestamp/example"
```
#### Bare repository example
```bash
example_sync_method="git"
example_source="https://github.com/example/example.git"
example_repo="/home/mirror/git/example.git"
example_bare="true"
example_timestamp="/home/mirror/timestamp/example"
```
### aws
Synchronize with an s3 bucket using aws cli. To use this, you need the aws cli package installed.

View file

@ -5,7 +5,7 @@ PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:$HOME/.local/
# Variables for trace generation.
PROGRAM="mirror-sync"
VERSION="20260602"
VERSION="20260616"
TRACEHOST=$(hostname -f)
mirror_hostname=$(hostname -f)
DATE_STARTED=$(LC_ALL=POSIX LANG=POSIX date -u -R)
@ -617,12 +617,58 @@ git_sync() {
# Start the module.
module_config "$1"
# Do a git pull within the repo folder to sync.
# Read git specific configuration.
eval source="\$${MODULE}_source"
eval bare="\$${MODULE}_bare"
# Normalize the bare flag to either "true" or empty.
case "${bare,,}" in
1|true|yes|bare) bare="true" ;;
*) bare="" ;;
esac
# If the destination does not yet contain a git repository, clone it from
# the configured source. Bare repositories are cloned with --mirror so the
# configured fetch refspec mirrors all refs from upstream.
if [[ ! -e "${repo:?}/.git" ]] && [[ ! -e "${repo:?}/HEAD" ]]; then
if [[ ! $source ]]; then
echo "No git repository at '${repo:?}' and no source defined to clone from."
exit 1
fi
echo "Cloning '${source}' into '${repo:?}'."
if [[ $bare ]]; then
eval git clone --mirror ${options:+$options} "'${source}'" "'${repo:?}'"
else
eval git clone ${options:+$options} "'${source}'" "'${repo:?}'"
fi
RT=$?
if (( RT == 0 )); then
post_successful_sync
else
post_failed_sync
fi
log_end_header
return
fi
# Move into the repo folder to sync.
if ! cd "${repo:?}"; then
echo "Failed to access '${repo:?}' git repository."
exit 1
fi
# Determine whether the repository is bare. Honor an explicit configuration
# if set, otherwise auto-detect. Bare repositories have no working tree, so a
# `git pull` is not possible; instead use `git remote update` which honors the
# configured fetch refspec (e.g. a mirror clone created with --mirror).
if [[ ! $bare ]] && [[ $(git rev-parse --is-bare-repository 2>/dev/null) == "true" ]]; then
bare="true"
fi
if [[ $bare ]]; then
eval git remote update --prune ${options:+$options}
else
eval git pull ${options:+$options}
fi
RT=$?
if (( RT == 0 )); then
post_successful_sync