summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Guthrie <colin@mageia.org>2013-07-30 00:11:45 +0100
committerColin Guthrie <colin@mageia.org>2013-07-30 00:11:45 +0100
commitfc6813194b819262bcb81129b169069c14c4c3e0 (patch)
tree50c697aef4df8ead7083af675ed00b0346bcdbe3
parent5a128469347a9383476fc2bb9263b3f71332e31d (diff)
downloadsvn-git-migration-fc6813194b819262bcb81129b169069c14c4c3e0.tar
svn-git-migration-fc6813194b819262bcb81129b169069c14c4c3e0.tar.gz
svn-git-migration-fc6813194b819262bcb81129b169069c14c4c3e0.tar.bz2
svn-git-migration-fc6813194b819262bcb81129b169069c14c4c3e0.tar.xz
svn-git-migration-fc6813194b819262bcb81129b169069c14c4c3e0.zip
Add a script to just import Mageia only svn.
i.e. for projects where no Mandriva project exists.
-rwxr-xr-xscripts/mageia-import.sh221
1 files changed, 221 insertions, 0 deletions
diff --git a/scripts/mageia-import.sh b/scripts/mageia-import.sh
new file mode 100755
index 0000000..26c4301
--- /dev/null
+++ b/scripts/mageia-import.sh
@@ -0,0 +1,221 @@
+#!/bin/bash
+
+NEWSVNURL="file:///home/colin/svn-git/soft"
+NEWSVNUUID=$(svn info $NEWSVNURL | grep "^Repository UUID: " | cut -d' ' -f3)
+
+SOFTWARE=$1
+if [ -z $SOFTWARE ]; then
+ echo "Missing software to convert..."
+ exit 1
+fi
+
+if [ -d $SOFTWARE-origin ]; then
+ echo "It seems the svn-git repository already exists ($SOFTWARE-origin)"
+ exit 1
+fi
+
+if [ -d $SOFTWARE.git ]; then
+ echo "It seems the converted git repository already exists ($SOFTWARE.git)"
+ exit 1
+fi
+
+skiprevisions=
+skiprevisionsx="$2"
+if [ -n "$skiprevisionsx" ]; then
+ for rev in $skiprevisionsx; do
+ rev=$(echo $rev | sed 's/r//g')
+ rev=$(( $rev + 0 ))
+ if [ $rev -gt 0 ]; then
+ skiprevisions="$skiprevisions $rev"
+ fi
+ done
+fi
+
+echo "Identified software name: $SOFTWARE"
+echo "SVN Revisions to skip: $skiprevisions"
+echo
+
+git svn init $NEWSVNURL/$SOFTWARE --no-metadata --stdlayout $SOFTWARE-origin
+cd $SOFTWARE-origin
+revision=0
+if [ -n "$skiprevisions" ]; then
+ for rev in $skiprevisions; do
+ git svn fetch -A ../authors-transform.txt -r $(( $revision + 1 )):$(( $rev - 1 ))
+ revision=$rev
+ done
+fi
+git svn fetch -A ../authors-transform.txt -r $(( $revision + 1 )):HEAD
+git reset --hard trunk
+echo
+echo "done"
+
+
+echo
+echo "Now creating bare git repository"
+git init --bare ../$SOFTWARE.git
+git remote rm origin
+git remote add origin ../$SOFTWARE.git
+#git push --set-upstream master
+git push origin master 'refs/remotes/*:refs/heads/*'
+
+pushd ../$SOFTWARE.git
+git branch -D trunk
+git branch -D origin/master 2>/dev/null
+
+# Tagging logic inspired by https://github.com/nothingmuch/git-svn-abandon/blob/master/git-svn-abandon-fix-refs
+# Keep a map of tags and their original sha1 for the SQL database cerated below
+declare -A tagmap
+tags=$(git for-each-ref --format='%(refname)' refs/heads/tags | cut -d / -f 4)
+for tag in $tags; do
+ ref="refs/heads/tags/$tag"
+ refsha1=$(git rev-parse "$ref")
+ reftreesha1=$(git rev-parse "$ref":)
+
+ # Find the oldest ancestor for which the tree is the same
+ parentref="$ref"
+ while [ $(git rev-parse --quiet --verify "$parentref"^:) = "$reftreesha1" ]; do
+ parentref="$parentref"^
+ done
+ parent=$(git rev-parse "$parentref")
+
+ # If this ancestor is in master then we can just tag it
+ # otherwise the tag has diverged from master and it's actually more like a
+ # branch than a tag
+ merge=$(git merge-base master $parent)
+ if [ "$merge" = "$parent" ]; then
+ targetref=$parent
+ else
+ targetref=$refsha1
+ fi
+
+ tagmap[$refsha1]=$tag
+
+ # create an annotated tag based on the last commit in the tag, and delete the "branchy" ref for the tag
+ git show -s --pretty='format:%s%n%n%b' "$ref" | \
+ env GIT_COMMITTER_NAME="$(git show -s --pretty='format:%an' "$ref")" \
+ GIT_COMMITTER_EMAIL="$(git show -s --pretty='format:%ae' "$ref")" \
+ GIT_COMMITTER_DATE="$(git show -s --pretty='format:%ad' "$ref")" \
+ GIT_AUTHOR_NAME="$(git show -s --pretty='format:%an' "$ref")" \
+ GIT_AUTHOR_EMAIL="$(git show -s --pretty='format:%ae' "$ref")" \
+ GIT_AUTHOR_DATE="$(git show -s --pretty='format:%ad' "$ref")" \
+ git tag -a -F - "$tag" "$targetref"
+
+ git update-ref -d "$ref"
+done
+
+# Implement a branch name policy
+# 1. Branches matching ([1-3]) are renamed to distro/mga\1
+# 2. Branches matching (20[0-9\.]+) are renamed to distro/mdv\1
+# 3. Branches matching (mes[0-9].*) are renamed to distro/\1
+# 4. All other branches are renamed to topic/\1 (excl. master)
+
+branches=$(git for-each-ref --format='%(refname)' refs/heads | cut -d / -f 3-)
+for branch in $branches; do
+ ref="refs/heads/$branch"
+ refsha1=$(git rev-parse "$ref")
+ reftreesha1=$(git rev-parse "$ref":)
+
+ # Find the oldest ancestor for which the tree is the same
+ parentref="$ref"
+ while [ $(git rev-parse --quiet --verify "$parentref"^:) = "$reftreesha1" ]; do
+ parentref="$parentref"^
+ done
+ parent=$(git rev-parse "$parentref")
+
+ # If this ancestor is in master then we can just squash it
+ # otherwise the branch has diverged from master and it's actually a proper
+ # branch
+ merge=$(git merge-base master $parent)
+ if [ "$merge" = "$parent" ]; then
+ git update-ref "$ref" $parent $refsha1
+ fi
+
+ if (echo $branch | grep -qE '^[0-3]$'); then
+ git branch -m $branch distro/mga$branch
+ elif (echo $branch | grep -qE '^20[0-9\.]+$'); then
+ git branch -m $branch distro/mdv$branch
+ elif (echo $branch | grep -qE '^mes[0-9].*$'); then
+ git branch -m $branch distro/$branch
+ elif [ "$branch" != "master" ]; then
+ git branch -m $branch topic/$branch
+ fi
+done
+
+git gc --aggressive
+popd
+
+
+# And finally we create some SQL for creating a nice revision map database
+
+# CREATE TABLE refs (distro char(3) NOT NULL, soft varchar(255) NOT NULL, revision int(10) unsigned NOT NULL, sha1 char(40) NOT NULL, head varchar(255) NOT NULL);
+
+# Parse a git-svn revmap file into SQL
+# $1 = Name of revmap file
+# $2 = Distro ('mdv' or 'mga')
+# $3 = head name i.e. branch or tag name (only used when not processing trunk/master)
+# $4 = Special SHA1 (last sha1 to look for if 'mdv', fake sha1 commit if 'mga')
+parsesvnrevmap()
+{
+ if [ ! -f "$1" ]; then
+ echo "No such file '$1'" >&2
+ exit 1
+ fi
+ for map in $(cat "$1" | xxd -c24 -g24 | cut -b 10-57); do
+ sha1=$(echo $map | cut -b 9-)
+ if [ "$sha1" = "0000000000000000000000000000000000000000" ]; then
+ continue
+ fi
+ if [ -n "$4" -a "$2" = "mga" -a "$sha1" = "$4" ]; then
+ continue
+ fi
+ rev=$(printf "%d" 0x$(echo $map | cut -b 1-8))
+
+ if [ -n "${tagmap[$sha1]}" ]; then
+ echo "INSERT INTO refs VALUES('$2', '$SOFTWARE', $rev, '', '${tagmap[$sha1]}');"
+ else
+ branch=$3
+ if [ -n "$branch" ]; then
+ if (echo $branch | grep -qE '^[0-3]$'); then
+ branch=distro/mga$branch
+ elif (echo $branch | grep -qE '^20[0-9\.]+$'); then
+ branch=distro/mdv$branch
+ elif (echo $branch | grep -qE '^mes[0-9].*$'); then
+ branch=distro/$branch
+ elif [ "$branch" != "master" ]; then
+ branch=topic/$branch
+ fi
+ fi
+ echo "INSERT INTO refs VALUES('$2', '$SOFTWARE', $rev, '$sha1', '$branch');"
+ fi
+
+ # Exit if we've reached our reset sha1 as any future revisions are not used
+ # by Mageia
+ if [ -n "$4" -a "$2" = "mdv" -a "$sha1" = "$4" ]; then
+ break
+ fi
+ done
+}
+
+echo
+echo -n "Creating revision -> sha1 map SQL... "
+
+sql="../$SOFTWARE-revmap.sql"
+rm -f "$sql" "$sql".xz
+
+# Mageia commits
+revmap=".git/svn/refs/remotes/trunk/.rev_map.$NEWSVNUUID"
+if [ -f "$revmap" ]; then
+ parsesvnrevmap "$revmap" "mga" "" $fakesha1 >>"$sql"
+fi
+for revmap in $(find .git/svn/refs/remotes/tags -name .rev_map.$NEWSVNUUID 2>/dev/null); do
+ # Note, still pass in the tag name in case the tag is really more of a branch...
+ parsesvnrevmap "$revmap" "mga" "$(echo $revmap | cut -d'/' -f6)" >>"$sql"
+done
+for revmap in $(find .git/svn/refs/remotes -maxdepth 2 -not -iwholename ".git/svn/refs/remotes/trunk/.rev_map.*" -name .rev_map.$NEWSVNUUID 2>/dev/null); do
+ parsesvnrevmap "$revmap" "mga" "$(echo $revmap | cut -d'/' -f5)" >>"$sql"
+done
+
+xz "$sql"
+
+cd ..
+echo "done"