@@ -16,6 +16,22 @@ import sys
16
16
import os
17
17
import json
18
18
import shutil
19
+ import subprocess
20
+
21
+ #
22
+ # If you want to switch to hg-git compatibility mode:
23
+ # git config --global remote-hg.hg-git-compat true
24
+ #
25
+ # git:
26
+ # Sensible defaults for git.
27
+ # hg bookmarks are exported as git branches, hg branches are prefixed
28
+ # with 'branches/'.
29
+ #
30
+ # hg:
31
+ # Emulate hg-git.
32
+ # Only hg bookmarks are exported as git branches.
33
+ # Commits are modified to preserve hg information and allow biridectionality.
34
+ #
19
35
20
36
NAME_RE = re .compile ('^([^<>]+)' )
21
37
AUTHOR_RE = re .compile ('^([^<>]+?)? ?<([^<>]+)>$' )
@@ -226,7 +242,7 @@ def mark_to_rev(mark):
226
242
return marks .to_rev (mark )
227
243
228
244
def export_ref (repo , name , kind , head ):
229
- global prefix , marks
245
+ global prefix , marks , mode
230
246
231
247
ename = '%s/%s' % (kind , name )
232
248
tip = marks .get_tip (ename )
@@ -261,6 +277,33 @@ def export_ref(repo, name, kind, head):
261
277
else :
262
278
modified , removed = get_filechanges (repo , c , parents [0 ])
263
279
280
+ if mode == 'hg' :
281
+ extra_msg = ''
282
+
283
+ if rev_branch != 'default' :
284
+ extra_msg += 'branch : %s\n ' % rev_branch
285
+
286
+ renames = []
287
+ for f in c .files ():
288
+ if f not in c .manifest ():
289
+ continue
290
+ rename = c .filectx (f ).renamed ()
291
+ if rename :
292
+ renames .append ((rename [0 ], f ))
293
+
294
+ for e in renames :
295
+ extra_msg += "rename : %s => %s\n " % e
296
+
297
+ for key , value in extra .iteritems ():
298
+ if key in ('author' , 'committer' , 'encoding' , 'message' , 'branch' , 'hg-git' ):
299
+ continue
300
+ else :
301
+ extra_msg += "extra : %s : %s\n " % (key , urllib .quote (value ))
302
+
303
+ desc += '\n '
304
+ if extra_msg :
305
+ desc += '\n --HG--\n ' + extra_msg
306
+
264
307
if len (parents ) == 0 and rev :
265
308
print 'reset %s/%s' % (prefix , ename )
266
309
@@ -354,7 +397,7 @@ def list_head(repo, cur):
354
397
g_head = (head , node )
355
398
356
399
def do_list (parser ):
357
- global branches , bmarks
400
+ global branches , bmarks , mode
358
401
359
402
repo = parser .repo
360
403
for branch in repo .branchmap ():
@@ -368,8 +411,11 @@ def do_list(parser):
368
411
cur = repo .dirstate .branch ()
369
412
370
413
list_head (repo , cur )
371
- for branch in branches :
372
- print "? refs/heads/branches/%s" % branch
414
+
415
+ if mode != 'hg' :
416
+ for branch in branches :
417
+ print "? refs/heads/branches/%s" % branch
418
+
373
419
for bmark in bmarks :
374
420
print "? refs/heads/%s" % bmark
375
421
@@ -437,6 +483,7 @@ def get_merge_files(repo, p1, p2, files):
437
483
438
484
def parse_commit (parser ):
439
485
global marks , blob_marks , bmarks , parsed_refs
486
+ global mode
440
487
441
488
from_mark = merge_mark = None
442
489
@@ -482,7 +529,9 @@ def parse_commit(parser):
482
529
return of ['ctx' ]
483
530
is_exec = of ['mode' ] == 'x'
484
531
is_link = of ['mode' ] == 'l'
485
- return context .memfilectx (f , of ['data' ], is_link , is_exec , None )
532
+ rename = of .get ('rename' , None )
533
+ return context .memfilectx (f , of ['data' ],
534
+ is_link , is_exec , rename )
486
535
487
536
repo = parser .repo
488
537
@@ -509,6 +558,21 @@ def parse_commit(parser):
509
558
if merge_mark :
510
559
get_merge_files (repo , p1 , p2 , files )
511
560
561
+ if mode == 'hg' :
562
+ i = data .find ('\n --HG--\n ' )
563
+ if i >= 0 :
564
+ tmp = data [i + len ('\n --HG--\n ' ):].strip ()
565
+ for k , v in [e .split (' : ' ) for e in tmp .split ('\n ' )]:
566
+ if k == 'rename' :
567
+ old , new = v .split (' => ' , 1 )
568
+ files [new ]['rename' ] = old
569
+ elif k == 'branch' :
570
+ extra [k ] = v
571
+ elif k == 'extra' :
572
+ ek , ev = v .split (' : ' , 1 )
573
+ extra [ek ] = urllib .unquote (ev )
574
+ data = data [:i ]
575
+
512
576
ctx = context .memctx (repo , (p1 , p2 ), data ,
513
577
files .keys (), getfilectx ,
514
578
user , (date , tz ), extra )
@@ -596,12 +660,25 @@ def do_export(parser):
596
660
def main (args ):
597
661
global prefix , dirname , branches , bmarks
598
662
global marks , blob_marks , parsed_refs
599
- global peer
663
+ global peer , mode
600
664
601
665
alias = args [1 ]
602
666
url = args [2 ]
603
667
peer = None
604
668
669
+ cmd = ['git' , 'config' , '--get' , 'remote-hg.hg-git-compat' ]
670
+ hg_git_compat = False
671
+ try :
672
+ if subprocess .check_output (cmd ) == 'true\n ' :
673
+ hg_git_compat = True
674
+ except subprocess .CalledProcessError :
675
+ pass
676
+
677
+ if hg_git_compat :
678
+ mode = 'hg'
679
+ else :
680
+ mode = 'git'
681
+
605
682
if alias [4 :] == url :
606
683
is_tmp = True
607
684
alias = util .sha1 (alias ).hexdigest ()
0 commit comments