Files
Fast-Export/hg-reset.py
Ekin Dursun c49dd0cf60 Remove Python 2 compatibility code
Python 2 support was removed recently, so we don't need the
compatibility code anymore.
2023-11-18 20:22:18 +03:00

157 lines
5.0 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright (c) 2007, 2008 Rocco Rutte <pdmef@gmx.net> and others.
# License: GPLv2
from mercurial import node
from hg2git import setup_repo,load_cache,get_changeset,get_git_sha1
from optparse import OptionParser
import sys
from binascii import hexlify
def heads(ui,repo,start=None,stop=None,max=None):
# this is copied from mercurial/revlog.py and differs only in
# accepting a max argument for xrange(startrev+1,...) defaulting
# to the original repo.changelog.count()
if start is None:
start = node.nullid
if stop is None:
stop = []
if max is None:
max = repo.changelog.count()
stoprevs = dict.fromkeys([repo.changelog.rev(n) for n in stop])
startrev = repo.changelog.rev(start)
reachable = {startrev: 1}
heads = {startrev: 1}
parentrevs = repo.changelog.parentrevs
for r in range(startrev + 1, max):
for p in parentrevs(r):
if p in reachable:
if r not in stoprevs:
reachable[r] = 1
heads[r] = 1
if p in heads and p not in stoprevs:
del heads[p]
return [(repo.changelog.node(r), b"%d" % r) for r in heads]
def get_branches(ui,repo,heads_cache,marks_cache,mapping_cache,max):
h=heads(ui,repo,max=max)
stale=dict.fromkeys(heads_cache)
changed=[]
unchanged=[]
for node,rev in h:
_,_,user,(_,_),_,desc,branch,_=get_changeset(ui,repo,rev)
del stale[branch]
git_sha1=get_git_sha1(branch)
cache_sha1=marks_cache.get(b"%d" % (int(rev)+1))
if git_sha1!=None and git_sha1==cache_sha1:
unchanged.append([branch,cache_sha1,rev,desc.split(b'\n')[0],user])
else:
changed.append([branch,cache_sha1,rev,desc.split(b'\n')[0],user])
changed.sort()
unchanged.sort()
return stale,changed,unchanged
def get_tags(ui,repo,marks_cache,mapping_cache,max):
l=repo.tagslist()
good,bad=[],[]
for tag,node in l:
if tag==b'tip': continue
rev=int(mapping_cache[hexlify(node)])
cache_sha1=marks_cache.get(b"%d" % (int(rev)+1))
_,_,user,(_,_),_,desc,branch,_=get_changeset(ui,repo,rev)
if int(rev)>int(max):
bad.append([tag,branch,cache_sha1,rev,desc.split(b'\n')[0],user])
else:
good.append([tag,branch,cache_sha1,rev,desc.split(b'\n')[0],user])
good.sort()
bad.sort()
return good,bad
def mangle_mark(mark):
return b"%d" % (int(mark)-1)
if __name__=='__main__':
def bail(parser,opt):
sys.stderr.write('Error: No option %s given\n' % opt)
parser.print_help()
sys.exit(2)
parser=OptionParser()
parser.add_option("--marks",dest="marksfile",
help="File to read git-fast-import's marks from")
parser.add_option("--mapping",dest="mappingfile",
help="File to read last run's hg-to-git SHA1 mapping")
parser.add_option("--heads",dest="headsfile",
help="File to read last run's git heads from")
parser.add_option("--status",dest="statusfile",
help="File to read status from")
parser.add_option("-r","--repo",dest="repourl",
help="URL of repo to import")
parser.add_option("-R","--revision",type=int,dest="revision",
help="Revision to reset to")
(options,args)=parser.parse_args()
if options.marksfile==None: bail(parser,'--marks option')
if options.mappingfile==None: bail(parser,'--mapping option')
if options.headsfile==None: bail(parser,'--heads option')
if options.statusfile==None: bail(parser,'--status option')
if options.repourl==None: bail(parser,'--repo option')
if options.revision==None: bail(parser,'-R/--revision')
heads_cache=load_cache(options.headsfile)
marks_cache=load_cache(options.marksfile,mangle_mark)
state_cache=load_cache(options.statusfile)
mapping_cache = load_cache(options.mappingfile)
l=int(state_cache.get(b'tip',options.revision))
if options.revision+1>l:
sys.stderr.write('Revision is beyond last revision imported: %d>%d\n' % (options.revision,l))
sys.exit(1)
ui,repo=setup_repo(options.repourl)
stale,changed,unchanged=get_branches(ui,repo,heads_cache,marks_cache,mapping_cache,options.revision+1)
good,bad=get_tags(ui,repo,marks_cache,mapping_cache,options.revision+1)
print("Possibly stale branches:")
for b in stale:
sys.stdout.write('\t%s\n' % b.decode('utf8'))
print("Possibly stale tags:")
for b in bad:
sys.stdout.write(
'\t%s on %s (r%s)\n'
% (b[0].decode('utf8'), b[1].decode('utf8'), b[3].decode('utf8'))
)
print("Unchanged branches:")
for b in unchanged:
sys.stdout.write('\t%s (r%s)\n' % (b[0].decode('utf8'),b[2].decode('utf8')))
print("Unchanged tags:")
for b in good:
sys.stdout.write(
'\t%s on %s (r%s)\n'
% (b[0].decode('utf8'), b[1].decode('utf8'), b[3].decode('utf8'))
)
print("Reset branches in '%s' to:" % options.headsfile)
for b in changed:
sys.stdout.write(
'\t:%s %s\n\t\t(r%s: %s: %s)\n'
% (
b[0].decode('utf8'),
b[1].decode('utf8'),
b[2].decode('utf8'),
b[4].decode('utf8'),
b[3].decode('utf8'),
)
)
print("Reset ':tip' in '%s' to '%d'" % (options.statusfile,options.revision))