Reputation: 3348
I converted a Subversion repository to git a couple of weeks ago, thought that everything looked fine, then switched over to working with git exclusively. However, now I notice that I made a mistake when converting tags and branches.
The SVN repo had a hierarchy of tags. So, for instance, we had something like:
branches
project1
1.0
1.1
project2
1.0.0.1
etc. I now have git 'tags' project1 and project2. I tried to create the nested tags by running git ls-tree project1
, then git tag project1-1.0 <hash>
, but if I try to check the resulting tag out I get the message "Cannot switch branch to a non-commit". I see that I have tagged a tree rather than a commit.
Is there a clever way for me to create the tags manually?
Upvotes: 1
Views: 417
Reputation: 3348
Thanks to @stuart for putting me on the right track. The process I used was a bit long-winded but I think I have the right results.
First I created a file containing svn links to my tag 'parent' folders (those containing the version-numbered tags.) I processed that file to create another one containing the paths contained in each of those parents:
#!/usr/bin/python
import os
f = open('parents')
parentPaths = [x.strip('\n') for x in f.readlines()]
f.close()
for parentPath in parentPaths:
escapedPath = parentPath.replace('\\','\\\\').replace('/', '\\/').replace('&', '\\&')
c = "svn ls '" + parentPath + "' | sed -e 's/\\(.*\\)/" + escapedPath + "\\/\\1/' >> paths"
os.system(c)
Next I got SVN revision numbers for each of those paths using this script:
#!/usr/bin/python
import os
f = open('paths')
ps = [ x.strip('\n') for x in f.readlines() ]
f.close()
for p in ps:
branchName = p.replace("svn://myrepo/tags/", "").strip(" ").rstrip("/\n").replace("/", "-").replace(" ", "-").replace(")", "").replace("(", "").lower()
eBN = branchName.replace("\\", "\\\\").replace("/", "\\/").replace("&", "\\&")
c = "svn log '" + p + "' --stop-on-copy -l 1 -v | grep -E '\\(from .*:[0-9]+\\)$' | sed -e 's/.*(from .*:\\([0-9]*\\))$/\\1/' >> revs/" + eBN
os.system(c)
One tag may contain several SVN log revision entries, so I munged the output of the above into a single file called revs.out:
#!/usr/bin/python
import os
o = open('revs.out', 'w')
for filename in os.listdir('revs') :
f = open('revs/' + filename)
l = [ x.strip('\n') for x in f.readlines() ]
f.close()
o.write( "{0} {1}\n".format( max(l), filename ) )
o.close()
This contains, for instance:
4073 myproject-version-1.12.44
6982 myproject-version-1.13.9
The next bit gets a bit tricky. Most of the tags were made on trunk, and I got git commit refs for those like this (running in a git repo):
#!/usr/bin/python
import os
f = open('../svn/revs.out')
revs = [ x.strip('\n').split(' ') for x in f.readlines() ]
f.close()
for rev in revs:
r = rev[0]
n = rev[1]
c = "git log --all --grep 'trunk@" + r + " ' --pretty=format:%H | sed -e 's/\\(.*\\)/git tag " + n + " \\1\\n/' >> ~/src/svn/genTags.sh"
os.system(c)
Other tags were made from branches, or from folders in the trunk hierarchy, or were otherwise empty tags created when a new folder was created in the 'tags' hierarchy. These cases I dealt with pretty much manually.
The result at this point was a script which would itself create git tags. Here is an excerpt:
git tag project1-1.2.0.2 86e0f47f37ee28a3b16be26e4ab81a39a24015aa
git tag project2-1.1.0.2 9cefabc1e8e66e974bb3d987a1089027535c8562
git tag project2-1.1.0.8 1d3e9abe6f4ec440806d32ed60ae80a2568778eb
I then ran the script to create the tags.
Upvotes: 0
Reputation: 20656
If you look in gitk
(turning on the all branches view), and find the project1
branch, you will be able to see all of the commits on that branch. Go through and find the one which should be tagged, and then use git tag <hash>
. Repeat for the other tags :)
Upvotes: 1