From 8aff9df2c37a9c5ad4754a3d787b6fbf727fea88 Mon Sep 17 00:00:00 2001 From: Rocco Rutte Date: Mon, 19 Mar 2007 09:04:42 +0000 Subject: [PATCH] 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 --- hg-reset.py | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hg-reset.sh | 64 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100755 hg-reset.py create mode 100755 hg-reset.sh diff --git a/hg-reset.py b/hg-reset.py new file mode 100755 index 0000000..8e1fa87 --- /dev/null +++ b/hg-reset.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python + +# Copyright (c) 2007 Rocco Rutte +# License: MIT + +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) diff --git a/hg-reset.sh b/hg-reset.sh new file mode 100755 index 0000000..4204005 --- /dev/null +++ b/hg-reset.sh @@ -0,0 +1,64 @@ +#!/bin/sh + +# Copyright (c) 2007 Rocco Rutte +# License: MIT + +ROOT="`dirname $0`" +REPO="" +PFX="hg2git" +SFX_MARKS="marks" +SFX_HEADS="heads" +SFX_STATE="state" +QUIET="" + +USAGE="[-r ] -R " +LONG_USAGE="Print SHA1s of latest changes per branch up to useful +to reset import and restart at . +If 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 $? -- 2.11.4.GIT