From fc6813194b819262bcb81129b169069c14c4c3e0 Mon Sep 17 00:00:00 2001 From: Colin Guthrie Date: Tue, 30 Jul 2013 00:11:45 +0100 Subject: Add a script to just import Mageia only svn. i.e. for projects where no Mandriva project exists. --- scripts/mageia-import.sh | 221 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100755 scripts/mageia-import.sh 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" -- cgit v1.2.1