回顾性地在git中重新创建svn标签

时间:2011-12-22 12:40:51

标签: git svn

几周前我将一个Subversion存储库转换为git,认为一切都很好,然后转而专门使用git。但是,现在我注意到在转换标签和分支时我犯了一个错误。

SVN repo有一个标签层次结构。所以,例如,我们有类似的东西:

 branches
  project1
   1.0
   1.1
  project2
   1.0.0.1

等。我现在有git'tags'project1和project2。我尝试通过运行git ls-tree project1然后git tag project1-1.0 <hash>来创建嵌套标记,但是如果我尝试检查生成的标记,则会收到消息“无法将分支切换为非提交”。我看到我标记了一棵树而不是提交。

我是否有一种聪明的方法可以手动创建标签?

2 个答案:

答案 0 :(得分:1)

如果您查看gitk(打开所有分支视图),并找到project1分支,您将能够看到该分支上的所有提交。浏览并找到应标记的那个,然后使用git tag <hash>。重复其他标签:)

答案 1 :(得分:0)

感谢@stuart让我走上正轨。我使用的过程有点啰嗦,但我认为我有正确的结果。

首先,我创建了一个文件,其中包含指向我的标签'parent'文件夹的svn链接(包含版本号标记的文件夹。)我处理了该文件以创建另一个文件,其中包含每个父文件中包含的路径:

#!/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)

接下来,我使用此脚本获取每个路径的SVN修订号:

#!/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)

一个标签可能包含多个SVN日志修订条目,因此我将上述输出发送到名为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()

这包含,例如:

4073 myproject-version-1.12.44
6982 myproject-version-1.13.9

接下来的一点有点棘手。大多数标签都是在trunk上制作的,我为这样的人提供了git commit refs(在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)

其他标签来自分支,或来自主干层次结构中的文件夹,或者是在“标签”层次结构中创建新文件夹时创建的其他空标签。我手动处理这些案件。

此时的结果是一个脚本,它本身会创建git标签。这是一段摘录:

git tag project1-1.2.0.2 86e0f47f37ee28a3b16be26e4ab81a39a24015aa
git tag project2-1.1.0.2 9cefabc1e8e66e974bb3d987a1089027535c8562
git tag project2-1.1.0.8 1d3e9abe6f4ec440806d32ed60ae80a2568778eb

然后我运行脚本来创建标签。