Open main menu

GIT Migration/Tools script

< GIT Migration
Revision as of 15:17, 7 July 2012 by Lightkey (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This shell script has been used to convert the scummvm-tools repository from Subversion to git.

The section that renames authors has been censored. Modify it as needed.

If you wish to use the script, copy it from "View Source" since some pieces that use the '\' character are formatted incorrectly (e.g. with missing parentheses).

#!/bin/sh

# Script to convert the scummvm-tools repository from subversion to git

# Assumed:
# git svn clone -s https://scummvm.svn.sourceforge.net/svnroot/scummvm/tools/ scummvm-tools-git
# cd scummvm-tools-git

echo =====================
echo copy remote branches
echo =====================

git branch branch-0-10-0                remotes/branch-0-10-0
git branch branch-0-11-0                remotes/branch-0-11-0
git branch branch-0-8-0                 remotes/branch-0-8-0
git branch branch-0-9-0                 remotes/branch-0-9-0
git branch branch-1-1-0                 remotes/branch-1-1-0
git branch branch-1-2-0                 remotes/branch-1-2-0
git branch gsoc2007-decompiler          remotes/gsoc2007-decompiler
git branch gsoc2007-toolsgui            remotes/gsoc2007-toolsgui
git branch gsoc2009-decompiler          remotes/gsoc2009-decompiler
git branch gsoc2009-gui                 remotes/gsoc2009-gui
git branch gsoc2010-decompiler          remotes/gsoc2010-decompiler
git branch tags/branch-0-8-0-base       remotes/tags/branch-0-8-0-base
git branch tags/release-0-10-0          remotes/tags/release-0-10-0
git branch tags/release-0-11-0          remotes/tags/release-0-11-0
git branch tags/release-0-12-0          remotes/tags/release-0-12-0
git branch tags/release-0-13-0          remotes/tags/release-0-13-0
git branch tags/release-0-3-0           remotes/tags/release-0-3-0
git branch tags/release-0-4-0           remotes/tags/release-0-4-0
git branch tags/release-0-4-1           remotes/tags/release-0-4-1
git branch tags/release-0-5-0           remotes/tags/release-0-5-0
git branch tags/release-0-6-0           remotes/tags/release-0-6-0
git branch tags/release-0-6-1           remotes/tags/release-0-6-1
git branch tags/release-0-7-0           remotes/tags/release-0-7-0
git branch tags/release-0-8-0           remotes/tags/release-0-8-0
git branch tags/release-0-9-0           remotes/tags/release-0-9-0
git branch tags/release-1-0-0           remotes/tags/release-1-0-0
git branch tags/release-1-0-0rc1        remotes/tags/release-1-0-0rc1
git branch tags/release-1-0-0rc1@43666  remotes/tags/release-1-0-0rc1@43666
git branch tags/release-1-1-0           remotes/tags/release-1-1-0
git branch tags/release-1-1-1           remotes/tags/release-1-1-1
git branch tags/release-1-2-0           remotes/tags/release-1-2-0
git branch tags/release_030             remotes/tags/release_030

echo =================================================
echo Re-tag in the correct places and remove branches
echo =================================================

git branch -d gsoc2010-decompiler # was merged
git branch -d gsoc2009-gui        # was merged

# function from git-filter-branch.sh to set GIT_* commit env vars
# based on a given commit
set_ident () {
	lid="$(echo "$1" | tr "[A-Z]" "[a-z]")"
	uid="$(echo "$1" | tr "[a-z]" "[A-Z]")"
	pick_id_script='
		/^'$lid' /{
			s/'\''/'\''\\'\'\''/g
			h
			s/^'$lid' \([^<]*\) <[^>]*> .*$/\1/
			s/'\''/'\''\'\'\''/g
			s/.*/GIT_'$uid'_NAME='\''&'\''; export GIT_'$uid'_NAME/p

			g
			s/^'$lid' [^<]* <\([^>]*\)> .*$/\1/
			s/'\''/'\''\'\'\''/g
			s/.*/GIT_'$uid'_EMAIL='\''&'\''; export GIT_'$uid'_EMAIL/p

			g
			s/^'$lid' [^<]* <[^>]*> \(.*\)$/\1/
			s/'\''/'\''\'\'\''/g
			s/.*/GIT_'$uid'_DATE='\''&'\''; export GIT_'$uid'_DATE/p

			q
		}
	'

	LANG=C LC_ALL=C sed -ne "$pick_id_script"
	# Ensure non-empty id name.
	echo "case \"\$GIT_${uid}_NAME\" in \"\") GIT_${uid}_NAME=\"\${GIT_${uid}_EMAIL%%@*}\" && export GIT_${uid}_NAME;; esac"
}

set_commit_env () {
	eval "$(git cat-file commit $1 | set_ident AUTHOR)"
	eval "$(git cat-file commit $1 | set_ident COMMITTER)"
}

set_commit_date () {
	set_commit_env $1
	unset GIT_AUTHOR_NAME
	unset GIT_AUTHOR_EMAIL
	unset GIT_COMMITTER_NAME
	unset GIT_COMMITTER_EMAIL
}

unset_commit_env () {
	unset GIT_AUTHOR_NAME
	unset GIT_AUTHOR_EMAIL
	unset GIT_AUTHOR_DATE
	unset GIT_COMMITTER_NAME
	unset GIT_COMMITTER_EMAIL
	unset GIT_COMMITTER_DATE
}

set_commit_env 0f1c47a
git tag -m "Tag v1.2.0" v1.2.0 5fedf6456b7b8ce2e628c564821e47775dd33590
git branch -D tags/release-1-2-0
git branch -D branch-1-2-0       # empty branch

set_commit_env c18c334
git tag -m "Tag v1.1.1" v1.1.1 c18c3349e461fa51dd884edfbf7310b7c84c090a
git branch -D tags/release-1-1-1

set_commit_env 23181e4
git tag -m "Tag v1.1.0" v1.1.0 23181e4b39906e3cf82413b16eafeed7e44eea0c
git branch -D tags/release-1-1-0

set_commit_env feba424
git tag -m "Tag v1.0.0" v1.0.0 feba424c22aa1acaa07d3c829466ecaeee5b7a60
git branch -D tags/release-1-0-0

set_commit_env 9da1a7a
git tag -m "Tag v1.0.0rc1" v1.0.0rc1 f82a509
git branch -D tags/release-1-0-0rc1
git branch -D tags/release-1-0-0rc1@43666

set_commit_env a5d5876
git tag -m "Tag v0.13.0" v0.13.0 4b64cb8bbbdb9cd1a239418b49bc9291a5ebbbff
git branch -D tags/release-0-13-0
  
set_commit_env 73caf37
git tag -m "Tag v0.12.0" v0.12.0 0e4766ebfc4c2fa04aaa24350a3a75becc871dc2
git branch -D tags/release-0-12-0

set_commit_env a0c2133
git tag -m "Tag v0.11.0" v0.11.0 e44695c2bbebaf199f13e3214a802c946fab44b4
git branch -D tags/release-0-11-0

set_commit_env a10d5d1
git tag -m "Tag v0.10.0" v0.10.0 7b33c6e143bd2d056cb5a1556c60938fc3260cb1
git branch -D tags/release-0-10-0
git branch -D branch-0-10-0 # empty branch

set_commit_env 6f3b71f
git tag -m "Tag v0.9.0" v0.9.0 83ee8b39d48adcd71fcfb69b575dd39e29377d7f
git branch -D tags/release-0-9-0

set_commit_env 0e92a0d
git tag -m "Tag v0.8.0" v0.8.0 0e92a0d760389fdaa08f5bd23c0f5f6b7a14cd80
git branch -D tags/release-0-8-0
git branch -D tags/branch-0-8-0-base

set_commit_env 2ca61c8
git tag -m "Tag v0.7.0" v0.7.0 2ca61c87422b36c2ce1de773502c551451fe172b
git branch -D tags/release-0-7-0

set_commit_env c504a41f39e61c0313675e3332c3e4082a054957
git tag -m "Tag v0.6.1" v0.6.1 c504a41f39e61c0313675e3332c3e4082a054957
git branch -D tags/release-0-6-1

set_commit_env 43c7d16f5ed515c9ea6b51a46a98702bf8bb30ac
git tag -m "Tag v0.6.0" v0.6.0 43c7d16f5ed515c9ea6b51a46a98702bf8bb30ac
git branch -D tags/release-0-6-0

set_commit_env 7e0f1aef93cdc6003e9d3b2f4821e4e2a2a34504
git tag -m "Tag v0.5.0" v0.5.0 7e0f1aef93cdc6003e9d3b2f4821e4e2a2a34504
git branch -D tags/release-0-5-0

set_commit_env 3e62a6e09383bd8ad9890b879910d983c2b55f3a
git tag -m "Tag v0.4.1" v0.4.1 3e62a6e09383bd8ad9890b879910d983c2b55f3a
git branch -D tags/release-0-4-1

set_commit_env 630b8d7411f5cc11cbba387fd11d0551d244a689
git tag -m "Tag v0.4.0" v0.4.0 630b8d7411f5cc11cbba387fd11d0551d244a689
git branch -D tags/release-0-4-0

set_commit_env 47b134b2dd3c1d1e457432d85c356f2cd580ab02
git tag -m "Tag v0.3.0" v0.3.0 47b134b2dd3c1d1e457432d85c356f2cd580ab02
git branch -D tags/release-0-3-0
git branch -D tags/release_030   # tag was renamed

# remove the remote refs
git for-each-ref --format='%(refname)' refs/remotes/ | while read ref; do
    git update-ref -d "$ref"
done

# Remove some unwanted commits

echo ==================================================
echo Remove some bad commits, and edit commit metadata
echo ==================================================

git filter-branch --tag-name-filter cat --commit-filter '
        svn_id=$(git cat-file commit $GIT_COMMIT | fgrep git-svn-id | cut -d@ -f2 | cut -d" " -f 1)
        if [ "$svn_id" = "48503" ]; # This commit is a bad svn tag that adds branch-1-1-0/ to the tree
        then
                skip_commit "$@";
        else
                git commit-tree "$@";
        fi' master..v1.1.0

# remove filter-branch backup
git for-each-ref --format='%(refname)' refs/original/ | while read ref; do
    git update-ref -d "$ref"
done

# rewrite git-svn-id lines
git filter-branch --tag-name-filter cat --msg-filter '
perl -p -e "s/^git-svn-id.*@(\d+) .*$/svn-id: r\1/"' -- --all

# remove filter-branch backup
git for-each-ref --format='%(refname)' refs/original/ | while read ref; do
    git update-ref -d "$ref"
done

# rename authors and remove empty commits.
# Source: http://recursive-design.com/blog/2009/04/29/rename-authors-in-a-git-repository/
git filter-branch --tag-name-filter cat --prune-empty --env-filter '
n=$GIT_AUTHOR_NAME
e=$GIT_AUTHOR_EMAIL

case ${GIT_AUTHOR_NAME} in
	guybrush) n="Guybrush Threepwood" ; e="guybrush@scummvm.org" ;;
	lechuck) n="G.P. LeChuck" ; e="lechuck@scummvm.org" ;;
esac

export GIT_AUTHOR_NAME="$n"
export GIT_AUTHOR_EMAIL="$e"
export GIT_COMMITTER_NAME="$n"
export GIT_COMMITTER_EMAIL="$e"
' -- --all

# remove filter-branch backup
git for-each-ref --format='%(refname)' refs/original/ | while read ref; do
    git update-ref -d "$ref"
done


echo ===================
echo Create new commits
echo ===================

# Create .gitignore based on "git svn show-ignore"
cat << EOF > .gitignore
*.o
.deps

/.gdb_history
/construct_mohawk
/create_sjisfnt
/decine
/decompile
/degob
/dekyra
/deriven
/descumm
/desword2
/extract_mohawk
/gob_loadcalc
/ScummVM Tools.app
/scummvm-tools
/scummvm-tools-cli
/config.mk
/config.h
/config.log

/decompiler/doc/doc.pdf

/decompiler/test/runner
/decompiler/test/runner.cpp
/decompiler/test/*.dSYM
EOF
git add .gitignore
unset_commit_env
git commit -m "Add .gitignore"

# Freeze dead branches.
# Tag using the old timestamp to avoid "gitk --all" getting ugly
for b in \
  branch-0-11-0 \
  branch-0-8-0 \
  branch-0-9-0 \
  branch-1-1-0 \
  gsoc2007-decompiler \
  gsoc2007-toolsgui \
  gsoc2009-decompiler; do
set_commit_date $b
git tag -m "Freeze dead $b branch" dead/$b $b
git branch -D $b
done

echo =====================
echo Remove git-svn cruft
echo =====================
# Source: https://github.com/nothingmuch/git-svn-abandon

# ditch all pre-conversion objects forcefully
git reflog expire --all --expire=now
git gc --aggressive

git prune
git fsck --full