-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathsvn-to-monorepo
More file actions
executable file
·178 lines (149 loc) · 4.23 KB
/
svn-to-monorepo
File metadata and controls
executable file
·178 lines (149 loc) · 4.23 KB
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
#!/bin/bash
__SUMMARY__=$(cat <<"__TLDR__"
svn-to-monorepo
Converts the VDT SVN repo to a Git repo with a 'monorepo' layout --
meaning all of the branches are in a directory, instead of there being
one Git branch per SVN branch.
__TLDR__
)
AUTHORS_FILE=.svn-authors.txt
AUTHORS_URL=https://vdt.cs.wisc.edu/svn-authors.txt
GITHUB_REPOSITORY=osg-htc/software-packaging
SVN=https://vdt.cs.wisc.edu/svn
PROG=${0##*/}
PROGDIR=$(dirname "$0")
FILTER_SCRIPT=$PROGDIR/svn-to-monorepo-filter-monorepo
ask_yn () {
echo >&2 "$@"
while read -r; do
case $REPLY in
[Yy]*) return 0;;
[Nn]*) return 1;;
*) echo >&2 "Enter yes or no";;
esac
done
return 2 # EOF
}
eecho () {
echo >&2 "$@"
}
fail () {
set +exu
ret=${1:-1}
shift &>/dev/null || :
if [[ -z $* ]]; then
echo "$PROG: unspecified failure, exiting" >&2
else
echo "$PROG:" "$@" >&2
fi
exit "$ret"
}
usage () {
echo >&2 "$__SUMMARY__"
echo >&2
echo >&2 "Usage: $PROG <destination>"
exit "$1"
}
require_program () {
command -v "$1" &>/dev/null ||
fail 127 "Required program '$1' not found in PATH"
}
GIT () {
git -C "$DESTDIR" "$@"
}
GIT_RAW () {
git -C "$DESTDIR_RAW" "$@"
}
#
# Parse args
#
if [[ $1 == -h || $1 == --help ]]; then
usage 0
fi
if [[ $# != 1 ]]; then
usage 2
fi
DESTDIR=$(readlink -f "$1")
DESTDIR_RAW=${DESTDIR}.raw
set -o nounset
#
# Check for required programs
#
require_program git
git svn -h >/dev/null || fail 127 "git svn not available; try installing the git-svn package (or equivalent on your distribution)"
require_program curl
require_program git-filter-repo
[[ -x $FILTER_SCRIPT ]] || fail 127 "$FILTER_SCRIPT not found or not executable"
#
# Create a fresh dir for the Git repo
#
if [[ -d $DESTDIR ]]; then
if ask_yn "$DESTDIR already exists. Replace it?"; then
rm -rf "${DESTDIR}.bak" || fail 4 "Unable to delete ${DESTDIR}.bak"
mv -f "${DESTDIR}" "${DESTDIR}.bak" || fail 4 "Unable to move ${DESTDIR} out of the way"
else
fail 4 "Not replacing $DESTDIR"
fi
else
mkdir "$DESTDIR" || fail 5 "Could not create $DESTDIR"
fi
#
# Init the repo
#
if [[ ! -e $DESTDIR_RAW/.git/svn ]]; then
if [[ -e $DESTDIR_RAW ]]; then
if ask_yn "$DESTDIR_RAW already exists but does not look like a git-svn repo. Delete it?"; then
rm -rf "$DESTDIR_RAW" || fail 4 "Unable to delete $DESTDIR_RAW"
else
fail 4 "Not deleting $DESTDIR_RAW"
fi
fi
mkdir "$DESTDIR_RAW" || fail 5 "Could not create $DESTDIR_RAW"
GIT_RAW svn init $SVN/native/redhat --ignore-paths='^(tags)|(/_[a-z_]+/|[.]tar[.]gz$|[.]rpm$)' || fail 6 "Error creating Git repo"
curl -o "$DESTDIR_RAW/.git/$AUTHORS_FILE" "$AUTHORS_URL" || fail 7 "Could not download authors file"
GIT_RAW config svn.authorsfile ".git/$AUTHORS_FILE"
#
# Fetch from SVN and filter the results
#
eecho "*"
eecho "* Fetching SVN commits for the first time, go make a sandwich"
eecho "*"
GIT_RAW svn fetch -q --log-window=1000 || fail 7 "Fetch failed"
else
eecho "*"
eecho "* Updating SVN commits"
eecho "*"
GIT_RAW svn rebase || fail 7 "Rebase failed"
fi
eecho "*"
eecho "* Cloning and filtering"
eecho "*"
git clone --no-local "$DESTDIR_RAW" "$DESTDIR" || fail 11 "clone from $DESTDIR_RAW to $DESTDIR failed"
"$FILTER_SCRIPT" "$DESTDIR" || fail 8 "Filter failed"
#
# Configure the remote and fetch from it
#
GIT remote add github https://github.com/${GITHUB_REPOSITORY} || fail 9 "Adding GitHub as a remote failed"
timeout 180 git -C "$DESTDIR" fetch github || fail 11 "Fetch from GitHub failed"
GIT branch --set-upstream-to=github/main
#
# Done! Push if we can do it without rewriting history.
#
eecho "*"
eecho "* Repo conversion complete"
eecho "*"
if GIT merge-base --is-ancestor github/main main
then
eecho "* Resulting repo is a fast-forward"
if ask_yn "Push to GitHub?"; then
eecho "* Pushing"
GIT push github main || fail 10 "Failed to push"
eecho "* Done"
else
eecho "* Not pushing, as requested. Done."
exit 0
fi
else
eecho "* New conversion is not a fast forward; please investigate"
fi
# vim:et:sw=4:sts=4:ts=8