717ab5c5039cd8691cf1e6517342e924e4ecd251
[python/fast-export.git] / hg2git.py
1 #!/usr/bin/env python
2
3 # Copyright (c) 2007 Rocco Rutte <pdmef@gmx.net>
4 # License: MIT <http://www.opensource.org/licenses/mit-license.php>
5
6 from mercurial import repo,hg,cmdutil,util,ui,revlog,node
7 import re
8 import os
9 import sys
10
11 # default git branch name
12 cfg_master='master'
13 # silly regex to see if user field has email address
14 user_re=re.compile('([^<]+) (<[^>]+>)$')
15 # silly regex to clean out user names
16 user_clean_re=re.compile('^["]([^"]+)["]$')
17
18 def setup_repo(url):
19   myui=ui.ui(interactive=False)
20   return myui,hg.repository(myui,url)
21
22 def fixup_user(user,authors):
23   if authors!=None:
24     # if we have an authors table, try to get mapping
25     # by defaulting to the current value of 'user'
26     user=authors.get(user,user)
27   name,mail,m='','',user_re.match(user)
28   if m==None:
29     # if we don't have 'Name <mail>' syntax, use 'user
30     # <devnull@localhost>' if use contains no at and
31     # 'user <user>' otherwise
32     name=user
33     if '@' not in user:
34       mail='<devnull@localhost>'
35     else:
36       mail='<%s>' % user
37   else:
38     # if we have 'Name <mail>' syntax, everything is fine :)
39     name,mail=m.group(1),m.group(2)
40
41   # remove any silly quoting from username
42   m2=user_clean_re.match(name)
43   if m2!=None:
44     name=m2.group(1)
45   return '%s %s' % (name,mail)
46
47 def get_branch(name):
48   # 'HEAD' is the result of a bug in mutt's cvs->hg conversion,
49   # other CVS imports may need it, too
50   if name=='HEAD' or name=='default' or name=='':
51     name=cfg_master
52   return name
53
54 def get_changeset(ui,repo,revision,authors={}):
55   node=repo.lookup(revision)
56   (manifest,user,(time,timezone),files,desc,extra)=repo.changelog.read(node)
57   tz="%+03d%02d" % (-timezone / 3600, ((-timezone % 3600) / 60))
58   branch=get_branch(extra.get('branch','master'))
59   return (node,manifest,fixup_user(user,authors),(time,tz),files,desc,branch,extra)
60
61 def mangle_key(key):
62   return key
63
64 def load_cache(filename,get_key=mangle_key):
65   cache={}
66   if not os.path.exists(filename):
67     return cache
68   f=open(filename,'r')
69   l=0
70   for line in f.readlines():
71     l+=1
72     fields=line.split(' ')
73     if fields==None or not len(fields)==2 or fields[0][0]!=':':
74       sys.stderr.write('Invalid file format in [%s], line %d\n' % (filename,l))
75       continue
76     # put key:value in cache, key without ^:
77     cache[get_key(fields[0][1:])]=fields[1].split('\n')[0]
78   f.close()
79   return cache
80
81 def save_cache(filename,cache):
82   f=open(filename,'w+')
83   map(lambda x: f.write(':%s %s\n' % (str(x),str(cache.get(x)))),cache.keys())
84   f.close()
85
86 def get_git_sha1(name,type='heads'):
87   try:
88     # use git-rev-parse to support packed refs
89     cmd="GIT_DIR='%s' git-rev-parse --verify refs/%s/%s 2>/dev/null" % (os.getenv('GIT_DIR','/dev/null'),type,name)
90     p=os.popen(cmd)
91     l=p.readline()
92     p.close()
93     if l == None or len(l) == 0:
94       return None
95     return l[0:40]
96   except IOError:
97     return None