{"id":182,"date":"2019-02-18T16:25:58","date_gmt":"2019-02-18T16:25:58","guid":{"rendered":"https:\/\/iain.rauch.co.uk\/blog\/?p=182"},"modified":"2019-02-18T16:25:58","modified_gmt":"2019-02-18T16:25:58","slug":"svn-to-git-google-cloud-source-repos","status":"publish","type":"post","link":"https:\/\/iain.rauch.co.uk\/blog\/2019-02\/svn-to-git-google-cloud-source-repos\/","title":{"rendered":"From SVN to Google Cloud Source Repositories"},"content":{"rendered":"\n<p>I have been maintaining my own SVN server for many years, but in order to share code and make use of managed services, it was time to migrate some of my repositories to Git.<\/p>\n\n\n\n<p>There are many tutorials for svn-git migration, here&#8217;s a customised script which works for me: <tt>migrate-svn-to-git.sh<\/tt>. Note, it requires an <tt>authors.txt<\/tt> file &#8211; there any plenty of adequate resources out there for how to create one.<\/p>\n\n\n\n<p>There is nothing specific about this script for Google Source Repos, that is just my choice for private code so it can make use of Google Cloud Build and gcr.io.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>#!\/usr\/bin\/env bash<br><br><\/strong>svnUri=<strong>\"$1\"<br><\/strong>gitUri=<strong>\"$2\"<br><br>if [[ -z \"${svnUri}\" || -z \"${gitUri}\" ]]<\/strong>; <strong>then<br>    <\/strong>echo <strong>\"[ERROR] Usage migrate-svn-to-git.sh &lt;svn_uri> &lt;git_uri>\" <\/strong><em>1>&amp;2<br>    <\/em>exit 1<br><strong>fi<br><br>if [[ <\/strong>! <strong>-f <\/strong>authors.txt<strong> ]]<\/strong>; <strong>then<br>    <\/strong>echo <strong>\"[ERROR] authors.txt is missing\" <\/strong><em>1>&amp;2<br>    <\/em>exit 1<br><strong>fi<br><br><\/strong>echo <strong>\"[INFO] Cloning from SVN: ${svnUri}\"<br><\/strong>git svn --authors-file=authors.txt clone -s <strong>$<\/strong>{svnUri} --prefix svn\/ migration<br>cd migration<br><br>echo <strong>\"[INFO] Creating Git tags\"<br>for <\/strong>t <strong>in $<\/strong>(git for-each-ref --format=<strong>'%(refname:short)' <\/strong>refs\/remotes\/svn\/tags); <strong>do <\/strong>git tag <strong>$<\/strong>(echo <strong>$<\/strong>{t} | sed <strong>'s^svn\/tags\/^^'<\/strong>) <strong>$<\/strong>{t} <strong>&amp;&amp; <\/strong>git branch -D -r <strong>$<\/strong>{t}; <strong>done<br><\/strong>echo <strong>\"[INFO] Creating Git branches\"<br>for <\/strong>b <strong>in $<\/strong>(git for-each-ref --format=<strong>'%(refname:short)' <\/strong>refs\/remotes\/svn | grep -v trunk); <strong>do <\/strong>git branch <strong>$<\/strong>(echo <strong>$<\/strong>{b} | sed <strong>'s^svn\/^^'<\/strong>) refs\/remotes\/<strong>$<\/strong>{b} <strong>&amp;&amp; <\/strong>git branch -D -r <strong>$<\/strong>{b}; <strong>done<br><br><\/strong>echo <strong>\"[INFO] Creating .gitignore file\"<br><\/strong>git svn show-ignore <em>> .gitignore<br><\/em>git add .gitignore<br>git commit -m <strong>\"Added .gitignore\"<br><br><\/strong>echo <strong>\"[INFO] Pushing to Git: ${gitUri}\"<br><\/strong>git remote add google <strong>$<\/strong>{gitUri}<br>git push --force google --tags<br>git push --force google --all<br><br>cd -<br><br>echo <strong>\"[INFO] Removing migration directory\"<br><\/strong>rm -rf migration<\/pre>\n\n\n\n<p>Once you have created the Git repo, you need to switch your working copy of a project from SVN to Git. Here&#8217;s a script: <tt>switch-svn-to-git.sh<\/tt><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>#!\/usr\/bin\/env bash<\/strong><br><em><br><\/em>gitUri=<strong>\"$1\"<br><br>if [[ -z \"${gitUri}\" ]]<\/strong>; <strong>then<br>    <\/strong>echo <strong>\"[ERROR] Usage switch-svn-to-git.sh &lt;git_uri>\" <\/strong><em>1>&amp;2<br>    <\/em>exit 1<br><strong>fi<br><br>if [[ <\/strong>! <strong>-d <\/strong>.svn<strong> ]]<\/strong>; <strong>then<br>    <\/strong>echo <strong>\"[ERROR] Not a SVN project\" <\/strong><em>1>&amp;2<br>    <\/em>exit 1<br><strong>fi<br><br><\/strong>echo <strong>\"[INFO] Finding current branch\"<br><\/strong>svnBranch=<strong>$<\/strong>(svn info | grep <strong>'^URL:' <\/strong>| egrep -o <strong>'(tags|branches)\/[^\/]+|trunk' <\/strong>| egrep -o <strong>'[^\/]+$'<\/strong>)<br>echo <strong>\"[DEBUG] ${svnBranch}\"<br><br><\/strong>echo <strong>\"[INFO] Cleaning SVN directory\"<br><\/strong>rm -rf .svn<br><br>echo <strong>\"[INFO] Initialising Git from: ${gitUri}\"<br><\/strong>git init<br>git remote add origin <strong>$<\/strong>{gitUri}<br>git fetch<br><br>echo <strong>\"[INFO] Saving working copy\"<br><\/strong>git show origin\/master:.gitignore <em>> .gitignore<br><\/em>git checkout -b tmp<br>git add .<br>git commit -m <strong>\"local changes\"<br><br><\/strong>echo <strong>\"[INFO] Checking out branch\"<br><\/strong>gitBranch=<strong>\"master\"<br>if [[ $<\/strong>{svnBranch} <strong>!= \"trunk\" ]]<\/strong>; <strong>then<br>    <\/strong>gitBranch=<strong>\"${svnBranch}\"<br>fi<br><\/strong>git checkout <strong>$<\/strong>{gitBranch}<br><br>echo <strong>\"[INFO] Merging working copy\"<br><\/strong>git merge --allow-unrelated-histories -X theirs --squash tmp<br>git branch --delete --force tmp<br><br>echo <strong>\"[INFO] Deleting IntelliJ reference to SVN (if exists)\"<br><\/strong>test -f .idea\/vcs.xml <strong>&amp;&amp; <\/strong>rm .idea\/vcs.xml<br><br>echo <strong>\"[INFO] Done - you may want to set your name \/ email with: git config user.email &lt;email>\"<\/strong><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>I have been maintaining my own SVN server for many years, but in order to share code and make use of managed services, it was time to migrate some of my repositories to Git. There are many tutorials for svn-git &hellip; <a href=\"https:\/\/iain.rauch.co.uk\/blog\/2019-02\/svn-to-git-google-cloud-source-repos\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[8,5,4],"tags":[],"class_list":["post-182","post","type-post","status-publish","format-standard","hentry","category-development","category-linux","category-mac-os-x"],"_links":{"self":[{"href":"https:\/\/iain.rauch.co.uk\/blog\/wp-json\/wp\/v2\/posts\/182","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/iain.rauch.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/iain.rauch.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/iain.rauch.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/iain.rauch.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=182"}],"version-history":[{"count":2,"href":"https:\/\/iain.rauch.co.uk\/blog\/wp-json\/wp\/v2\/posts\/182\/revisions"}],"predecessor-version":[{"id":184,"href":"https:\/\/iain.rauch.co.uk\/blog\/wp-json\/wp\/v2\/posts\/182\/revisions\/184"}],"wp:attachment":[{"href":"https:\/\/iain.rauch.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=182"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/iain.rauch.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=182"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/iain.rauch.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=182"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}