HG tag movement is now supported with this patch.
This patch creates a .git/hg2git-mapping file, which maps
HG revision numbers to HG hashes. Combined with the
.git/hg2git-marks file, which maps HG revisions to GIT hashes,
we can now reprocess all tags at the end of each hg export
operation.
count=0
max=len(files)
for file in files:
count=0
max=len(files)
for file in files:
+ # Skip .hgtags files. They only get us in trouble.
+ if file == ".hgtags":
+ sys.stderr.write('Skip %s\n' % (file))
+ continue
d=ctx.filectx(file).data()
wr('M %s inline %s' % (gitmode(manifest.flags(file)),file))
wr('data %d' % len(d)) # had some trouble with size()
d=ctx.filectx(file).data()
wr('M %s inline %s' % (gitmode(manifest.flags(file)),file))
wr('data %d' % len(d)) # had some trouble with size()
sys.stderr.write('Warning: sanitized %s [%s] to [%s]\n' % (what,name,n))
return n
sys.stderr.write('Warning: sanitized %s [%s] to [%s]\n' % (what,name,n))
return n
-def export_commit(ui,repo,revision,marks,heads,last,max,count,authors,sob,brmap):
+def export_commit(ui,repo,revision,marks,mapping,heads,last,max,count,authors,sob,brmap):
def get_branchname(name):
if brmap.has_key(name):
return brmap[name]
def get_branchname(name):
if brmap.has_key(name):
return brmap[name]
-def export_tags(ui,repo,marks_cache,start,end,count,authors):
+def export_tags(ui,repo,marks_cache,mapping_cache,count,authors):
l=repo.tagslist()
for tag,node in l:
tag=sanitize_name(tag,"tag")
# ignore latest revision
if tag=='tip': continue
l=repo.tagslist()
for tag,node in l:
tag=sanitize_name(tag,"tag")
# ignore latest revision
if tag=='tip': continue
- rev=repo.changelog.rev(node)
- # ignore those tags not in our import range
- if rev<start or rev>=end: continue
+ # ignore tags to nodes that are missing (ie, 'in the future')
+ if node.encode('hex_codec') not in mapping_cache:
+ sys.stderr.write('Tag %s refers to unseen node %s\n' % (tag, node.encode('hex_codec')))
+ continue
+
+ rev=int(mapping_cache[node.encode('hex_codec')])
- ref=get_parent_mark(rev,marks_cache)
+ ref=marks_cache.get(str(rev),':%d' % (rev))
if ref==None:
sys.stderr.write('Failed to find reference for creating tag'
' %s at r%d\n' % (tag,rev))
if ref==None:
sys.stderr.write('Failed to find reference for creating tag'
' %s at r%d\n' % (tag,rev))
def mangle_mark(mark):
return str(int(mark)-1)
def mangle_mark(mark):
return str(int(mark)-1)
-def hg2git(repourl,m,marksfile,headsfile,tipfile,authors={},sob=False,force=False):
+def hg2git(repourl,m,marksfile,mappingfile,headsfile,tipfile,authors={},sob=False,force=False):
_max=int(m)
marks_cache=load_cache(marksfile,mangle_mark)
_max=int(m)
marks_cache=load_cache(marksfile,mangle_mark)
+ mapping_cache=load_cache(mappingfile)
heads_cache=load_cache(headsfile)
state_cache=load_cache(tipfile)
heads_cache=load_cache(headsfile)
state_cache=load_cache(tipfile)
if _max<0 or max>tip:
max=tip
if _max<0 or max>tip:
max=tip
+ for rev in range(0,max):
+ (revnode,_,_,_,_,_,_,_)=get_changeset(ui,repo,rev,authors)
+ mapping_cache[revnode.encode('hex_codec')] = str(rev)
+
+
c=0
last={}
brmap={}
for rev in range(min,max):
c=0
last={}
brmap={}
for rev in range(min,max):
- c=export_commit(ui,repo,rev,marks_cache,heads_cache,last,max,c,authors,sob,brmap)
-
- c=export_tags(ui,repo,marks_cache,min,max,c,authors)
-
- sys.stderr.write('Issued %d commands\n' % c)
+ c=export_commit(ui,repo,rev,marks_cache,mapping_cache,heads_cache,last,max,c,authors,sob,brmap)
state_cache['tip']=max
state_cache['repo']=repourl
save_cache(tipfile,state_cache)
state_cache['tip']=max
state_cache['repo']=repourl
save_cache(tipfile,state_cache)
+ save_cache(mappingfile,mapping_cache)
+
+ c=export_tags(ui,repo,marks_cache,mapping_cache,c,authors)
+
+ sys.stderr.write('Issued %d commands\n' % c)
parser.add_option("-m","--max",type="int",dest="max",
help="Maximum hg revision to import")
parser.add_option("-m","--max",type="int",dest="max",
help="Maximum hg revision to import")
+ parser.add_option("--mapping",dest="mappingfile",
+ help="File to read last run's hg-to-git SHA1 mapping")
parser.add_option("--marks",dest="marksfile",
help="File to read git-fast-import's marks from")
parser.add_option("--heads",dest="headsfile",
parser.add_option("--marks",dest="marksfile",
help="File to read git-fast-import's marks from")
parser.add_option("--heads",dest="headsfile",
if options.max!=None: m=options.max
if options.marksfile==None: bail(parser,'--marks')
if options.max!=None: m=options.max
if options.marksfile==None: bail(parser,'--marks')
+ if options.mappingfile==None: bail(parser,'--mapping')
if options.headsfile==None: bail(parser,'--heads')
if options.statusfile==None: bail(parser,'--status')
if options.repourl==None: bail(parser,'--repo')
if options.headsfile==None: bail(parser,'--heads')
if options.statusfile==None: bail(parser,'--status')
if options.repourl==None: bail(parser,'--repo')
if options.default_branch!=None:
set_default_branch(options.default_branch)
if options.default_branch!=None:
set_default_branch(options.default_branch)
- sys.exit(hg2git(options.repourl,m,options.marksfile,options.headsfile,
+ sys.exit(hg2git(options.repourl,m,options.marksfile,options.mappingfile,options.headsfile,
options.statusfile,authors=a,sob=options.sob,force=options.force))
options.statusfile,authors=a,sob=options.sob,force=options.force))
ROOT="`dirname $0`"
REPO=""
PFX="hg2git"
ROOT="`dirname $0`"
REPO=""
PFX="hg2git"
SFX_MARKS="marks"
SFX_HEADS="heads"
SFX_STATE="state"
SFX_MARKS="marks"
SFX_HEADS="heads"
SFX_STATE="state"
GIT_DIR="$GIT_DIR" $PYTHON "$ROOT/hg-fast-export.py" \
--repo "$REPO" \
--marks "$GIT_DIR/$PFX-$SFX_MARKS" \
GIT_DIR="$GIT_DIR" $PYTHON "$ROOT/hg-fast-export.py" \
--repo "$REPO" \
--marks "$GIT_DIR/$PFX-$SFX_MARKS" \
+ --mapping "$GIT_DIR/$PFX-$SFX_MAPPING" \
--heads "$GIT_DIR/$PFX-$SFX_HEADS" \
--status "$GIT_DIR/$PFX-$SFX_STATE" \
"$@" \
--heads "$GIT_DIR/$PFX-$SFX_HEADS" \
--status "$GIT_DIR/$PFX-$SFX_STATE" \
"$@" \
-| git fast-import $QUIET --export-marks="$GIT_DIR/$PFX-$SFX_MARKS.tmp" \
-|| die 'Git fast-import failed'
+| git fast-import $QUIET --export-marks="$GIT_DIR/$PFX-$SFX_MARKS.tmp"
# move recent marks cache out of the way...
if [ -f "$GIT_DIR/$PFX-$SFX_MARKS" ] ; then
# move recent marks cache out of the way...
if [ -f "$GIT_DIR/$PFX-$SFX_MARKS" ] ; then
return [(repo.changelog.node(r),str(r)) for r in heads]
return [(repo.changelog.node(r),str(r)) for r in heads]
-def get_branches(ui,repo,heads_cache,marks_cache,max):
+def get_branches(ui,repo,heads_cache,marks_cache,mapping_cache,max):
h=heads(ui,repo,max=max)
stale=dict.fromkeys(heads_cache)
changed=[]
h=heads(ui,repo,max=max)
stale=dict.fromkeys(heads_cache)
changed=[]
unchanged.sort()
return stale,changed,unchanged
unchanged.sort()
return stale,changed,unchanged
-def get_tags(ui,repo,marks_cache,max):
+def get_tags(ui,repo,marks_cache,mapping_cache,max):
l=repo.tagslist()
good,bad=[],[]
for tag,node in l:
if tag=='tip': continue
l=repo.tagslist()
good,bad=[],[]
for tag,node in l:
if tag=='tip': continue
- rev=repo.changelog.rev(node)
+ rev=int(mapping_cache[node.encode('hex_codec')])
cache_sha1=marks_cache.get(str(int(rev)+1))
_,_,user,(_,_),_,desc,branch,_=get_changeset(ui,repo,rev)
if int(rev)>int(max):
cache_sha1=marks_cache.get(str(int(rev)+1))
_,_,user,(_,_),_,desc,branch,_=get_changeset(ui,repo,rev)
if int(rev)>int(max):
ui,repo=setup_repo(options.repourl)
ui,repo=setup_repo(options.repourl)
- stale,changed,unchanged=get_branches(ui,repo,heads_cache,marks_cache,options.revision+1)
- good,bad=get_tags(ui,repo,marks_cache,options.revision+1)
+ 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:"
map(lambda b: sys.stdout.write('\t%s\n' % b),stale.keys())
print "Possibly stale branches:"
map(lambda b: sys.stdout.write('\t%s\n' % b),stale.keys())
REPO=""
PFX="hg2git"
SFX_MARKS="marks"
REPO=""
PFX="hg2git"
SFX_MARKS="marks"
SFX_HEADS="heads"
SFX_STATE="state"
QUIET=""
SFX_HEADS="heads"
SFX_STATE="state"
QUIET=""
GIT_DIR="$GIT_DIR" $PYTHON "$ROOT/hg-reset.py" \
--repo "$REPO" \
--marks "$GIT_DIR/$PFX-$SFX_MARKS" \
GIT_DIR="$GIT_DIR" $PYTHON "$ROOT/hg-reset.py" \
--repo "$REPO" \
--marks "$GIT_DIR/$PFX-$SFX_MARKS" \
+ --mapping "$GIT_DIR/$PFX-$SFX_MAPPING" \
--heads "$GIT_DIR/$PFX-$SFX_HEADS" \
--status "$GIT_DIR/$PFX-$SFX_STATE" \
"$@"
--heads "$GIT_DIR/$PFX-$SFX_HEADS" \
--status "$GIT_DIR/$PFX-$SFX_STATE" \
"$@"