10 Sep 2019 - tsp
Last update 11 Sep 2019
9 mins
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:
pushed
onto other nodes and pulled
from 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 devel/git-subversion
package).
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 trunk
, branches
,
tags
layout for which one can supply the --stdlayout
option but it’s
easily adaptable to other layouts by specifying the locations via -T
, -t
and
-b
during init
respectively.
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:
--stdlayout
uses the well known /trunk/
, /branches/
, /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.--trunk=other/trunk
, --tags=other/tags
, --branches=other/branches
can 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.--username
might specify the username for http, https and svn transports. This cannot
be used for ssh transport though.Example:
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:
--loacaltime
uses 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-paths
allows one to specify a regular expression of paths that should not be
fetched.Example:
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 --preserve-empty-dirs
a .gitignore
file is created in every empty
directory that is cloned from the SVN repository to prevent removal on later SVN commits.
The 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.
Example:
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
then 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 svn dcommit
.
Just use git svn rebase
always before you resume working or before dcommit
ing.
If it’s only about a simple repository one can simply do a git svn init
followed by
a 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.
This article is tagged:
Dipl.-Ing. Thomas Spielauer, Wien (webcomplains389t48957@tspi.at)
This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/