hg-reset.sh: Helper for partially re-importing from hg

Given a hg revision to reset to, these scripts get the latest changes
per hg branch and print git SHA1. The user then needs to manually reset
branches as needed, tune the state file and can re-import things again.

Signed-off-by: Rocco Rutte <pdmef@gmx.net>
This commit is contained in:
Rocco Rutte
2007-03-19 09:04:42 +00:00
parent 7044bdd4d1
commit 8aff9df2c3
2 changed files with 155 additions and 0 deletions

91
hg-reset.py Executable file
View File

@@ -0,0 +1,91 @@
#!/usr/bin/env python
# Copyright (c) 2007 Rocco Rutte <pdmef@gmx.net>
# License: MIT <http://www.opensource.org/licenses/mit-license.php>
from mercurial import repo,hg,cmdutil,util,ui,revlog,node
from hg2git import setup_repo,load_cache,get_changeset
from optparse import OptionParser
import sys
def heads(ui,repo,start=None,stop=None,max=None):
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 xrange(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),str(r)) for r in heads]
def get_branches(ui,repo,heads_cache,marks_cache,max):
h=heads(ui,repo,max=max)
old=dict.fromkeys(heads_cache)
r=[]
for node,rev in h:
_,_,user,(_,_),_,desc,branch,_=get_changeset(ui,repo,rev)
del old[branch]
r.append([branch,marks_cache.get(str(int(rev)+1)),rev,desc.split('\n')[0],user])
r.sort()
return old,r
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("--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.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)
state_cache=load_cache(options.statusfile)
l=int(state_cache.get('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=get_branches(ui,repo,heads_cache,marks_cache,options.revision+1)
print "Possibly stale branches:"
map(lambda b: sys.stdout.write('\t%s\n' % b),stale.keys())
print "Reset branches in '%s' to:" % options.headsfile
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)
print "Reset ':tip' in '%s' to '%d'" % (options.statusfile,options.revision)

64
hg-reset.sh Executable file
View File

@@ -0,0 +1,64 @@
#!/bin/sh
# Copyright (c) 2007 Rocco Rutte <pdmef@gmx.net>
# License: MIT <http://www.opensource.org/licenses/mit-license.php>
ROOT="`dirname $0`"
REPO=""
PFX="hg2git"
SFX_MARKS="marks"
SFX_HEADS="heads"
SFX_STATE="state"
QUIET=""
USAGE="[-r <repo>] -R <rev>"
LONG_USAGE="Print SHA1s of latest changes per branch up to <rev> useful
to reset import and restart at <rev>.
If <repo> is omitted, use last hg repository as obtained from state file,
GIT_DIR/$PFX-$SFX_STATE by default.
Options:
-R Hg revision to reset to
-r Mercurial repository to use
"
. git-sh-setup
cd_to_toplevel
while case "$#" in 0) break ;; esac
do
case "$1" in
-r|--r|--re|--rep|--repo)
shift
REPO="$1"
;;
-*)
# pass any other options down to hg2git.py
break
;;
*)
break
;;
esac
shift
done
# for convenience: get default repo from state file
if [ x"$REPO" = x -a -f "$GIT_DIR/$PFX-$SFX_STATE" ] ; then
REPO="`egrep '^:repo ' "$GIT_DIR/$PFX-$SFX_STATE" | cut -d ' ' -f 2`"
echo "Using last hg repository \"$REPO\""
fi
# make sure we have a marks cache
if [ ! -f "$GIT_DIR/$PFX-$SFX_MARKS" ] ; then
touch "$GIT_DIR/$PFX-$SFX_MARKS"
fi
GIT_DIR="$GIT_DIR" python "$ROOT/hg-reset.py" \
--repo "$REPO" \
--marks "$GIT_DIR/$PFX-$SFX_MARKS" \
--heads "$GIT_DIR/$PFX-$SFX_HEADS" \
--status "$GIT_DIR/$PFX-$SFX_STATE" \
"$@"
exit $?