From ec1be3d05f7fe6e5b8bdaa6c18a0a17f42c9c2b3 Mon Sep 17 00:00:00 2001 From: Rocco Rutte Date: Thu, 25 Oct 2007 15:21:46 +0200 Subject: [PATCH 1/3] hg-fast-export.py: Minor tweaks/cleanup Remove some unused variables, generalize dictionary-splitting and make sure we don't sort filename lists twice (repo.status returns files sorted already). Signed-off-by: Rocco Rutte --- hg-fast-export.py | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/hg-fast-export.py b/hg-fast-export.py index c85e84e..8113333 100755 --- a/hg-fast-export.py +++ b/hg-fast-export.py @@ -41,18 +41,18 @@ def get_parent_mark(parent,marks): otherwise the SHA1 from the cache.""" return marks.get(str(parent),':%d' % (parent+1)) -def mismatch(f1,f2): +def file_mismatch(f1,f2): """See if two revisions of a file are not equal.""" return node.hex(f1)!=node.hex(f2) -def outer_set(dleft,dright,l,c,r): +def split_dict(dleft,dright,l=[],c=[],r=[],match=file_mismatch): """Loop over our repository and find all changed and missing files.""" for left in dleft.keys(): right=dright.get(left,None) if right==None: # we have the file but our parent hasn't: add to left set l.append(left) - elif mismatch(dleft[left],right): + elif match(dleft[left],right): # we have it but checksums mismatch: add to center set c.append(left) for right in dright.keys(): @@ -69,11 +69,10 @@ def get_filechanges(repo,revision,parents,mleft): for p in parents: if p<0: continue mright=repo.changectx(p).manifest() - dleft=mleft.keys() - dleft.sort() - dright=mright.keys() - dright.sort() - l,c,r=outer_set(mleft,mright,l,c,r) + l,c,r=split_dict(mleft,mright,l,c,r) + l.sort() + c.sort() + r.sort() return l,c,r def get_author(logmessage,committer,authors): @@ -115,11 +114,9 @@ def get_author(logmessage,committer,authors): def export_file_contents(ctx,manifest,files): count=0 - files.sort() max=len(files) for file in files: - fctx=ctx.filectx(file) - d=fctx.data() + d=ctx.filectx(file).data() wr('M %s inline %s' % (gitmode(manifest.execf(file)),file)) wr('data %d' % len(d)) # had some trouble with size() wr(d) @@ -194,6 +191,7 @@ def export_commit(ui,repo,revision,marks,heads,last,max,count,authors,sob): if revision==0: # first revision: feed in full manifest added=man.keys() + added.sort() type='full' elif is_merge(parents): # later merge revision: feed in changed manifest @@ -213,7 +211,8 @@ def export_commit(ui,repo,revision,marks,heads,last,max,count,authors,sob): (branch,type,revision+1,max,len(added),len(changed),len(removed))) map(lambda r: wr('D %s' % r),removed) - export_file_contents(ctx,man,added+changed) + export_file_contents(ctx,man,added) + export_file_contents(ctx,man,changed) wr() return checkpoint(count) From 431c32de6b0879f4a8ae0447923ccc4a28577395 Mon Sep 17 00:00:00 2001 From: Rocco Rutte Date: Thu, 25 Oct 2007 15:23:17 +0200 Subject: [PATCH 2/3] hg-fast-export.py: Don't attempt to dump revs beyond tip with -m Signed-off-by: Rocco Rutte --- hg-fast-export.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hg-fast-export.py b/hg-fast-export.py index 8113333..6b501f8 100755 --- a/hg-fast-export.py +++ b/hg-fast-export.py @@ -305,7 +305,7 @@ def hg2git(repourl,m,marksfile,headsfile,tipfile,authors={},sob=False,force=Fals min=int(state_cache.get('tip',0)) max=_max - if _max<0: + if _max<0 or max>tip: max=tip c=0 From 4cc930807d314f63ee3867e1143c62e34bc15aa6 Mon Sep 17 00:00:00 2001 From: Rocco Rutte Date: Fri, 26 Oct 2007 16:06:40 +0200 Subject: [PATCH 3/3] hg-fast-import.py: Sanitize ref names At least the opensolaris hg repo has tag names containing '*', so sanitize all branch and tag names roughly according to the specs for git-check-ref-format(1). Signed-off-by: Rocco Rutte --- hg-fast-export.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/hg-fast-export.py b/hg-fast-export.py index 6b501f8..97dba5f 100755 --- a/hg-fast-export.py +++ b/hg-fast-export.py @@ -133,10 +133,31 @@ def is_merge(parents): c+=1 return c>1 +def sanitize_name(name,what="branch"): + """Sanitize input roughly according to git-check-ref-format(1)""" + + def dot(name): + if name[0] == '.': return '_'+name[1:] + return name + + n=name + p=re.compile('([[ ^:?*]|\.\.)') + n=p.sub('_', n) + if n[-1] == '/': n=n[:-1]+'_' + n='/'.join(map(dot,n.split('/'))) + p=re.compile('_+') + n=p.sub('_', n) + + if n!=name: + sys.stderr.write('Warning: sanitized %s [%s] to [%s]\n' % (what,name,n)) + return n + def export_commit(ui,repo,revision,marks,heads,last,max,count,authors,sob): (revnode,_,user,(time,timezone),files,desc,branch,_)=get_changeset(ui,repo,revision,authors) parents=repo.changelog.parentrevs(revision) + branch=sanitize_name(branch) + wr('commit refs/heads/%s' % branch) wr('mark :%d' % (revision+1)) if sob: @@ -220,6 +241,7 @@ def export_commit(ui,repo,revision,marks,heads,last,max,count,authors,sob): def export_tags(ui,repo,marks_cache,start,end,count,authors): l=repo.tagslist() for tag,node in l: + tag=sanitize_name(tag,"tag") # ignore latest revision if tag=='tip': continue rev=repo.changelog.rev(node)