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