.\" Man page generated from reStructuredText.
.
.TH SVN2GIT  "1" "08/04/2016" "svn2git  2\&.3\&.2"
.SH "NAME"
svn2git \- migrates from svn to git
.SH DESCRIPTION
svn2git \- is a tiny utility for migrating projects from Subversion to Git
while keeping the trunk, branches and tags where they should be. It uses
git\-svn to clone an svn repository and does some clean\-up to make sure
branches and tags are imported in a meaningful way, and that the code checked
into master ends up being what\(aqs currently in your svn trunk rather than
whichever svn branch your last commit was in.
.SH SYNOPSIS
\fIsvn2git\fR [\-h|\-\-help] [\-\-rebase] [\-m|\-\-metadata] [\-v|\-\-verbose]
        [\-\-rootistrunk][\-\-notrunk][\-\-nobranches]
        [\-\-authors AUTHORS_FILE]
        [\-\-exclude REGEX]
        [\-\-branches BRANCHES_PATH]
        [\-\-notags][\-\-no\-minimize]
        [\-\-rebasebranch REBASEBRANCH]
        [\-\-revision START_REV:[END_REV]]
        [\-\-trunk TRUNK_PATH]
        [\-\-username NAME]
        [\-\-password PASS]
.SH OPTIONS REFERENCE
.TP
.B \-\-rebase
Instead of cloning a new project, rebase an existing one against SVN
.TP
.BI \-\-username \ NAME
Username for transports that needs it (http(s), svn)
.TP
.BI \-\-password \ PASS
Username for transports that needs it (http(s), svn)ssword for transports that needs it (http(s), svn)
.TP
.BI \-\-trunk \ TRUNK_PATH
Subpath to trunk from repository URL (default: trunk)
.TP
.BI \-\-branches \ BRANCHES_PATH
Subpath to branches from repository URL (default: branches); can be used multiple times
.TP
.BI \-\-tags \ TAGS_PATH
Subpath to tags from repository URL (default: tags); can be used multiple times
.TP
.B \-\-rootistrunk
Use this if the root level of the repo is equivalent to the trunk and there are
no tags or branches
.TP
.B \-\-notrunk
Do not import anything from trunk
.TP
.B \-\-nobranches
Do not try to import any branches
.TP
.B \-\-notags
Do not try to import any tags
.TP
.B \-\-no\-minimize\-url
Accept URLs as\-is without attempting to connect to a higher level directory
.TP
.B \-\-revision START_REV[:END_REV]
Start importing from SVN revision START_REV; optionally end at END_REV
.TP
.B \-m\fP,\fB  \-\-metadata
Include metadata in git logs (git\-svn\-id)
.TP
.B \-\-authors AUTHORS_FILE
Path to file containing svn\-to\-git authors mapping (default:
~/.svn2git/authors)
.TP
.B \-\-exclude REGEX
Specify a Perl regular expression to filter paths when fetching; can be used
multiple times
.TP
.B \-v\fP,\fB  \-\-verbose
Be verbose in logging \-\- useful for debugging issues
.TP
.B \-h\fP,\fB  \-\-help
Show this message
.SH EXAMPLES
For instance this could be a situation in a svn repository:
.TP
.B trunk
\&...
.TP
.B branches 
\1.x
\2.x
.TP
.B tags
\1.0.0
\1.0.1
\1.0.2
\1.1.0
\2.0.0
.PP
git\-svn will go through the commit history to build a new git repo. It will \
import all branches and tags as remote svn branches, whereas what you really \
want is git\-native local branches and git tag objects. So after importing this \
project you\(aqll get:
.IP
.nf
.B $ git branch
\ * master
.IP
.B $ git branch \-a
\ * master
\ 1.x
\ 2.x
\ tags/1.0.0
\ tags/1.0.1
\ tags/1.0.2
\ tags/1.1.0
\ tags/2.0.0
\ trunk

.B $ git tag \-l
\ [ empty ]
.fi
.PP
After svn2git is done with your project, you\(aqll get this instead:
.IP
.nf
.B $ git branch
\ * master
\ 1.x
\ 2.x

.B $ git tag \-l
\ 1.0.0
\ 1.0.1
\ 1.0.2
\ 1.1.0
\ 2.0.0
.fi
.PP
Finally, it makes sure the HEAD of master is the same as the current trunk of
the svn repo.
.SH INSTALLATION
Make sure you have git, git\-svn, and ruby installed. svn2git is a ruby wrapper
around git\(aqs native SVN support through git\-svn.  It is possible to have
git installed without git\-svn installed, so please do verify that you can run
\fI$ git svn\fP successfully.  For a Debian\-based system, the installation of
the prerequisites would look like:
.sp
\  $ sudo apt\-get install git\-core git\-svn ruby rubygems
.sp
Once you have the necessary software on your system, you can install svn2git
through rubygems, which will add the \fIsvn2git\fP command to your PATH.
.sp
\  $ sudo gem install svn2git
.SH USAGE
There are several ways you can create a git repo from an existing svn repo. The
differentiating factor is the svn repo layout. Below is an enumerated listing
of the varying supported layouts and the proper way to create a git repo from a
svn repo in the specified layout.
.sp
.nf
.IP 1. 3
The svn repo is in the standard layout of (trunk, branches, tags) at the root
level of the repo.
.sp
\  $ svn2git \fI\%http://svn.example.com/path/to/repo\fP
.sp
.IP 2. 3
The svn repo is NOT in standard layout and has only a trunk and tags at the
root level of the repo.
.sp
\  $ svn2git \fI\%http://svn.example.com/path/to/repo\fP \-\-trunk dev \\
    \-\-tags rel \-\-nobranches
.sp
.IP 3. 3
The svn repo is NOT in standard layout and has only a trunk at the root level
of the repo.
.sp
\  $ svn2git \fI\%http://svn.example.com/path/to/repo\fP \-\-trunk trunk \\
    \-\-nobranches \-\-notags
.sp
.IP 4. 3
The svn repo is NOT in standard layout and has no trunk, branches, or tags at
the root level of the repo. Instead the root level of the repo is equivalent to
the trunk and there are no tags or branches.
.sp
\  $ svn2git \fI\%http://svn.example.com/path/to/repo\fP \-\-rootistrunk
.sp
.IP 5. 3
The svn repo is in the standard layout but you want to exclude the massive doc
directory and the backup files you once accidentally added.
.sp
\  $ svn2git \fI\%http://svn.example.com/path/to/repo\fP \-\-exclude doc \\
    \-\-exclude \(aq.*~$\(aq
.sp
.IP 6. 3
The svn repo actually tracks several projects and you only want to migrate one
of them.
.sp
\  $ svn2git \fI\%http://svn.example.com/path/to/repo/nested_project\fP \\
    \-\-no\-minimize\-url
.sp
If the svn repo is password protected.
.sp
\  $ svn2git \fI\%http://svn.example.com/path/to/repo\fP \\
    \-\-username <<user_with_perms>>
.sp
You need to migrate starting at a specific svn revision number.
.sp
\  $ svn2git \fI\%http://svn.example.com/path/to/repo\fP \\
    \-\-revision <<starting_revision_number>>
.sp
You need to migrate starting at a specific svn revision number, ending at a
specific revision number.
.sp
\  $ svn2git \fI\%http://svn.example.com/path/to/repo\fP \-\-revision \\
  <<starting_revision_number>>:<<ending_revision_number>>
.sp
Include metadata (git\-svn\-id) in git logs.
.sp
\  $ svn2git \fI\%http://svn.example.com/path/to/repo\fP \-\-metadata
.sp
The above will create a git repository in the current directory with the git
version of the svn repository. Hence, you need to make a directory that you
want your new git repo to exist in, change into it and then run one of the
above commands. Note that in the above cases the trunk, branches, tags options
are simply folder names relative to the provided repo path. For example if you
specified trunk=foo branches=bar and tags=foobar it would be referencing
\fI\%http://svn.example.com/path/to/repo/foo\fP as your trunk, and so on.
However, in case 4 it references the root of the repo as trunk.
.sp
As of svn2git 2.0 there is a new feature to pull in the latest changes from SVN
into your git repository created with svn2git.  This is a one way sync, but
allows you to use svn2git as a mirroring tool for your SVN repositories.
.sp
The command to call is:
.sp
  $ cd <EXISTING_REPO> && svn2git \-\-rebase
.fi
.SH AUTHORS
To convert all your svn authors to git format, create a file somewhere on your
system with the list of conversions to make, one per line, for example:

  jcoglan = James Coglan <\fI\%jcoglan@never\-you\-mind.com\fP>
  stnick = Santa Claus <\fI\%nicholas@lapland.com\fP>
.sp
Then pass an _authors_ option to svn2git pointing to your file:
.sp
  $ svn2git \fI\%http://svn.example.com/path/to/repo\fP \\
    \-\-authors ~/authors.txt
.sp
Alternatively, you can place the authors file into \fI~/.svn2git/authors\fP and
svn2git will load it out of there. This allows you to build up one authors file
for all your projects and have it loaded for each repository that you migrate.
.sp
If you need a jump start on figuring out what users made changes in your svn
repositories the following command sequence might help. It grabs all the logs
from the svn repository, pulls out all the names from the commits, sorts them,
and then reduces the list to only unique names. So, in the end it outputs a
list of usernames of the people that made commits to the svn repository which
name on its own line. This would allow you to easily redirect the output of
this command sequence to \fI~/.svn2git/authors\fP and have a very good starting
point for your mapping.
.sp
  $ svn log \-\-quiet | grep \-E "r[0\-9]+ | .+ |" \\
    | cut \-d\(aq|\(aq \-f2 | sed \(aqs/^ //\(aq | sort | uniq
.sp
Or, for a remote URL:

  $ svn log \-\-quiet \fI\%http://path/to/root/of/project\fP \\
    | grep \-E "r[0\-9]+ | .+ |" | cut \-d\(aq|\(aq \-f2 \\
    | sed \(aqs/^ //\(aq | sort | uniq
.SH DEBUGGING
If you\(aqre having problems with converting your repository and you\(aqre not
sure why, try turning on verbose logging.  This will print out more information
from the underlying git\-svn process.
.sp
You can turn on verbose logging with the \fI\-v\fP or \fI\-\-verbose\fP flags,
like so:
.sp
  $ svn2git \fI\%http://svn.yoursite.com/path/to/repo\fP \-\-verbose
.SH FAQ
.IP 1. 3
Why don\(aqt the tags show up in the master branch?
The tags won\(aqt show up in the master branch because the tags are actually
tied to the commits that were created in svn when the user made the tag.
Those commits are the first (head) commit of branch in svn that is
associated with that tag. If you want to see all the branches and tags
and their relationships in gitk you can run the following: gitk \-\-all
.sp
For further details please refer to FAQ #2.
.sp
.IP 2. 3
Why don\(aqt you reference the parent of the tag commits instead?
In svn you are forced to create what are known in git as annotated tags.
It just so happens that svn annotated tags allow you to commit change
sets along with the tagging action. This means that the svn annotated tag
is a bit more complex then just an annotated tag it is a commit which is
treated as an annotated tag. Hence, for there to be a true 1\-to\-1 mapping
between git and svn we have to transfer over the svn commit which acts as
an annotated tag and then tag that commit in git using an annotated tag.
.sp
If we were to reference the parent of this svn tagged commit there could
potentially be situations where a developer would checkout a tag in git
and the resulting code base would be different than if they checked out
that very same tag in the original svn repo. This is only due to the fact
that the svn tags allow changesets in them, making them not just annotated
tags.