VCS/GitOverSvn

De TartareFR
Version datée du 14 octobre 2012 à 10:42 par Didier (discussion | contributions) (→‎git-svn setup)
(diff) ← Version précédente | Voir la version actuelle (diff) | Version suivante → (diff)
Aller à la navigation Aller à la recherche

Git with SVN tracker

git svn is a simple conduit for changesets between Subversion and git. It provides a bidirectional flow of changes between a Subversion and a git repository.

git svn can track a standard Subversion repository, following the common "trunk/branches/tags" layout, with the --stdlayout ( -s ) option. It can also follow branches and tags in any layout with the -T/-t/-b options (see options to init below, and also the clone command).

Once tracking a Subversion repository (with any of the above methods), the git repository can be updated from Subversion by the fetch command and Subversion updated from git by the dcommit command.


Create SVN repository

$ svnadmin create repo
$ svn co http://localhost/svn/repo
Checked out revision 0.
$ cd svn_repo
$ svn mkdir trunk tags branches
A         trunk
A         tags
A         branches
$ svn commit -m "Create svn repository structure"
Adding         branches
Adding         tags
Adding         trunk

Committed revision 1.

Create Git repository

$ mkdir repo
$ cd repo
$ git init
Initialized empty Git repository in /Users/nicolas/Temp/git_to_svn/project/.git/

$ echo "foo" > test.txt; git add test.txt
$ git commit -m "Initial version"
master (root-commit) 88464cf] Initial version
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 test.txt

$ echo "bar" > test.txt; git commit test.txt -m "Second version"
 master cb62866] Second version
 1 files changed, 1 insertions(+), 1 deletions(-)

git-svn setup

$ git svn init -s http://localhost/svn/repo

$ git svn fetch
r1 = 741ab63aea786882eafd38dc74369e651f554c9c (trunk)

Depending on the layout of your SVN project, you might need to drop the -s parameter and add -t, -T or -b flags, see the git-svn manpage.

Idea.png
svn init arguments
Option -s assume svn already have trunk/tags/branches ( --stdlayout )
For explicitely declare this directories:
  • -T <DIR> or --trunk <DIR> for declare trunk directory
  • --b=<DIR> or --branches <DIR> for declare branches directory
  • --t=<DIR> or --tags <DIR> for declare tags directory

If you already have a previous initialisation, your git repository is now ready and synchronized. Otherwise, we need to synchronize the svn repository with the git repository.

A little naive we could try to push everything to the SVN repository now:

$ git svn dcommit
Unable to determine upstream SVN information from HEAD history.
Perhaps the repository is empty. at /opt/local/libexec/git-core/git-svn line 439.

This fails since the git svn command can’t figure out which commits to push: there’s no link between our original Git repository and the Subversion heads.

To fix this, we can use a Git graft to link them. We’ll tell Git the commit which created the SVN folder in which we want to store the project is the parent commit of the first commit in our Git repository:

$ git show-ref trunk
741ab63aea786882eafd38dc74369e651f554c9c refs/remotes/trunk

$ git log --pretty=oneline master | tail -n1
88464cfdf549a82b30ee7c52e53e2b310f0d9ec4 Initial version

$ echo "88464cfdf549a82b30ee7c52e53e2b310f0d9ec4 741ab63aea786882eafd38dc74369e651f554c9c" >> .git/info/grafts

If now you execute git log, you’ll see the “Create repository structure” SVN commit is displayed after our “Initial version” commit.

Pushing to SVN now works fine:

$ git svn dcommit
Committing to http://localhost/svn/repo ...
	A	test.txt
Committed r2
	A	test.txt
r2 = 8c72757dd3a7d550ed8ef393bb74c0350d22dbac (trunk)
No changes between current HEAD and refs/remotes/trunk
Resetting to the latest refs/remotes/trunk
test.txt: locally modified
	M	test.txt
Committed r3
	M	test.txt
r3 = ca0fc06d477bcd4dd5c6f6d2ae6d94356b510280 (trunk)
No changes between current HEAD and refs/remotes/trunk
Resetting to the latest refs/remotes/trunk

All set Face-smile.png

Howto use it

push commit to remote SVN

git svn dcommit

Pull update from remote SVN

git svn rebase