Skip to content

Instantly share code, notes, and snippets.

@JeffJacobson
Last active February 3, 2021 00:38
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save JeffJacobson/e5703e3d3d923d706af1affedbb82cff to your computer and use it in GitHub Desktop.
One-way clone from SVN to Git

PowerShell Scripts for migrating from Subversion to Git

Automates some of the process described here.

How to use

  1. Copy the PowerShell scripts into a new folder.

  2. Open PowerShell command window and change to the directory created in the previous step.

  3. Create a variable containing the URL of the SVN repository. (This just saves you from needing to retype it multiple times.)

    [uri]$url = "http://example.com/svn/OIT/GIS/myrepo/trunk"
  4. Run the Get-SvnUsers.ps1 script

    .\Get-SvnUsers.ps1 $url "email.example.com" | out-file -encoding ascii users.txt
  5. Edit the user names and email addresses for accuracy. Only edit text to the right of the equals signs. Note the same user name with different casing may appear in the list. You must leave these duplicate entries in the list but should give them both the same name and email address.

    Before

    PubliJo = PubliJo <PubliJo@email.example.com>
    publijo = publijo <publijo@email.example.com>
    

    After

    PubliJo = John Q. Public <john.q.public@email.example.com>
    publijo = John Q. Public <john.q.public@email.example.com>
    
  6. Run the Clone-SvnToGit.ps1 script

    .\Clone-SvnToGit.ps1 $url users.txt

    This will clone the SVN repository into a new Git repository folder. This process will take several minutes.

  7. Examine the Git repository folder to make sure the expected code files are present.

  8. Move the new Git repository folder to a new location (optional).

  9. Create a new, empty repository on remote server (e.g., TFS or GitHub). Do not have the server auto-generate any files such as .gitignore or README.md.

  10. Set the Git repository on your computer to use the remote repository

    git remote add origin http://git.example.com/my-reopsitory
  11. Push to the remote repository

    git push --mirror

    or

    git push origin --all
    git push origin --tags
<#
.SYNOPSIS
Clones an Subversion repository into a Git repository.
.DESCRIPTION
Clones a Subversion repository into a Git repository, for migrating from Subversion to Git.
This is a scripted version of the processed outlined here:
http://web.archive.org/web/20161107131841/https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git
.EXAMPLE
PS C:\> .\Clone-SvnToGit.ps1 https://example.com/path/to/svn/myrepo/trunk users.txt
This will clone the SVN repository at the given URL into a git repository folder called "myrepo",
maintaining the history from the SVN repository. The user info from SVN log will be mapped to git users
using the users.txt file.
.INPUTS
1. SvnTrunkUrl - Subversion repository URL.
2. AuthorsFile - A text file containing list of users. The text should be in the format specified below, with
each user appearing on a new line.
svnusername = Git User Name <useremail@example.com>
johnqpublic = John Q. Public <johnqpublic@example.com>
John Doe = John Doe <john.doe@example.net>
.NOTES
Based on http://web.archive.org/web/20161107131841/https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git
#>
#Requires -RunAsAdministrator
param (
[parameter(Mandatory=$true, HelpMessage="URL to the Subversion repository's trunk")] [Uri] $SvnTrunkUrl,
[parameter(Mandatory=$true, HelpMessage="Text file mapping SVN user names to Git user names")] [System.IO.FileInfo] $AuthorsFile
)
# See http://web.archive.org/web/20161107131841/https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git
$out_name = Split-Path $SvnTrunkUrl.LocalPath -Leaf
Write-Output "Copying SVN $SvnTrunkUrl to Git: $out_name"
# Set the current directory to the location of this script file.
$startLocation = Get-Location
try
{
Write-Information "Cloning SVN repository..."
git svn clone $SvnTrunkUrl --authors-file=$AuthorsFile --no-metadata -s $out_name
# Change directory to git
Set-Location $out_name
# Move remote branches to local branches/tags
Copy-Item -Recurse -Force .git/refs/remotes/origin/tags/* .git/refs/tags/
Remove-Item -Recurse -Force .git/refs/remotes/origin/tags
Copy-Item -Recurse -Force .git/refs/remotes/origin/* .git/refs/heads/
Remove-Item -Recurse -Force .git/refs/remotes/origin
# This process results in an extra branch called "trunk". It can be deleted.
git branch -d trunk
}
finally
{
Set-Location $startLocation
}
<#
.SYNOPSIS
Lists users from SVN repository's log
.DESCRIPTION
Generates a mapping of SVN users to Git users for use with Clone-SvnToGit.ps1 script.
For output format example, see https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git
.EXAMPLE
PS C:\> .\Get-SvnUsers http://example.com/svn/myrepo/trunk | out-file -encoding ascii users.txt
Gets a list of users from the SVN repository and then redirects the scripts output to a file called users.txt.
.INPUTS
URL to subversion repository.
.OUTPUTS
List of users.
.NOTES
See https://git-scm.com/book/en/v2/Git-and-Other-Systems-Migrating-to-Git
#>
param(
[parameter(Mandatory=$true,HelpMessage="Subversion repository URL")] [Uri] $SvnUrl,
[parameter(HelpMessage="Email server to use when converting SVN usernames to email addresses.")] [string] $EmailServer = "users.noreply.github.com"
)
$xmlFile = New-TemporaryFile
try {
svn log $SvnUrl --xml > $xmlFile
$users = $xmlFile | Select-Xml -XPath "//author" | Select-Object -ExpandProperty "node" | Select-Object -ExpandProperty "#text" -Unique | Sort-Object
foreach ($user in $users) {
$emailName = Split-Path $user -Leaf
[string]$line = $user + " = " + $emailName + " <" + $emailName + "@" + $EmailServer + ">"
Write-Output $line
}
} finally {
Remove-Item $xmlFile
}
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment