Reconciling cat and dog - the most productive git-svn
setup
I would like to present productive and effective setup for the git-svn
bridge which removes most of the obstacles and fixes some problems which occur with this bridged approach.
Configuration
Before we start - one remark: if you installed git
on your machine first time ever, please remember about setting up proper user, email and one-more-thing just for convinience:
Starting
At first, you need to clone
(or checkout
in SVN terminology) repository. You can do in three different ways:
- First way (2nd line) checkouts repository with a standard SVN layout (
trunk
,branches
,tags
) and associates branches, tags andtrunk
withgit
master
. - Second way (5th line) checkouts whole repository as it is.
- Third way (starts in 8th line) is really an expansion for
git-svn clone
.
1
2
3
4
5
6
7
8
9
10
11
# Standard layout.
~ $ git svn clone -s $SVN_REPOSITORY_ROOT_URL
# Non-standard layout.
~ $ git svn clone $SVN_REPOSITORY_ROOT_URL
# 'git svn clone ...' is basically a shortcut for these commands:
~ $ mkdir REPOSITORY
~ $ cd REPOSITORY
~ $ git svn init $SVN_REPOSITORY_TRUNK_URL .
~ $ git svn fetch -r HEAD
Updating and commiting
Besides pull
and push
(or update
and commit
in SVN terminology) everything works like in classical git
.
First line represents svn update
command, second - series of svn commit
commands with messages collected inside local git
repository.
1
2
~ $ git svn rebase
~ $ git svn dcommit
Ignores
If you cannot store your .gitignore
file in the SVN repository you can exclude these files locally:
But .gitignore
file can be very convenient - you can easily share exclusions with other members of the team which also use this bridged approach. Moreover, this command is really slow for bigger repositories, so that is another advantage of having this file.
Branches
If your repository does not have standard layout you can still easily associate SVN branch in your .git/config
by adding new svn-remote
section:
Then you should run (and develop the habit of running):
As the last step, you need to checkout
new branch:
After that your branch will be available like normal git
branch. Remember that your trunk
is actually a git
master
branch.
Removing empty directories
Regarding the git-svn
bridge, dangling empty directories are my nightmare. Fortunately, someone thought about it and we can enable deleting empty directories on commit (globally via git-config
or on demand just for certain commit):
Problems
There are still a few problems with the newest SVN clients for such combination. The most annoying is assertion … failed related to the renaming operation. This error looks like this example:
At first glance you may think that the only (and the worst possible - lost information and mess in history) option is to split your commit into two. Happily, you can perform your commit normally but you need to turn off rename detection:
Unfortunately you will still commit two changes, this time in one batch (as a deletion the old file and creation file with the new name), instead of just a file rename, so you will still loose information in the process.
To avoid this completely the only option is to downgrade SVN client to the latest version on 1.7.X
branch.
Credits
Big thanks to @skremiec for undeceiving me in some cases and pointing out svn.rmdir
option .