emperor: (Phoenix)
posted by [personal profile] emperor at 03:04pm on 11/02/2015 under , ,
Git has become the de-facto standard revision control system, so one of the things I've been doing recently at work is moving our old Subversion repositories to git[0]. git svn is a plausible tool, but it's more designed for continued inter-operation between git and svn than for a one-way export. For example, because tags in svn are basically specially-named branches, they end up as branches in the resulting git repository, which isn't really what you wanted.

Thankfully, the internet has plenty of handy tutorials on how to improve on git svn's default operation, so the resulting git repository is a better starting point for future development. Probably the best of these is The git book's article. Two of the steps are to turn the "tags as branches" into proper tags, and to rename the remotes/* branches to local branches:

#tag-branches into tags
$ cp -Rf .git/refs/remotes/origin/tags/* .git/refs/tags/
$ rm -Rf .git/refs/remotes/origin/tags
#remotes/* branches into local branches
$ cp -Rf .git/refs/remotes/* .git/refs/heads/
$ rm -Rf .git/refs/remotes


It may[1], however, turn out that there is nothing in .git/refs/remotes/origin/tags/, even if there were tags in your svn repository and git branch -a shows the relevant branches! This will be vexing. Furthermore, there will only be a few branches in .git/refs/remotes/. What is going on?

The answer is that git has tidied up .git/refs because it has run git pack-refs for you. That means that there is now a file .git/packed_refs which has lines of the form:
7c8a5686b698a61a33c4a6c73776da20b5ede635 refs/heads/origin/protocol2

This is the equivalent to having the file .git/refs/heads/origin/protocol2 containing 7c8a5686b698a61a33c4a6c73776da20b5ede635 (i.e. that the tip of the origin/protocol2 branch is 7c8a568...).

So what? Well, it now means you can achieve the tidying up that the above shell runes do by editing .git/packed_refs (carefully!). For example, I used emacs' query-replace function to replace refs/remotes/origin/tags/ with refs/tags. And joy was unconfined.

So I wrote this in case anyone else trips over this feature (so feel free to link to this post). If I have some tuits I might try and get the git book updated, too...

[0] Also taking advantage of this opportunity to re-structure them somewhat with git filter-branch and friends, but that's not really relevant right now.
[1] More likely if your repository was large or complex

July

SunMonTueWedThuFriSat
    1
 
2
 
3 4
 
5
 
6
 
7
 
8
 
9 10
 
11
 
12
 
13
 
14
 
15
 
16
 
17
 
18
 
19
 
20
 
21
 
22
 
23
 
24
 
25
 
26
 
27
 
28
 
29
 
30
 
31