10 Sep 2019 - tsp
Normally git and svn is viewed as a competing solution for source control. But in fact git and svn just serve different development models and provide different features. In fact there are situations where git is more suited and also situations where subversion is.
Note that this article is only focusing on the interoperability between git and svn. If you want to know more about git you can take a look at my git cheat-sheet or read a full book on all techniques and the theory behind version management with git like Version Control with Git: Powerful tools and techniques for collaborative software development (note: Amazon affilate link, this pages author profits from qualified purchases).
The main difference between SVN and GIT is that GIT tries to model a distributed non centralized development process wheras SVN defines that there is a single ground thruth to all history and current state of the project, the centralized repository. This leads to some differences:
pushedonto other nodes and
pulledfrom there. For GIT this can also happen only partially. This means that there can be a myriad of different repository layouts and even non-linear history layouts that make sense from each clients standpoint.
When do you want to use SVN and when GIT? If you have a centralized strictly managed workflow that requires a single true history and a simple client - use SVN. If you require distributed development features, offline repositories or like the idea of local branches on developer machines, multiple remotes, signed commits, etc. - use GIT. In case you are unsure use GIT - but be prepared to read a little more onto it’s usage and play around a little bit with rebases, branching and similar commands at the Learn Git Branching service.
On the other hand it might also be interesting to use a centralized SVN repository with the GIT clients on the client side - then one can use the single centralized linear repository on the server side as well as SVN client for most users - and the GIT client using local repositories, GIT features like rewrites in local branches and similar features on selected clients for advanced users.
Note that interoperability normally requires an additional package installed (for
example on FreeBSD that’s the
There are also tools which provide interoperability - for example the
git svn command. This command allows users to provide a bidirectional
flow between git and subversion - or in other words one can use git as a client
for an SVN repository and having the benefits of using a local GIT repository. It simply
adds SVN as a remote and translates most basic features between GIT and SVN.
It can follow a standard subversion repository (especially easy if this repository
follows the well known
tags layout for which one can supply the
--stdlayout option but it’s
easily adaptable to other layouts by specifying the locations via
To initialize a git repository with additional metadata for subversion one can use
git svn init. This initializes a git repository with additional metadata. This command
acceps some additional arguments:
--stdlayoutuses the well known
/tags/reository layout to infer information about the subversion repository. Other options (as listed below) take precedence in case one wants to override that behaviour.
--branches=other/branchescan set different paths for trunk, tags or branches. Each of these directories can be specified multiple times if they are spread all around the repository which might be the case for different sub projects.
--usernamemight specify the username for http, https and svn transports. This cannot be used for ssh transport though.
git svn init svn://svn.example.com/reponame --username=exampleuser -T trunk -b branches -t tags
To fetch data from the SVN remote into the local GIT repository one can use the
git svn fetch
command. This command accepts a few useful options:
--loacaltimeuses local timezone information for git logs instead of UTC. This is interesting if one wants to use the same log output format for git and SVN since SVN uses local timezone format. One shouldn’t use this option if one wants to interoperate with external GIT repositories!
--ignore-pathsallows one to specify a regular expression of paths that should not be fetched.
git svn fetch
There is a single command to initialize and fetch in a single step that’s called
git svn clone.
If one specified
.gitignore file is created in every empty
directory that is cloned from the SVN repository to prevent removal on later SVN commits.
git svn rebase command fetches revisions from the SVN parent of the current head and
rebases the current uncomitted work against it. This is similar to
svn update but preserves
linear history (this is different to
git pull and
git merge to keep the history
models of SVN and GIT the same).
Note that rebase requires a clean working copy.
git svn rebase
Commit all local branch commits to the remote SVN as single commits. This replays all local commits (optionally from a different local branch) into a remote SVN repository - one comit at a time.
git svn dcommit
One should note that
dcommit changes all commit hashes - i.e. it might get problematic
if these commits have already been pushed to a remote git repository. If one really wants to
use SVN and GIT remotes one should always first
svn dcommit into the remote SVN and
git push into the remote GIT repository.
In case of conflicts one should use
svn rebase after the failed
svn dcommit to
move local modifications at the currently known remote head state. After this action one
can resume the usage of
git svn rebase always before you resume working or before
If it’s only about a simple repository one can simply do a
git svn init followed by
git svn fetch or a combines
git svn clone to check out all commits ever
done on a subversion repository into a local git repository. This leads to a repository
consisting of a set of commits that correspond to the linear SVN history. One can then
simply attach an GIT remote and continue usage of GIT using all GIT features - if one
really stops using the SVN repository from this point on.