Git SVN: Difference between revisions

From miki
Jump to navigation Jump to search
Line 110: Line 110:
* http://ujihisa.blogspot.com/2010/10/git-svn-low-risk-practice.html
* http://ujihisa.blogspot.com/2010/10/git-svn-low-risk-practice.html
* http://stackoverflow.com/questions/190431/is-git-svn-dcommit-after-merging-in-git-dangerous
* http://stackoverflow.com/questions/190431/is-git-svn-dcommit-after-merging-in-git-dangerous

== Config with non-standard layout ==

In case the SVN repo does not follow the standard directory layout (i.e. <tt>trunk/</tt>, <tt>branches/</tt> and <tt>tags</tt>), we can change the default config. Here an example of config:

<source lang="text">
[user]
name = beq06659
email = michael.peeters@nxp.com
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
autocrlf = false
whitespace = -blank-at-eol,-space-before-tab,-blank-at-eof
[apply]
ignorewhitespace = change
[svn-remote "svn"]
url = https://www.collabnet.nxp.com/svn/atop
fetch = trunk:refs/remotes/trunk
branches = branches/*:refs/remotes/*
# branches = Release_Branches/Customer/Audi/*:refs/remotes/Release_Branches/Customer/Audi/*
# branches = Release_Branches/Customer/S1NN/*:refs/remotes/Release_Branches/Customer/S1NN/*
# branches = Release_Branches/Dev/*:refs/remotes/Release_Branches/Dev/*
# branches = Release_Branches/Indus/*:refs/remotes/Release_Branches/Indus/*
# tags = tags/*:refs/remotes/tags/*
tags = tags/Customer/*:refs/remotes/tags/Customer/*
tags = tags/Industrial/Telebox/*:refs/remotes/tags/Industrial/Telebox/*
tags = tags/Industrial/*:refs/remotes/tags/Industrial/*
tags = tags/Intermediate/*:refs/remotes/tags/Intermediate/*
tags = tags/Mainline/*:refs/remotes/tags/Mainline/*
</source>

;Do's and Don't's
* We see that there are overlapping tag specification (<tt>tags/Industrial/Telebox/*</tt> and <tt>tags/Industrial/*</tt>). This is because some tags are created in the parent directory, and some more are to be found in the <tt>Telebox</tt> sub-directory. This will create a conflict though because git will create a reference named <tt>tags/Industrial/Telebox</tt>, and later will try to create a reference <tt>tags/Industrial/Telebox/...</tt> that fails because The first reference prevents creating the sub-directory. To solve, simply remove the reference and restart:
<source lang="bash">
git branch -r -D tags/Industrial/Telebox
git svn fetch
</source>
* Git svn falls back in ''stupid mode'' (i.e. fetching the full history of each branch, even if given revision was already fetched in the past) if it is initialized without any option. So '''always init / clone the repo with option <tt>-s</tt> (standard layout)'''. If the layout is non-standard, use <code>git svn init</tt> and edit the config.
* Never change the default location of branch. Never use a spec like <code> branches = branches/*:refs/remotes/branches/*</code>. When trying with such a spec, git svn was fetching and fetching again the same revisions (from <tt>r1</tt>!).


== Tips ==
== Tips ==

Revision as of 13:10, 22 November 2011

This page is dedicated to Subversion integration in Git

References

Configuration

My default .git/config file on Linux:

[user]
    name = ...
    email = ...
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	autocrlf = false
	whitespace = -blank-at-eol, -space-before-tab,-blank-at-eof
[apply]
    ignorewhitespace = change
[svn-remote "svn"]
	url = ...
	fetch = ...
	branches = ...
	tags = ...

My default .git/config file on Cygwin:

[user]
    name = ...
    email = ...
[core]
	repositoryformatversion = 0
	filemode = false
	bare = false
	logallrefupdates = true
	ignorecase = true
	autocrlf = false
	whitespace = -blank-at-eol, -space-before-tab,-blank-at-eof
[apply]
    ignorewhitespace = change
[svn-remote "svn"]
	url = https://www.collabnet.nxp.com/svn/atop
	fetch = trunk:refs/remotes/trunk
	branches = branches/*:refs/remotes/*
	tags = tags/*:refs/remotes/tags/*

Workflow

Get a clone of subversion repository with:

# git: git clone => 
# svn: svn checkout =>
git svn clone https://www.mysvn.org/svn/project -T trunk -b branches -t tags --username='USER'
git svn clone https://www.mysvn.org/svn/project --stdlayout --username='USER'                   # Identical
# Clean / compress git DB if necessary...
git gc

Fetch all changes from SVN repo:

# git: git fetch =>
git svn fetch

Fetch and merge all changes from SVN repo:

# git: git pull =>
# svn: svn update =>
git svn rebase
git svn rebase -l                   # Only rebase against last fetched commit from upstream SVN
In case of conflicts (see [1]):
  • You are on a (no-branch) branch (with git status showing a .dotest file you can ignore)
  • Use the usual git rebase --abort (to bail out), git rebase --continue (solved conflict), git rebase --skip (no-op patch)

Send local changes to SVN repo:

# git: git push =>
git svn dcommit

Annotate changes in a file:

# git: git blame =>
# svn: svn annotate/blame =>
git svn blame fullpath              # Only accept full path! (from project rootdir)
git blame file

Create git .gitignore from svn:

# Typically in project root:
git-svn show-ignore > .gitignore

More Workflows

Config with non-standard layout

In case the SVN repo does not follow the standard directory layout (i.e. trunk/, branches/ and tags), we can change the default config. Here an example of config:

[user]
      name = beq06659
      email = michael.peeters@nxp.com
[core]
      repositoryformatversion = 0
      filemode = true
      bare = false
      logallrefupdates = true
      autocrlf = false
      whitespace = -blank-at-eol,-space-before-tab,-blank-at-eof
[apply]
      ignorewhitespace = change
[svn-remote "svn"]
      url = https://www.collabnet.nxp.com/svn/atop
      fetch = trunk:refs/remotes/trunk
      branches = branches/*:refs/remotes/*
#     branches = Release_Branches/Customer/Audi/*:refs/remotes/Release_Branches/Customer/Audi/*
#     branches = Release_Branches/Customer/S1NN/*:refs/remotes/Release_Branches/Customer/S1NN/*
#     branches = Release_Branches/Dev/*:refs/remotes/Release_Branches/Dev/*
#     branches = Release_Branches/Indus/*:refs/remotes/Release_Branches/Indus/*
#     tags = tags/*:refs/remotes/tags/*
      tags = tags/Customer/*:refs/remotes/tags/Customer/*
      tags = tags/Industrial/Telebox/*:refs/remotes/tags/Industrial/Telebox/*
      tags = tags/Industrial/*:refs/remotes/tags/Industrial/*
      tags = tags/Intermediate/*:refs/remotes/tags/Intermediate/*
      tags = tags/Mainline/*:refs/remotes/tags/Mainline/*
Do's and Don't's
  • We see that there are overlapping tag specification (tags/Industrial/Telebox/* and tags/Industrial/*). This is because some tags are created in the parent directory, and some more are to be found in the Telebox sub-directory. This will create a conflict though because git will create a reference named tags/Industrial/Telebox, and later will try to create a reference tags/Industrial/Telebox/... that fails because The first reference prevents creating the sub-directory. To solve, simply remove the reference and restart:
git branch -r -D tags/Industrial/Telebox
git svn fetch
  • Git svn falls back in stupid mode (i.e. fetching the full history of each branch, even if given revision was already fetched in the past) if it is initialized without any option. So always init / clone the repo with option -s (standard layout). If the layout is non-standard, use git svn init and edit the config.
  • Never change the default location of branch. Never use a spec like branches = branches/*:refs/remotes/branches/*. When trying with such a spec, git svn was fetching and fetching again the same revisions (from r1!).

Tips

Remove orphaned svn branch
See [2] (and simple fix at [3])

Troubleshooting

Bugs

  • Byte order not compatible — Recently got the following error on cygwin:
Byte order is not compatible at ../../lib/Storable.pm (autosplit into ../../lib/auto/Storable/_retrieve.al) line 380, at /usr/share/perl/5.10.1/Memoize/Storable.pm line 21
[...] 
Could not unmemoize function `lookup_svn_merge', because it was not memoized to begin with at /usr/lib/git-core/git-svn line 3197
Basically git svn cannot read the content of its cache, and crashes. This can happen after an update of Perl, or when using a copy of a repository that has been created on another machine (typ. with different endianness settings) (see [4] and [5]).
The best fix is to simply delete the git svn cache:
rm -r .git/svn/caches