master
Marc Wäckerlin 7 years ago
parent 756662ea3a
commit 26490ed06f
  1. 208
      svn-to-git

@ -0,0 +1,208 @@
#!/bin/bash -e
############################################################################ begin logging
# check if stdout is a terminal...
if test -t 1; then
# see if it supports colors...
ncolors=$(tput colors)
if test -n "$ncolors" && test $ncolors -ge 8; then
bold="$(tput bold)"
underline="$(tput smul)"
standout="$(tput smso)"
normal="$(tput sgr0)"
black="$(tput setaf 0)"
red="$(tput setaf 1)"
green="$(tput setaf 2)"
yellow="$(tput setaf 3)"
blue="$(tput setaf 4)"
magenta="$(tput setaf 5)"
cyan="$(tput setaf 6)"
white="$(tput setaf 7)"
fi
fi
append_msg() {
if test $# -ne 0; then
echo -n ": ${bold}$*"
fi
echo "${normal}"
}
# write a message
message() {
if test $# -eq 0; then
return
fi
echo "${bold}${white}$*${normal}" 1>&2
}
# write a success message
success() {
echo -n "${bold}${green}success" 1>&2
append_msg $* 1>&2
}
# write a notice
notice() {
echo -n "${bold}${yellow}notice" 1>&2
append_msg $* 1>&2
}
# write a warning message
warning() {
echo -en "${bold}${red}warning" 1>&2
append_msg $* 1>&2
}
# write error message
error() {
echo -en "${bold}${red}error" 1>&2
append_msg $* 1>&2
}
# run a command, print the result and abort in case of error
# option: --ignore: ignore the result, continue in case of error
run() {
ignore=1
while test $# -gt 0; do
case "$1" in
(--ignore) ignore=0;;
(*) break;;
esac
shift;
done
echo -n "${bold}${yellow}running:${white} $*${normal} … "
set +e
result=$($* 2>&1)
res=$?
set -e
if test $res -ne 0; then
if test $ignore -eq 1; then
error "failed with return code: $res"
if test -n "$result"; then
echo "$result"
fi
exit 1
else
warning "ignored return code: $res"
fi
else
success
fi
}
############################################################################ error handler
function traperror() {
set +x
local err=($1) # error status
local line="$2" # LINENO
local linecallfunc="$3"
local command="$4"
local funcstack="$5"
IFS=" "
for e in ${err[@]}; do
if test -n "$e" -a "$e" != "0"; then
error "line $line - command '$command' exited with status: $e (${err[@]})"
if [ "${funcstack}" != "main" -o "$linecallfunc" != "0" ]; then
echo -n " ... error at ${funcstack} " 1>&2
if [ "$linecallfunc" != "" ]; then
echo -n "called at line $linecallfunc" 1>&2
fi
echo
fi
exit $e
fi
done
success
exit 0
}
# catch errors
trap 'traperror "$? ${PIPESTATUS[@]}" $LINENO $BASH_LINENO "$BASH_COMMAND" "${FUNCNAME[@]}" "${FUNCTION}"' ERR SIGINT INT TERM EXIT
######################################################### commandline parameter evaluation
while test $# -gt 0; do
case "$1" in
(--help|-h) less <<EOF
SYNOPSIS
$0 [OPTIONS]
OPTIONS
--help, -h show this help
DESCRIPTION
EOF
exit;;
(*) error "unknow option $1, try $0 --help"; exit 1;;
esac
if test $# -eq 0; then
error "missing parameter, try $0 --help"; exit 1
fi
shift;
done
##################################################################################### Main
function createusers() {
tmpdir="/tmp/old-svn-${gittarget}"
svn co "$svnurl" "$tmpdir"
cd "$tmpdir"
svn log -q | \
awk -F '|' \
'/^r/ {sub("^ ", "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | \
sort -u > "$users"
cd -
rm -rf "$tmpdir"
}
users=users.txt
options=("--authors-file=$users" "--no-metadata" "--prefix" "" "-s")
svnurl="$1"
giturl="$2"
gittarget="${svnurl##*/}"
if ! test -f "$users"; then
createusers
fi
# migration according to
# https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git
# one-way clone subversion repository
run git svn clone "${options[@]}" "$svnurl" "$gittarget"
cd "$gittarget"
# move the tags to be proper git tags
for t in $(git for-each-ref --format='%(refname:short)' refs/remotes/tags); do
run git tag ${t/tags\//} $t && git branch -D -r $t
done
# move the rest of the references under refs/remotes to be local branches
for b in $(git for-each-ref --format='%(refname:short)' refs/remotes); do
run git branch $b refs/remotes/$b && git branch -D -r $b
done
# remove peg-revisions
for p in $(git for-each-ref --format='%(refname:short)' | grep @); do
run git branch -D $p
done
# remove extra trunk branch
run git branch -d trunk
# add new remote repository
run git remote add origin "$giturl"
run git push origin --all
run git push origin --tags
# checkout fresh git repository
cd -
run rm -rf "$gittarget"
run git clone "$giturl" "$gittarget"
Loading…
Cancel
Save