This commit is contained in:
Midgard 2022-05-23 14:35:29 +02:00
parent 655f5c2fb4
commit 41b0b69231
Signed by: midgard
GPG key ID: 511C112F1331BBB4
2 changed files with 61 additions and 21 deletions

View file

@ -2,6 +2,19 @@
Run this script to synchronize a repository once.
## Quick start
Clone git-mirror somewhere on your system. Create a script like the following in the directory of
the repository you want to keep mirrored, and configure the variables:
```bash
#!/bin/sh
mirror="$HOME/path/to/git-mirror/git-mirror.sh"
leader="github" # Name of the leader remote
followers="origin" # Space separated list of names of follower remotes
exec "$mirror" --notor "$(dirname "$0")" $leader $followers
```
## Dependencies
* bash
* git
@ -12,7 +25,7 @@ Run this script to synchronize a repository once.
./git-mirror.sh <workdir> <leader> <follower...>
```
## Get started
## How to use
Create a git repo, add remotes for the leader and the followers:
```bash
mkdir ~/git-mirror-my-repo; cd ~/git-mirror-my-repo
@ -33,15 +46,21 @@ The first remote, `github` in this case, is the leader. The others are followers
If you want to do this conveniently every now and then, you can create a script like this in your
repository's directory:
```bash
#!/bin/bash
mirror="$HOME/git-mirror/git-mirror.sh"
here="$(dirname "$0")"
exec "$mirror" --notor "$here" github origin
#!/bin/sh
mirror="$HOME/path/to/git-mirror/git-mirror.sh"
leader="github" # Name of the leader remote
followers="origin" # Space separated list of names of follower remotes
exec "$mirror" --notor "$(dirname "$0")" $leader $followers
```
Make sure to make it executable, and gitignore it when relevant. A good idea may be to choose an
arcane name, like `update--.sh`, and add it to a global gitignore file in `~/.gitignore`.
## Caveat
If a branch has diverged, it will not be updated. Update it manually in that case.
## Automate
To automate mirroring, run it periodically, for example once every 30 minutes. On a *NIX you could
use cron for this, or write a system service definition for your system supervisor (such as

View file

@ -1,7 +1,7 @@
#!/bin/bash
# git-mirror: Mirror a git repo in leader-followers configuration
# Copyright © 2019 Midgard
# Copyright © 2019-2022 Midgard
#
# This program is free software: you can redistribute it and/or modify it under the terms of the
# GNU Affero General Public License as published by the Free Software Foundation, either version 3
@ -60,10 +60,15 @@ echo "${branches[*]}"
IFS=$'\t'
up_to_date=( )
errors=( )
error() {
echo "XXX $1" >&2
tput bold
tput setaf 1
echo -n "XXX"
tput sgr0
echo " $1" >&2
errors[${#errors[*]}]="$1"
}
@ -84,33 +89,49 @@ for branchspec in "${branches[@]}"; do
if [ "$branch" = HEAD ]; then continue; fi
for remote in "${followers[@]}"; do
echo
echo "Updating $remote/$branch"
follower_ref="refs/remotes/$remote/$branch"
msg=""
if ! ref_exists "$follower_ref"; then
echo "Branch doesn't yet exist at remote, creating"
git checkout "$leader_sha" --
git push "$remote" "+HEAD:$branch" || { error "$remote $branch: failed to push"; continue; }
elif is_ref_at_sha "$follower_ref" "$leader_sha"; then
echo "Already up to date"
msg="Creating $remote/$branch"
elif ! is_ref_at_sha "$follower_ref" "$leader_sha"; then
msg="Updating $remote/$branch"
else
echo "Branch exists at remote, updating"
git checkout "$follower_ref" --
git merge --ff-only "$leader_sha" || { error "$remote $branch: FF not possible"; continue; }
git push "$remote" "+HEAD:$branch" || { error "$remote $branch: failed to push"; continue; }
up_to_date[${#up_to_date[*]}]="$remote/$branch"
fi
if [[ -n $msg ]]; then
echo
tput bold
echo "$msg"
tput sgr0
git push "$remote" "+$leader_sha:refs/heads/$branch" || { error "$remote $branch: failed to push"; continue; }
fi
done
done
if [[ "${#up_to_date[*]}" -gt 0 ]]; then
echo
echo "Already up to date:"
echo "${up_to_date[@]}"
fi
echo
if [[ "${#errors[*]}" -gt 0 ]]; then
tput bold
tput setaf 1
echo "Errors:"
echo "${errors[@]}"
tput sgr0
tput bold
for (( i=0; i < ${#errors[*]}; i++ )); do
echo "${errors[$i]}"
done
tput sgr0
exit 1
else
echo "No errors."
fi