view hg/hgsyncee @ 571:5ce1dc5f661f

Remove Russian comments.
author Oleksandr Gavenko <gavenkoa@gmail.com>
date Thu, 08 May 2014 22:24:32 +0300
parents b49dfaf54da8
children 8a1afde74602
line wrap: on
line source

#!/bin/sh
# -*- coding: cp1251-unix; sh-basic-offset: 4 -*-

# Copyright (C) 2008 by Oleksandr Gavenko <gavenkoa@gmail.com>

# set -x
# set -u

UTIL_NAME=$0
UTIL_NAME=${UTIL_NAME##*/}

LOG_FILE=$UTIL_NAME.log

Usage() {
    echo Sync two etalon repo set via intermediate repo set.
    echo "Usage:"
    echo "$UTIL_NAME [--help]"
    echo "  --help   print this help"
}

# Один аргумент со значением INFO или ERROR.
# Без аргументов - как если с аргументом ERROR.
PrintLog() {
    if [ x$1 = x ] ; then
        MSG_SIGN=ERROR
    else
        case $1 in
            INFO|PROCESSING)
                MSG_SIGN=$1
                MSG_SIGN_COLOR=$1
                ;;
            ADDED)
                MSG_SIGN=$1
                MSG_SIGN_COLOR="\033[32m"$1"\033[0m"
                ;;
            ERROR|WARNING)
                MSG_SIGN=$1
                MSG_SIGN_COLOR="\033[31m"$1"\033[0m"
                ;;
            *) exit 1 ;;
        esac
    fi
    printf "$MSG_SIGN_COLOR: $MSG\n"
    printf "$MSG_SIGN: $MSG\n" >>$LOG_FILE 2>&1
}

# For GNU ls.
export BLOCK_SIZE=1024
LOG_SIZE=20

# If log size larger then $LOG_SIZE KiB rotate log, log.1 and log.2.
RotateLog() {
    [ -e $LOG_FILE ] || return
    if [ `ls -s $LOG_FILE | sed 's_ *\([0-9]\) .*_\1_'` -ge $LOG_SIZE ]; then
        rm -f $LOG_FILE.2
        [ -e $LOG_FILE.1 ] && mv $LOG_FILE.1 $LOG_FILE.2
        mv $LOG_FILE $LOG_FILE.1
    fi
}

# Is hg utility present in system?
Check_HG_exist() {
    command -v hg && return 0 || return 1
}

Set_HG_REP_CONF() {
    # Если есть локальный файл конфигурации репозиториев (полезно для отладки).
    HG_REP_CONF=./hgsyncrc
    if [ -e $HG_REP_CONF ]; then
        return 0;
    fi
    # Иначе ищем по стандартному пути.
    if [ x$HOME = x ] ; then
        MSG="Var HOME not set."
        return 1;
    fi
    HG_REP_CONF=$HOME/.hgsyncrc
    if [ -e $HG_REP_CONF ] ; then
        return 0;
    fi
    HG_REP_CONF=/etc/hgsyncrc
    if [ -e $HG_REP_CONF ]; then
        return 0;
    fi
    MSG="Config file not found, see man page hgsyncrc(1)."
    return 1;
}

Check_HG_REP_CONF() {
    if [ x$HG_PUSH_DIR = x ] ; then
        MSG="HG_PUSH_DIR not set in $HG_REP_CONF"
        return 1;
    fi
    if [ -d $HG_PUSH_DIR ] ; then :
    else
        MSG="HG_PUSH_DIR from $HG_REP_CONF point for non existing dir."
        return 1;
    fi
    if [ x$HG_PULL_DIR = x ] ; then
        MSG="HG_PULL_DIR not set in $HG_REP_CONF"
        return 1;
        if [ -d $HG_PULL_DIR ] ; then :
        else
            MSG="HG_PULL_DIR from $HG_REP_CONF point for non existing dir."
            return 1;
        fi
    fi
    return 0;
}

# Expect two args - path to compared repos.
CheckRepCompatibility() {
    REP1_ZERO_REV=`hg -R $1 log -r0 --template '{node}'`
    REP2_ZERO_REV=`hg -R $2 log -r0 --template '{node}'`

    [ "$REP1_ZERO_REV" = "$REP2_ZERO_REV" ] && return 0 || return 1
}

# ##########
# Main work.
# ##########

case x${1-} in
    x-h|x--help)
        Usage
        exit 0;
        ;;
esac

RotateLog

echo >>$LOG_FILE 2>&1
echo ========================= >>$LOG_FILE 2>&1
date +"%F %T" >>$LOG_FILE 2>&1

if Check_HG_exist; then :
else
    MSG="It seems hg utility is not in the PATH."
    PrintLog ERROR
    exit 1;
fi

if Set_HG_REP_CONF; then
    . $HG_REP_CONF
else
    PrintLog
    exit 1;
fi

if Check_HG_REP_CONF; then :
else
    PrintLog
    exit 1;
fi

if [ -d "$HG_PULL_DIR" ] || mkdir "$HG_PULL_DIR"; then
    :
else
    MSG="Can not create $HG_PULL_DIR."
    PrintLog
    exit 1;
fi

MSG="Path to etalon repo set: $HG_PUSH_DIR"
PrintLog INFO
MSG="Path to intermediate repo set: $HG_PULL_DIR"
PrintLog INFO

echo

for dir in */.hg/. .*/.hg/.; do
    dir=${dir%/.hg/.}
    [ -d "$dir" ] || continue

    MSG="'$dir' repo."
    PrintLog PROCESSING

    if [ -d $HG_PUSH_DIR/$dir/.hg ]; then
        if [ -d $HG_PULL_DIR/$dir/.hg ] ; then
            if CheckRepCompatibility $HG_PULL_DIR/$dir $HG_PUSH_DIR/$dir; then :
            else
                MSG="It seems repositories $HG_PULL_DIR/$dir $HG_PUSH_DIR/$dir not compatable."
                PrintLog
                exit 1;
            fi
            hg -R $HG_PULL_DIR/$dir pull $HG_PUSH_DIR/$dir >>$LOG_FILE 2>&1
        else
            hg clone $HG_PUSH_DIR/$dir $HG_PULL_DIR/$dir >>$LOG_FILE 2>&1
        fi
        if CheckRepCompatibility $HG_PULL_DIR/$dir ./$dir; then :
        else
            MSG="It seems repo '$dir' and etalon repo not compatable."
            PrintLog
            exit 1;
        fi
        hg -R $HG_PULL_DIR/$dir pull ./$dir >>$LOG_FILE 2>&1
    else
        MSG="'$dir' repo skiped. It is absent in etalon repo set."
        PrintLog INFO
        continue
    fi

    HEAD_CNT=`hg -R $HG_PULL_DIR/$dir head | grep "changeset:" | wc -l`
    case $HEAD_CNT in
        # Если нет необходимости мержить - изменения "правильные"
        # и должны быть возвращены как в промежуточный репозиторий,
        # так и в эталонный репозиторий.
        1)
            CHANGESET_CNT=`hg --config defaults.outgoing="" --quiet -R $HG_PULL_DIR/$dir out \
                --template '{node}\n' $HG_PUSH_DIR/$dir | wc -l`
            case $CHANGESET_CNT in
                0) ;;
                *)
                    hg -R $HG_PULL_DIR/$dir push $HG_PUSH_DIR/$dir >>$LOG_FILE 2>&1
                    MSG="==> etalon"
                    PrintLog ADDED
                    ;;
            esac
            CHANGESET_CNT=`hg --config defaults.outgoing="" --quiet -R $HG_PULL_DIR/$dir out \
                --template '{node}\n' ./$dir | wc -l`
            case $CHANGESET_CNT in
                0) ;;
                *)
                    hg -R $HG_PULL_DIR/$dir push ./$dir >>$LOG_FILE 2>&1
                    MSG="==> work"
                    PrintLog ADDED
                    ;;
            esac
            ;;
        # Иначе переносим только "правильные" делты в промежуточный репозиторый
        # для их доступности из промежуточного репозитория на другом рабочем месте.
        *)
            MSG="You must manually merge '$dir' proj and repeat run $UTIL_NAME."
            PrintLog WARNING
            MSG="Go to $HG_PULL_DIR/$dir dir."
            PrintLog WARNING
            hg -R $HG_PUSH_DIR/$dir push -f ./$dir >>$LOG_FILE 2>&1
            ;;
    esac
done

command -v sync >/dev/null && sync