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. - dusum - Path to a file to store disk usage summary results of the repository directory.
### git ### 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 #### 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 #### Example
```bash ```bash
example_sync_method="git" example_sync_method="git"
example_source="https://github.com/example/example.git"
example_repo="/home/mirror/http/example" example_repo="/home/mirror/http/example"
example_timestamp="/home/mirror/timestamp/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 ### aws
Synchronize with an s3 bucket using aws cli. To use this, you need the aws cli package installed. 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. # Variables for trace generation.
PROGRAM="mirror-sync" PROGRAM="mirror-sync"
VERSION="20260602" VERSION="20260616"
TRACEHOST=$(hostname -f) TRACEHOST=$(hostname -f)
mirror_hostname=$(hostname -f) mirror_hostname=$(hostname -f)
DATE_STARTED=$(LC_ALL=POSIX LANG=POSIX date -u -R) DATE_STARTED=$(LC_ALL=POSIX LANG=POSIX date -u -R)
@ -617,12 +617,58 @@ git_sync() {
# Start the module. # Start the module.
module_config "$1" 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 if ! cd "${repo:?}"; then
echo "Failed to access '${repo:?}' git repository." echo "Failed to access '${repo:?}' git repository."
exit 1 exit 1
fi 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} eval git pull ${options:+$options}
fi
RT=$? RT=$?
if (( RT == 0 )); then if (( RT == 0 )); then
post_successful_sync post_successful_sync