Change syntax of mapping files
[fast-export.git] / hg2git.py
blob663452142e060fda610d370f969c1e971bc58192
1 #!/usr/bin/env python
3 # Copyright (c) 2007, 2008 Rocco Rutte <pdmef@gmx.net> and others.
4 # License: MIT <http://www.opensource.org/licenses/mit-license.php>
6 from mercurial import hg,util,ui,templatefilters
7 import re
8 import os
9 import sys
10 import subprocess
12 # default git branch name
13 cfg_master='master'
14 # default origin name
15 origin_name=''
16 # silly regex to see if user field has email address
17 user_re=re.compile('([^<]+) (<[^>]*>)$')
18 # silly regex to clean out user names
19 user_clean_re=re.compile('^["]([^"]+)["]$')
21 def set_default_branch(name):
22 global cfg_master
23 cfg_master = name
25 def set_origin_name(name):
26 global origin_name
27 origin_name = name
29 def setup_repo(url):
30 try:
31 myui=ui.ui(interactive=False)
32 except TypeError:
33 myui=ui.ui()
34 myui.setconfig('ui', 'interactive', 'off')
35 return myui,hg.repository(myui,url)
37 def fixup_user(user,authors):
38 user=user.strip("\"")
39 if authors!=None:
40 # if we have an authors table, try to get mapping
41 # by defaulting to the current value of 'user'
42 user=authors.get(user,user)
43 name,mail,m='','',user_re.match(user)
44 if m==None:
45 # if we don't have 'Name <mail>' syntax, extract name
46 # and mail from hg helpers. this seems to work pretty well.
47 # if email doesn't contain @, replace it with devnull@localhost
48 name=templatefilters.person(user)
49 mail='<%s>' % util.email(user)
50 if '@' not in mail:
51 mail = '<devnull@localhost>'
52 else:
53 # if we have 'Name <mail>' syntax, everything is fine :)
54 name,mail=m.group(1),m.group(2)
56 # remove any silly quoting from username
57 m2=user_clean_re.match(name)
58 if m2!=None:
59 name=m2.group(1)
60 return '%s %s' % (name,mail)
62 def get_branch(name):
63 # 'HEAD' is the result of a bug in mutt's cvs->hg conversion,
64 # other CVS imports may need it, too
65 if name=='HEAD' or name=='default' or name=='':
66 name=cfg_master
67 if origin_name:
68 return origin_name + '/' + name
69 return name
71 def get_changeset(ui,repo,revision,authors={},encoding=''):
72 node=repo.lookup(revision)
73 (manifest,user,(time,timezone),files,desc,extra)=repo.changelog.read(node)
74 if encoding:
75 user=user.decode(encoding).encode('utf8')
76 desc=desc.decode(encoding).encode('utf8')
77 tz="%+03d%02d" % (-timezone / 3600, ((-timezone % 3600) / 60))
78 branch=get_branch(extra.get('branch','master'))
79 return (node,manifest,fixup_user(user,authors),(time,tz),files,desc,branch,extra)
81 def mangle_key(key):
82 return key
84 def load_cache(filename,get_key=mangle_key):
85 cache={}
86 if not os.path.exists(filename):
87 return cache
88 f=open(filename,'r')
89 l=0
90 for line in f.readlines():
91 l+=1
92 fields=line.split(' ')
93 if fields==None or not len(fields)==2 or fields[0][0]!=':':
94 sys.stderr.write('Invalid file format in [%s], line %d\n' % (filename,l))
95 continue
96 # put key:value in cache, key without ^:
97 cache[get_key(fields[0][1:])]=fields[1].split('\n')[0]
98 f.close()
99 return cache
101 def save_cache(filename,cache):
102 f=open(filename,'w+')
103 map(lambda x: f.write(':%s %s\n' % (str(x),str(cache.get(x)))),cache.keys())
104 f.close()
106 def get_git_sha1(name,type='heads'):
107 try:
108 # use git-rev-parse to support packed refs
109 ref="refs/%s/%s" % (type,name)
110 l=subprocess.check_output(["git", "rev-parse", "--verify", "--quiet", ref])
111 if l == None or len(l) == 0:
112 return None
113 return l[0:40]
114 except subprocess.CalledProcessError:
115 return None