Improve
This commit is contained in:
parent
655f5c2fb4
commit
41b0b69231
2 changed files with 61 additions and 21 deletions
29
README.md
29
README.md
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue