chris@1544
|
1 #!/usr/bin/env python
|
chris@1544
|
2
|
chris@1544
|
3 # Copyright (c) 2007, 2008 Rocco Rutte <pdmef@gmx.net> and others.
|
chris@1544
|
4 # License: GPLv2
|
chris@1544
|
5
|
chris@1544
|
6 from mercurial import node
|
chris@1544
|
7 from hg2git import setup_repo,load_cache,get_changeset,get_git_sha1
|
chris@1544
|
8 from optparse import OptionParser
|
chris@1544
|
9 import sys
|
chris@1544
|
10
|
chris@1544
|
11 def heads(ui,repo,start=None,stop=None,max=None):
|
chris@1544
|
12 # this is copied from mercurial/revlog.py and differs only in
|
chris@1544
|
13 # accepting a max argument for xrange(startrev+1,...) defaulting
|
chris@1544
|
14 # to the original repo.changelog.count()
|
chris@1544
|
15 if start is None:
|
chris@1544
|
16 start = node.nullid
|
chris@1544
|
17 if stop is None:
|
chris@1544
|
18 stop = []
|
chris@1544
|
19 if max is None:
|
chris@1544
|
20 max = repo.changelog.count()
|
chris@1544
|
21 stoprevs = dict.fromkeys([repo.changelog.rev(n) for n in stop])
|
chris@1544
|
22 startrev = repo.changelog.rev(start)
|
chris@1544
|
23 reachable = {startrev: 1}
|
chris@1544
|
24 heads = {startrev: 1}
|
chris@1544
|
25
|
chris@1544
|
26 parentrevs = repo.changelog.parentrevs
|
chris@1544
|
27 for r in xrange(startrev + 1, max):
|
chris@1544
|
28 for p in parentrevs(r):
|
chris@1544
|
29 if p in reachable:
|
chris@1544
|
30 if r not in stoprevs:
|
chris@1544
|
31 reachable[r] = 1
|
chris@1544
|
32 heads[r] = 1
|
chris@1544
|
33 if p in heads and p not in stoprevs:
|
chris@1544
|
34 del heads[p]
|
chris@1544
|
35
|
chris@1544
|
36 return [(repo.changelog.node(r),str(r)) for r in heads]
|
chris@1544
|
37
|
chris@1544
|
38 def get_branches(ui,repo,heads_cache,marks_cache,mapping_cache,max):
|
chris@1544
|
39 h=heads(ui,repo,max=max)
|
chris@1544
|
40 stale=dict.fromkeys(heads_cache)
|
chris@1544
|
41 changed=[]
|
chris@1544
|
42 unchanged=[]
|
chris@1544
|
43 for node,rev in h:
|
chris@1544
|
44 _,_,user,(_,_),_,desc,branch,_=get_changeset(ui,repo,rev)
|
chris@1544
|
45 del stale[branch]
|
chris@1544
|
46 git_sha1=get_git_sha1(branch)
|
chris@1544
|
47 cache_sha1=marks_cache.get(str(int(rev)+1))
|
chris@1544
|
48 if git_sha1!=None and git_sha1==cache_sha1:
|
chris@1544
|
49 unchanged.append([branch,cache_sha1,rev,desc.split('\n')[0],user])
|
chris@1544
|
50 else:
|
chris@1544
|
51 changed.append([branch,cache_sha1,rev,desc.split('\n')[0],user])
|
chris@1544
|
52 changed.sort()
|
chris@1544
|
53 unchanged.sort()
|
chris@1544
|
54 return stale,changed,unchanged
|
chris@1544
|
55
|
chris@1544
|
56 def get_tags(ui,repo,marks_cache,mapping_cache,max):
|
chris@1544
|
57 l=repo.tagslist()
|
chris@1544
|
58 good,bad=[],[]
|
chris@1544
|
59 for tag,node in l:
|
chris@1544
|
60 if tag=='tip': continue
|
chris@1544
|
61 rev=int(mapping_cache[node.encode('hex_codec')])
|
chris@1544
|
62 cache_sha1=marks_cache.get(str(int(rev)+1))
|
chris@1544
|
63 _,_,user,(_,_),_,desc,branch,_=get_changeset(ui,repo,rev)
|
chris@1544
|
64 if int(rev)>int(max):
|
chris@1544
|
65 bad.append([tag,branch,cache_sha1,rev,desc.split('\n')[0],user])
|
chris@1544
|
66 else:
|
chris@1544
|
67 good.append([tag,branch,cache_sha1,rev,desc.split('\n')[0],user])
|
chris@1544
|
68 good.sort()
|
chris@1544
|
69 bad.sort()
|
chris@1544
|
70 return good,bad
|
chris@1544
|
71
|
chris@1544
|
72 def mangle_mark(mark):
|
chris@1544
|
73 return str(int(mark)-1)
|
chris@1544
|
74
|
chris@1544
|
75 if __name__=='__main__':
|
chris@1544
|
76 def bail(parser,opt):
|
chris@1544
|
77 sys.stderr.write('Error: No option %s given\n' % opt)
|
chris@1544
|
78 parser.print_help()
|
chris@1544
|
79 sys.exit(2)
|
chris@1544
|
80
|
chris@1544
|
81 parser=OptionParser()
|
chris@1544
|
82
|
chris@1544
|
83 parser.add_option("--marks",dest="marksfile",
|
chris@1544
|
84 help="File to read git-fast-import's marks from")
|
chris@1544
|
85 parser.add_option("--mapping",dest="mappingfile",
|
chris@1544
|
86 help="File to read last run's hg-to-git SHA1 mapping")
|
chris@1544
|
87 parser.add_option("--heads",dest="headsfile",
|
chris@1544
|
88 help="File to read last run's git heads from")
|
chris@1544
|
89 parser.add_option("--status",dest="statusfile",
|
chris@1544
|
90 help="File to read status from")
|
chris@1544
|
91 parser.add_option("-r","--repo",dest="repourl",
|
chris@1544
|
92 help="URL of repo to import")
|
chris@1544
|
93 parser.add_option("-R","--revision",type=int,dest="revision",
|
chris@1544
|
94 help="Revision to reset to")
|
chris@1544
|
95
|
chris@1544
|
96 (options,args)=parser.parse_args()
|
chris@1544
|
97
|
chris@1544
|
98 if options.marksfile==None: bail(parser,'--marks option')
|
chris@1544
|
99 if options.mappingfile==None: bail(parser,'--mapping option')
|
chris@1544
|
100 if options.headsfile==None: bail(parser,'--heads option')
|
chris@1544
|
101 if options.statusfile==None: bail(parser,'--status option')
|
chris@1544
|
102 if options.repourl==None: bail(parser,'--repo option')
|
chris@1544
|
103 if options.revision==None: bail(parser,'-R/--revision')
|
chris@1544
|
104
|
chris@1544
|
105 heads_cache=load_cache(options.headsfile)
|
chris@1544
|
106 marks_cache=load_cache(options.marksfile,mangle_mark)
|
chris@1544
|
107 state_cache=load_cache(options.statusfile)
|
chris@1544
|
108 mapping_cache = load_cache(options.mappingfile)
|
chris@1544
|
109
|
chris@1544
|
110 l=int(state_cache.get('tip',options.revision))
|
chris@1544
|
111 if options.revision+1>l:
|
chris@1544
|
112 sys.stderr.write('Revision is beyond last revision imported: %d>%d\n' % (options.revision,l))
|
chris@1544
|
113 sys.exit(1)
|
chris@1544
|
114
|
chris@1544
|
115 ui,repo=setup_repo(options.repourl)
|
chris@1544
|
116
|
chris@1544
|
117 stale,changed,unchanged=get_branches(ui,repo,heads_cache,marks_cache,mapping_cache,options.revision+1)
|
chris@1544
|
118 good,bad=get_tags(ui,repo,marks_cache,mapping_cache,options.revision+1)
|
chris@1544
|
119
|
chris@1544
|
120 print "Possibly stale branches:"
|
chris@1544
|
121 map(lambda b: sys.stdout.write('\t%s\n' % b),stale.keys())
|
chris@1544
|
122
|
chris@1544
|
123 print "Possibly stale tags:"
|
chris@1544
|
124 map(lambda b: sys.stdout.write('\t%s on %s (r%s)\n' % (b[0],b[1],b[3])),bad)
|
chris@1544
|
125
|
chris@1544
|
126 print "Unchanged branches:"
|
chris@1544
|
127 map(lambda b: sys.stdout.write('\t%s (r%s)\n' % (b[0],b[2])),unchanged)
|
chris@1544
|
128
|
chris@1544
|
129 print "Unchanged tags:"
|
chris@1544
|
130 map(lambda b: sys.stdout.write('\t%s on %s (r%s)\n' % (b[0],b[1],b[3])),good)
|
chris@1544
|
131
|
chris@1544
|
132 print "Reset branches in '%s' to:" % options.headsfile
|
chris@1544
|
133 map(lambda b: sys.stdout.write('\t:%s %s\n\t\t(r%s: %s: %s)\n' % (b[0],b[1],b[2],b[4],b[3])),changed)
|
chris@1544
|
134
|
chris@1544
|
135 print "Reset ':tip' in '%s' to '%d'" % (options.statusfile,options.revision)
|