Create a users file (i.e. users.txt
) for mapping SVN users to Git:
user1 = First Last Name <email@address.com>
user2 = First Last Name <email@address.com>
...
You can use this one-liner to build a template from your existing SVN repository:
svn log -q | awk -F '|' '/^r/ {gsub(/ /, "", $2); sub(" $", "", $2); print $2" = "$2" <"$2">"}' | sort -u > users.txt
SVN will stop if it finds a missing SVN user, not in the file. But after that, you can update the file and pick up where you left off.
Now pull the SVN data from the repository:
git svn clone --stdlayout --no-metadata --authors-file=users.txt svn://hostname/path dest_dir-tmp
This command will create a new Git repository in dest_dir-tmp
and start pulling the SVN repository. Note that the "--stdlayout" flag implies you have the common "trunk/, branches/, tags/" SVN layout. If your layout differs, become familiar with --tags
, --branches
, --trunk
options (in general git svn help
).
All common protocols are allowed: svn://
, http://
, https://
. The URL should target the base repository, something like http://svn.mycompany.com/myrepo/repository. The URL string must not include /trunk
, /tag
or /branches
.
Note that after executing this command it very often looks like the operation is "hanging/frozen", and it's quite normal that it can be stuck for a long time after initializing the new repository. Eventually, you will then see log messages which indicate that it's migrating.
Also note that if you omit the --no-metadata
flag, Git will append information about the corresponding SVN revision to the commit message (i.e. git-svn-id: svn://svn.mycompany.com/myrepo/<branchname/trunk>@<RevisionNumber> <Repository UUID>
)
If a user name is not found, update your users.txt
file then:
cd dest_dir-tmp
git svn fetch
You might have to repeat that last command several times, if you have a large project until all of the Subversion commits have been fetched:
git svn fetch
When completed, Git will checkout the SVN trunk
into a new branch. Any other branches are set up as remotes. You can view the other SVN branches with:
git branch -r
If you want to keep other remote branches in your repository, you want to create a local branch for each one manually. (Skip trunk/master.) If you don't do this, the branches won't get cloned in the final step.
git checkout -b local_branch remote_branch
# It's OK if local_branch and remote_branch are the same names
Tags are imported as branches. You have to create a local branch, make a tag and delete the branch to have them as tags in Git. To do it with tag "v1":
git checkout -b tag_v1 remotes/tags/v1
git checkout master
git tag v1 tag_v1
git branch -D tag_v1
Clone your GIT-SVN repository into a clean Git repository:
git clone dest_dir-tmp dest_dir
rm -rf dest_dir-tmp
cd dest_dir
The local branches that you created earlier from remote branches will only have been copied as remote branches into the newly cloned repository. (Skip trunk/master.) For each branch you want to keep:
git checkout -b local_branch origin/remote_branch
Finally, remove the remote from your clean Git repository that points to the now-deleted temporary repository:
git remote rm origin
Best Answer
Trac and Redmine both support integration with Git. It looks more or less exactly the same as the Subversion support. The bug tracker follows one repo as the benevolent dictator repo, it doesn't have to care about all the other clones around the place.
One thing I do think is worth mentioning is that any bug tracker needs to support git branches properly. Working on branches is such an important part of the Git methodology, it needs to be supported in the bug tracker. Redmine can do this through a patch, but last I looked (about a month ago), it wasn't in the main source tree (you could only follow master).
Other useful features would be a graphical representation of how branches are created and merged, similar to how gitk looks. I don't know of any bug tracker that does this kind of visualisation.
EDIT by Corey Trager. I copy/pasted @Squelch's answer here (I upvoted @Squelch too):
Due to the distributed nature of Git against the centralized nature of SVN, it is quite possible for every user or copy of the repository to have different branches. The exisitnig trackers typically have a local copy of the repository that is used as a central reference ("benevolent dictator") that can be regarded as the working copy for all users.
It is quite feasible for users to have a different branch structure in their local copy from that of the tracker. They might choose to keep some private, pull only the branches from the remote that they are interested in, or push a new branch to the remote (tracker). Users can even share branches between themselves that the remote may never see.
The bug tracker can really only reference repositories it has access to. Commonly this is local to the tracker, but it is also possible to pull from repositories remote to the tracker, and far harder to manage. If it is accessing a remote, it can only track branches that it has knowledge of, and there is not really a method of initiating this task apart from a scheduled task. This also assumes that users are serving their local copy too.
As you have already noted, a scheduled task, or an event hook can be used to update the tracker using the commit log for details. These details can then be matched to the tracker issues for viewing as required and noted above.
In short, the tracker will typically see whatever changes are made on the branches it currently has access to. With a hook these changes are seen immediately including the creation of a new branch. It will not see or track changes made to users (offline) repositories until they push those changes.
END OF @Squelch