summaryrefslogtreecommitdiffstats
path: root/git-svn-helper
blob: 01194cd2be2e2b72cf581cc06b8c6123a847b2b7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#! /bin/bash

ACTIONS=''
for arg in $@; do
    case "$arg" in
        pull|push|commit)
            ACTIONS="$ACTIONS $arg"
            ;;
        *)
            GIT_SVN_CONFIG=$arg
            ;;
    esac
done
BATCH_MODE=0
[ ! -z "$ACTIONS" ] && BATCH_MODE=1
GIT_SVN_CONFIG=${GIT_SVN_CONFIG:-".git-svn-config"}

RED="\033[0;31m"
RESET="\033[0m"

function error () {
    echo -e " $1 => ${RED}FAILURE${RESET}"  && exit 1
}

function say () {
    [ $BATCH_MODE == 0 ] && echo -e "$1"
    return 0
}

[ -e $GIT_SVN_CONFIG ] || error "$GIT_SVN_CONFIG does not exists!"
source ./$GIT_SVN_CONFIG

[ ! -z "$PRJ" ] || error "PRJ variable is not defined"
[ ! -z "$SVN_URL" ] || error "SVN_URL variable is not defined"
[ ! -z "$BRANCHES_TO_TRACK" ] || error "BRANCHES_TO_TRACK variable is not defined"

LOCAL_REPO=${LOCAL_REPO:-"local"}
LOCAL_DIR=${LOCAL_DIR:-"$(pwd)/${PRJ}"}
SVN_SUFFIX=_svn
SVN_CLONE_REPO=${SVN_CLONE_REPO:-"svn_clone"}
SVN_CLONE_DIR=${SVN_CLONE_DIR:-"$(pwd)/${PRJ}${SVN_SUFFIX}"}

URL_COLOR="\033[0;34m"
LRC="\033[0;33m"    # LOCAL REPO COLOR
LBC="\033[0;36m"    # LOCAL BRANCH COLOR
SRC="\033[0;35m"    # SVN CLONE REPO COLOR
SBC="\033[0;32m"    # SVN CLONE BRANCH COLOR
DSBC="\033[0;37m"   # DISTANT SVN BRANCH COLOR

function ask_ok () {
    [ $BATCH_MODE == 1 ] && return 0
    echo -e -n "$1${RESET}[${RED}Y${RESET}n] : "
    read  OK
    if [ "$OK" = "" -o "$OK" = "y" -o "$OK" = "Y" ]; then
        return 0
    fi
    say "${RED}abort${RESET}" && return 1
}

function create_svn_clone () {
    say "** clone from ${URL_COLOR}${SVN_URL}${RESET}" && cd ${SVN_CLONE_DIR%/*} && git svn clone ${SVN_URL} -T trunk -b branches -t tags ${SVN_CLONE_DIR} || error
    cd ${SVN_CLONE_DIR}
    for branch in $BRANCHES_TO_TRACK; do
        say "** checkout ${DSBC}${branch}${RESET} in ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${branch}${SVN_SUFFIX}${RESET}" && \
            git checkout $branch -b ${branch}${SVN_SUFFIX}  || error
    done
    say "** remove master branch" && git branch -D master || error
    say "** add ${LRC}${LOCAL_DIR}${RESET} as repo ${LRC}${LOCAL_REPO}${RESET}" && git remote add ${LOCAL_REPO} ${LOCAL_DIR} || error
}

function create_local_repo () {
    say "** git init ${LRC}${LOCAL_DIR}${RESET}" && git init ${LOCAL_DIR}|| error
    say "** cd ${LRC}${LOCAL_DIR}${RESET}" && cd ${LOCAL_DIR} || error
    say "** add ${SRC}${SVN_CLONE_DIR}${RESET} as repo ${SRC}${SVN_CLONE_REPO}${RESET}" && git remote add ${SVN_CLONE_REPO} ${SVN_CLONE_DIR} || error
    say "** fetch ${SRC}${SVN_CLONE_REPO}${RESET}" && git fetch ${SVN_CLONE_REPO} || error
    for branch in $BRANCHES_TO_TRACK; do
        say "** checkout ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${branch}${SVN_SUFFIX}${RESET} to ${SBC}${branch}${RESET}" && \
            git checkout ${SVN_CLONE_REPO}/${branch}${SVN_SUFFIX} -b ${branch}  || error
    done
}

function fetch_svn () {
    say "** cd ${SRC}${SVN_CLONE_DIR}${RESET}" && cd ${SVN_CLONE_DIR} || error
    say "** fetch from ${URL_COLOR}${SVN_URL}${RESET}" && git svn fetch || error
    BRANCHES=$(git for-each-ref --format="%(refname:short)" refs/heads/)
    for branch in $BRANCHES; do
        say "** rebase ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${branch}${RESET}" && git checkout $branch && git svn rebase || error
    done
    say "** cd ${SRC}${LOCAL_DIR}${RESET}" && cd ${LOCAL_DIR} || error
    say "** fetch ${SRC}${SVN_CLONE_REPO}${RESET}" && git fetch ${SVN_CLONE_REPO} || error
}

function push_to_clone () {
    say "** cd ${SRC}${SVN_CLONE_DIR}${RESET}" && cd ${SVN_CLONE_DIR} || error
    say "** fetch ${LRC}${LOCAL_REPO}${RESET}" && git fetch ${LOCAL_REPO} || error
    say "** checkout ${SBC}${SVN_B}${RESET}" && git checkout ${SVN_B} || error
    say "** rebase ${LRC}${LOCAL_REPO}${RESET}/${LBC}${LOCAL_B}${RESET} within ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_B}${RESET}" && \
        git rebase ${LOCAL_REPO}/${LOCAL_B} || error
    say "** cd ${SRC}${LOCAL_DIR}${RESET}" && cd ${LOCAL_DIR} || error
    say "** fetch ${SRC}${SVN_CLONE_REPO}${RESET}" && git fetch ${SVN_CLONE_REPO} || error
}

function dcommit () {
    say "** cd ${SRC}${SVN_CLONE_DIR}${RESET}" && cd ${SVN_CLONE_DIR} || error
    say "** checkout ${SBC}${SVN_B}${RESET}" && git checkout ${SVN_B} || error
    say "** rebase ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_B}${RESET}" && git svn rebase || error
    say "** dcommit ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_B}${RESET} to ${URL_COLOR}${SVN_URL}${RESET}" && git svn dcommit
}

function pull_from_clone () {
    #say "** cd ${SRC}${LOCAL_DIR}${RESET}" && cd ${LOCAL_DIR} || error
    #say "** fetch ${SRC}${SVN_CLONE_REPO}${RESET}" && git fetch ${SVN_CLONE_REPO} || error
    #say "** merge ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_B}${RESET} within ${LRC}${LOCAL_REPO}${RESET}/${LBC}${LOCAL_B}${RESET}" && git merge ${SVN_CLONE_REPO}/${SVN_B} || error
    say "To do so :"
    say "  ${LRC}- save your current work      ${SRC}$ git stash save NAME${RESET}"
    say "  ${LRC}- leave your current branch   ${SRC}$ git checkout ANOTHER_BRANCH${RESET}"
    say "  ${LRC}- delete your branch          ${SRC}$ git branch -D ${LOCAL_B}${RESET}"
    say "  ${LRC}- checkout your branch        ${SRC}$ git checkout ${SVN_CLONE_REPO}/${LOCAL_B}${SVN_SUFFIX} -b ${LOCAL_B}${RESET}"
    say "  ${LRC}- apply your current work     ${SRC}$ git stash pop/apply${RESET}"
}

if [ ! -d ${SVN_CLONE_DIR} ]; then
    ask_ok "clone svn repository ${URL_COLOR}${SVN_URL}${RESET} to ${SRC}${SVN_CLONE_DIR}${RESET} " && create_svn_clone
fi
if [ ! -d ${LOCAL_DIR} ]; then
    ask_ok "create local repository within ${LRC}${LOCAL_DIR}${RESET} " && create_local_repo
fi

cd ${LOCAL_DIR} 2>/dev/null || error "${LOCAL_DIR} does not exists"
LOCAL_B=$(git branch |grep '*' | gawk '{print $2;}') || error "unable to list local branches"
LOCAL_HEAD=$(git log --pretty="format:%H" HEAD~1..) || error "unable to read local head"
say "** ${LRC}${LOCAL_REPO}${RESET} current branch is ${LBC}${LOCAL_B}${RESET} head ${RED}${LOCAL_HEAD}${RESET}"
cd ${SVN_CLONE_DIR} 2>/dev/null || error "${SVN_CLONE_DIR} does not exists"
SVN_B=${LOCAL_B}_svn
git checkout ${SVN_B}
SVN_HEAD=$(git log --pretty="format:%H" HEAD~1..) || error "unable to read local head"
say "** ${LRC}${SVN_CLONE_REPO}${RESET} corresponding branch is ${LBC}${SVN_B}${RESET} head ${RED}${SVN_HEAD}${RESET}"
cd ${LOCAL_DIR}

while [ -z "$ACTIONS" ]; do
    say "\nOptions :"
    say " # 1) ${RED}fetch svn${RESET} and update branches within ${SRC}${SVN_CLONE_DIR}${RESET}"
    say " # 2) ${RED}push${RESET} ${LRC}${LOCAL_REPO}${RESET}/${LBC}${LOCAL_B}${RESET} within ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_B}${RESET}"
    say " # 3) ${RED}push${RESET} ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_B}${RESET} to ${URL_COLOR}${SVN_URL}${RESET}"
    say " # 4) ${RED}pull${RESET} ${SRC}${SVN_CLONE_REPO}${RESET}/${SBC}${SVN_B}${RESET} within ${LRC}${LOCAL_REPO}${RESET}/${LBC}${LOCAL_B}${RESET}"
    say " # q) ${RED}QUIT${RESET}"
    echo -n -e "\nyour choice : "
    read CHOICE
    echo ""
    case $CHOICE in
        q)
            exit 0
            ;;
        1)
            fetch_svn
            ;;
        2)
            push_to_clone
            ;;
        3)
            dcommit
            ;;
        4)
            pull_from_clone
            ;;
    esac
done

if [ ! -z "$ACTIONS" ]; then
    for action in $ACTIONS; do
        if [ "$action" == "pull" ];  then
            fetch_svn
        elif [ "$action" == "push" ];  then
            push_to_clone
        elif [ "$action" == "commit" ];  then
            dcommit
        fi
    done
fi