2828# write some progress message every this many file contents written
2929cfg_export_boundary = 1000
3030
31+ subrepo_cache = {}
32+ submodule_mappings = None
33+
3134def gitmode (flags ):
3235 return 'l' in flags and '120000' or 'x' in flags and '100755' or '100644'
3336
@@ -128,6 +131,48 @@ def export_file_contents(ctx,manifest,files,hgtags,encoding='',plugins={}):
128131 count = 0
129132 max = len (files )
130133 for file in files :
134+ if submodule_mappings and ctx .substate and file == ".hgsubstate" :
135+ # Remove all submodules as we don't detect deleted submodules properly
136+ # in any other way. We will add the ones not deleted back again below.
137+ for module in submodule_mappings .keys ():
138+ wr ('D %s' % module )
139+
140+ # Read .hgsubstate file in order to find the revision of each subrepo
141+ data = ctx .filectx (file ).data ()
142+ subHashes = {}
143+ for line in data .split ('\n ' ):
144+ if line .strip ()== "" :
145+ continue
146+ cols = line .split (' ' )
147+ subHashes [cols [1 ]]= cols [0 ]
148+
149+ gitmodules = ""
150+ # Create the .gitmodules file and all submodules
151+ for name in ctx .substate :
152+ gitRepoLocation = submodule_mappings [name ] + "/.git"
153+
154+ # Populate the cache to map mercurial revision to git revision
155+ if not name in subrepo_cache :
156+ subrepo_cache [name ]= (load_cache (gitRepoLocation + "/hg2git-mapping" ),
157+ load_cache (gitRepoLocation + "/hg2git-marks" ,
158+ lambda s : int (s )- 1 ))
159+
160+ (mapping_cache , marks_cache )= subrepo_cache [name ]
161+ if subHashes [name ] in mapping_cache :
162+ revnum = mapping_cache [subHashes [name ]]
163+ gitSha = marks_cache [int (revnum )]
164+ wr ('M 160000 %s %s' % (gitSha , name ))
165+ sys .stderr .write ("Adding submodule %s, revision %s->%s\n "
166+ % (name ,subHashes [name ],gitSha ))
167+ gitmodules += '[submodule "%s"]\n \t path = %s\n \t url = %s\n ' % (name , name , submodule_mappings [name ])
168+ else :
169+ sys .stderr .write ("Warning: Could not find hg revision %s for %s in git %s\n " % (subHashes [name ],name ,gitRepoLocation ))
170+
171+ if len (gitmodules ):
172+ wr ('M 100644 inline .gitmodules' )
173+ wr ('data %d' % (len (gitmodules )+ 1 ))
174+ wr (gitmodules )
175+
131176 # Skip .hgtags files. They only get us in trouble.
132177 if not hgtags and file == ".hgtags" :
133178 sys .stderr .write ('Skip %s\n ' % (file ))
@@ -443,6 +488,15 @@ def check_cache(filename, contents):
443488 (revnode ,_ ,_ ,_ ,_ ,_ ,_ ,_ )= get_changeset (ui ,repo ,rev ,authors )
444489 mapping_cache [revnode .encode ('hex_codec' )] = str (rev )
445490
491+ if submodule_mappings :
492+ # Make sure that all submodules are registered in the submodule-mappings file
493+ for rev in range (0 ,max ):
494+ ctx = revsymbol (repo ,str (rev ))
495+ if ctx .substate :
496+ for key in ctx .substate :
497+ if key not in submodule_mappings :
498+ sys .stderr .write ("Error: %s not found in submodule-mappings\n " % (key ))
499+ return 1
446500
447501 c = 0
448502 brmap = {}
@@ -515,6 +569,8 @@ def bail(parser,opt):
515569 help = "Additional search path for plugins " )
516570 parser .add_option ("--plugin" , action = "append" , type = "string" , dest = "plugins" ,
517571 help = "Add a plugin with the given init string <name=init>" )
572+ parser .add_option ("--subrepo-map" , type = "string" , dest = "subrepo_map" ,
573+ help = "Provide a mapping file between the subrepository name and the submodule name" )
518574
519575 (options ,args )= parser .parse_args ()
520576
@@ -527,6 +583,14 @@ def bail(parser,opt):
527583 if options .statusfile == None : bail (parser ,'--status' )
528584 if options .repourl == None : bail (parser ,'--repo' )
529585
586+ if options .subrepo_map :
587+ if not os .path .exists (options .subrepo_map ):
588+ sys .stderr .write ('Subrepo mapping file not found %s\n '
589+ % options .subrepo_map )
590+ sys .exit (1 )
591+ submodule_mappings = load_mapping ('subrepo mappings' ,
592+ options .subrepo_map ,False )
593+
530594 a = {}
531595 if options .authorfile != None :
532596 a = load_mapping ('authors' , options .authorfile , options .raw_mappings )
0 commit comments