-
Notifications
You must be signed in to change notification settings - Fork 5
/
cvs2git-migrator.sh
executable file
·355 lines (279 loc) · 8.41 KB
/
cvs2git-migrator.sh
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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
#!/bin/bash
### cvs2git-migrator.sh
###
### This is a CVS Import Coordinator Script
###
### Usage: (see usage function)
###
### ./cvs2git-migrator.sh [options] module
### options:
### -c=/--cvsroot= cvsroot e.g. :pserver:user@cvs:/home/cvs/ (note: cannot use cvsroot with password embedded like :pserver:user:pwd@host)
### -m=/--module= module (can be specified here instead of at end)
### -o=/--options= options file for cvs2git (default: ~/.cvs2git.options)
### --cvspassword= password to provide to cvs server
### --cache= cache dir (default ~/.cvs2git-cache/)
### --output= output directory (default: ./ )
### --verbose= verbose (extra messages)
###
### module: cvs module to import (can be directory in order to import only submodule)
###
### General Script Steps:
### cvsclone the cvs directory
### cvs2git to extract blob and data
### git fast import to create the repo from blob
###
### Dependencies:
### cvsclone
### cv2git (cvs2svn)
### git
###
### This Script has some caching capability
######################################
## Boiler Plate Functions ############
######################################
PROGNAME=$(basename $0)
function error_exit
{
#----------------------------------------------------------------
#Function for exit due to fatal program error
#Accepts 1 argument:
#string containing descriptive error message
#----------------------------------------------------------------
echo "${PROGNAME}: ${1:-"Unknown Error"}" 1>&2
exit 1
}
function usage
{
#--------------------------------------
# print the usage doc
#--------------------------------------
cat <<-EOF
Usage: $PROGNAME [OPTIONS] module
OPTIONS:
-c=/--cvsroot= : cvsroot e.g. :pserver:user@cvs:/home/cvs/
(note: cannot use cvsroot with password embedded like :pserver:user:pwd@host)
Overrides CVSROOT
-m=/--module= : module (alternative opt)
-o=/--options= : options file for cvs2git (default: /etc/cvs2git-migrator/cvs2git.options or ~/cvs2git-migrator/cvs2git.options if it exists)
-n=/--no-cache : disable caching
--cvspassword= : password to provide to cvs server
--cache= cache dir (default ~/.cvs2git-migrator/cache)
--output= output directory (default: pwd )
--verbose= verbose (extra messages)
module: cvs module to submodule to import
Environment Variables for optionless invocation
CVS2GIT_OUTPUT_DIR - --output
CVS2GIT_CACHE_DIR - --cache
CVS2GIT_OPTIONS - -/--options
CVS2GIT_MODULE - -m/--module module
CVS2GIT_VERBOSE - -v/--verbose
CVS_PASSWORD - --cvspassword
CVSROOT - -c/--cvsroot
EOF
exit 0
}
###########################################
## Configurable Vars (Put Defaults Here) ##
###########################################
OUTPUT=${CVS2GIT_OUTPUT_DIR-`pwd`}
CACHE=${CVS2GIT_CACHE_DIR-"${HOME}/.cvs2git-migrator/cache"}
_OPTIONS_1="${HOME}/.cvs2git-migrator/cvs2git.options"
_OPTIONS_2="/etc/cvs2git-migrator/cvs2git.options"
if [[ -e $_OPTIONS_1 ]] ; then
OPTIONS=$_OPTIONS_1
else
OPTIONS=$_OPTIONS_2
fi
OPTIONS=${CVS2GIT_OPTIONS-$OPTIONS}
MODULE=${CVS2GIT_MODULE-}
VERBOSE=${CVS2GIT_VERBOSE-}
CVSROOT=${CVSROOT-}
CVS_PASSWORD=${CVS_PASSWORD-}
######################################
## ARG Parsing to Set Vars ###########
######################################
if [[ $# = 0 && -z $MODULE ]]; then
usage
fi
#we use the construction
#${i#*=} to strip the
# option string of everything before =
while [[ $# -gt 0 ]]
do
i="$1"
case $i in
-c=*|--cvsroot=*)
CVSROOT=${i#*=}
echo "option: --cvsroot $CVSROOT"
shift
;;
-m=*|--module=*)
MODULE=${i#*=}
echo "option: --module $MODULE"
shift
;;
-o=*|--options=*)
OPTIONS=${i#*=}
echo "option: --options $OPTIONS"
shift
;;
--cvspassword=*)
CVS_PASSWORD="${i#*=}"
echo "option: --cvspassword is set"
shift
;;
--cache=*)
CACHE=${i#*=}
echo "option: --cache $CACHE"
shift
;;
-n|--no-cache)
CACHE=""
echo "options: --no-cache"
shift
;;
--output=*)
OUTPUT=${i#*=}
echo "option: --output $OUTPUT"
shift
;;
-v|--verbose)
VERBOSE=1
shift
;;
-h|--help)
usage
shift
;;
-*|--*)
error_exit "unknown option $1"
;;
*)
break
;;
esac
done
if [[ -n $1 ]]; then
MODULE=$1
echo "module: $MODULE"
elif [[ -z $MODULE ]]; then
error_exit "You Need to Specificy a Module"
fi
#setup verbose mode
if [ "$VERBOSE" = 1 ]; then
exec 4>&2 3>&1
else
exec 4>/dev/null 3>/dev/null
fi
############################################
## Project Init ############################
############################################
echo "Starting CVS2GIT Import"
#replace dir slashes in CVS Module with '-'
PROJECT_NAME=$(echo $MODULE | sed -e 's/\//-/g')
PROJECT_NAME="${PROJECT_NAME,,}"
echo "-debug- DBG Project Name: $PROJECT_NAME" >&3
PROJECT_QUALIFIED_NAME=$PROJECT_NAME-$(date +"%Y%m%d-%H%M%S")
echo "-debug- Project Qualified Name: $PROJECT_QUALIFIED_NAME" >&3
#root project directory
PROJECT_DIR=`cd $OUTPUT && pwd`/$PROJECT_QUALIFIED_NAME
echo "-debug- Project Dir: $PROJECT_DIR" >&3
if [[ ! -e $PROJECT_DIR ]]; then
mkdir -p $PROJECT_DIR
echo "Creating New Project in $PROJECT_DIR"
elif [[ ! -d $PROJECT_DIR ]]; then
echo "$PROJECT_DIR exists but is not a directory" >&4
error_exit "$LINENO: $PROJECT_DIR is not a directory"
fi
if [[ -z $CACHE ]]; then
echo "-debug- run with --no-cache using $PROJECT_DIR for cache" >&3
CACHE=$PROJECT_DIR
fi
if [[ ! -e $CACHE ]]; then
echo "-debug- no cache dir creating $CACHE" >&3
mkdir -p $CACHE
fi
if [[ ! -d $CACHE ]]; then
echo "$CACHE exists but is not a directory" >&4
error_exit "$LINENO: $CACHE is not a directory"
fi
############################################
## cvsclone ############################
############################################
echo "Cloning CVS Repository $CVSROOT/$MODULE"
# if local cvsroot
if [[ -e $CVSROOT && -d $CVSROOT/$MODULE && ! -d $CACHE/$MODULE ]]; then
(
cd $CACHE && \
mkdir -p $MODULE/CVSROOT && \
cp -rf $CVSROOT/$MODULE/* $MODULE/
)
elif [[ ! -d $CACHE/$MODULE ]]; then
## We try a few strategies to lo\gin to cvs and clone
## If .cvspass exists and has something then we reuse those credentials
## If the password is provided as argument or env we construct a login from that
## Otherwise we drop to STDIN to login
if [[ ! -z $CVS_PASSWORD ]]; then
echo "Logging into CVS Repository using provided password"
cvs_local=$(echo $CVSROOT | sed -e "s/@/:$CVS_PASSWORD@/g")
cvs -d "$cvs_local" login
unset cvs_local
elif [[ -s ${HOME}/.cvspass ]]; then
cvs login
fi
(
cd $CACHE \
&& cvsclone -d $CVSROOT $MODULE\
&& mkdir -p $MODULE/CVSROOT\
&& echo "Succesfully Cloned CVS Module $CVSROOT/$MODULE"
)
#cvs logout
else
echo "Using Cached Version of CVS Module in $CACHE/$MODULE"
fi
if [[ $CACHE = $PROJECT_DIR ]]; then
(
cd $PROJECT_DIR\
&& mv $MODULE "cvs-data"\
&& echo "-debug- Renaming CVS Data to \"cvs-data\"" >&3
)
else
(
cd $PROJECT_DIR\
&& cp -rf $CACHE/$MODULE "cvs-data" \
&& echo "-debug- Copying CVS Module to Project Working Directory $PROJECT_DIR" >&3
)
fi
################################################
#import the data into git ####################
################################################
if [[ -f $OPTIONS ]]; then
(
cd $PROJECT_DIR \
&& cvs2git \
--options=$OPTIONS\
&& echo "Importing CVS Data into Git BLOB and DATA Files"
)
else
error_exit "$LINENO: cvs2git cannot run \$OPTIONS=$OPTIONS not defined or is not a file (use --options to specify), options required for meaningful import"
fi
if [[ -e "$PROJECT_DIR/git-blob.dat" && -e "$PROJECT_DIR/git-dump.dat" ]]; then
(
cd $PROJECT_DIR \
&& git init --bare $PROJECT_NAME.git \
&& cd $PROJECT_NAME.git \
&& cat ../git-blob.dat ../git-dump.dat | \
git fast-import \
&& git-move-refs.py \
&& git gc --prune=now \
&& echo "Created Bare Git Repository from CVS2GIT Dump in $PROJECT_DIR/$PROJECT_NAME.git"
)
else
error_exit "$LINENO: git fast-import cannot run cv2git failed to create correct blob and dump files in $PROJECT_DIR"
fi
if (which cowsay); then
cowsay "-CVS2GIT Import Completed-"
else
echo "-CVS2GIT Import Complete-"
fi
exit 0