GIT/HG/SVN on multiple repos simultaneously
Posted by mazet on 15 Avr 2020 in Programmation
This script can be used to send commands on multiple repositories and work simultaneously. It is useful to synchronize, publish, tag or branch several repository.It works for Subversion, Mercurial and Git repositories just by naming the script svnall
, hgall
,or gitall
.
Shell
#!/bin/bash | |
| |
# default values | |
PROGNAME=$(basename $0) | |
FULLPROG=$0 | |
LIST="repos1 repos2 reposN" | |
| |
# debug | |
dryrun="no" | |
| |
# usage | |
function usage () { | |
echo "usage: $PROGNAME [-d] [-h] [-l list] command" | |
echo " -d: dry ryn" | |
echo " -h: help message" | |
echo " -l: repository list" | |
} | |
| |
# formating functions | |
function title () { echo -e "\033[0;1m$*\033[0;0m"; } | |
function pass () { echo -e "\033[1;32m$*\033[0;0m"; } | |
function warn () { echo -e "\033[1;33m$*\033[0;0m"; } | |
function fail () { echo -e "\033[1;31m$*\033[0;0m"; } | |
| |
# variables | |
list=$LIST | |
command= | |
| |
# VCS definition | |
VCS= | |
case $(basename $0) in | |
git*) VCS=git; BASE=.git;; | |
hg*) VCS=hg; BASE=.hg;; | |
svn*) VCS=svn; BASE=.svn;; | |
esac | |
function is_repos_clean() { | |
case "$VCS" in | |
git) git describe --dirty=+ 2>/dev/null | awk '/+/ {exit 1}';; | |
hg) hg id -i | awk '/+/ {exit 1}';; | |
svn) svn status -q | awk 'END {exit (NF!=0)}';; | |
*) fail "not defined yest" >&2; exit 1;; | |
esac | |
} | |
[ "$VCS" ] || { fail "unknown VCS" >&2; exit 1; } | |
| |
# parameter processing | |
while [ $# -gt 0 ]; do | |
case "$1" in | |
-d) dryrun="yes";; | |
-h) usage; exit 0;; | |
-l) shift; list=$1;; | |
-l=*) list=${1/#-l=};; | |
*) break;; | |
esac | |
shift | |
done | |
cmd=$* | |
| |
# check command | |
[ "$cmd" ] ||{ fail "no command defined" >&2; exit 1; } | |
| |
# directories | |
olddir=`pwd` | |
mydir=`dirname $0` | |
[ -z "$mydir" -o "$mydir" = "." ] && mydir=`pwd` | |
trap "cd $oldpwd; exit 1;" 0 1 2 15 | |
| |
# check root | |
root=$mydir | |
while [ ! -d $root/$BASE ]; do | |
root=`cd $root/..; pwd` | |
[ $root = "/" ] && break | |
done | |
[ -d $root/$BASE ] || \ | |
{ fail "can not find $VCS root" >&2; exit 2; } | |
| |
# check clean repository | |
title "check clean repository" | |
is_clean= | |
for d in $list; do | |
[ -d $root/../$d ] || \ | |
{ warn "skipping $d" >&2; continue; } | |
{ cd $root/../$d; is_repos_clean; } || \ | |
{ warn "= repository $d not clean"; is_clean="no"; } | |
done | |
if [ "$is_clean" = "no" ]; then | |
read -p "some repositories are not cleaned, do you want to proceed (y/n) [n] ? " ans | |
[[ "$ans" =~ ^[yY][eE][sS]$ || "$ans" =~ ^[yY]$ || | |
"$ans" =~ ^[oO][uU][iI]$ || "$ans" =~ ^[oO]$ ]] || exit 0 | |
fi | |
| |
# main process | |
for d in $list; do | |
[ -d $root/../$d ] || continue; | |
title "processing repository $d" | |
warn "= $VCS $cmd" | |
if [ "$dryrun" = "no" ]; then | |
{ cd $root/../$d && eval $VCS $cmd; } || exit 4 | |
else | |
echo "cd $root/../$d && $VCS $cmd" | |
fi | |
done |
This entry was posted by mazet and filed under Programmation.