remote-hg: check if a fetch is needed
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Felipe Contreras committed
May 24, 2013 at 21:30 UTC
ba091c200d88b27a0bd9027f24a7250f196fc304
2 files changed
+109
-1
contrib/remote-helpers/git-remote-hg
+39
@@ -973,6 +973,15 @@ def push(repo, remote, parsed_refs, p_revs):
973
974
return ret
975
976
+def check_tip(ref, kind, name, heads):
977
+ try:
978
+ ename = '%s/%s' % (kind, name)
979
+ tip = marks.get_tip(ename)
980
+ except KeyError:
981
+ return True
982
+ else:
983
+ return tip in heads
984
+
985
def do_export(parser):
986
global parsed_refs, bmarks, peer
987
@@ -995,6 +1004,8 @@ def do_export(parser):
1004
else:
1005
die('unhandled export command: %s' % line)
1006
1007
+ need_fetch = False
1008
+
1009
for ref, node in parsed_refs.iteritems():
1010
bnode = hgbin(node)
1011
if ref.startswith('refs/heads/branches'):
@@ -1002,6 +1013,16 @@ def do_export(parser):
1013
if branch in branches and bnode in branches[branch]:
1014
# up to date
1015
continue
1016
+
1017
+ if peer:
1018
+ remotemap = peer.branchmap()
1019
+ if remotemap and branch in remotemap:
1020
+ heads = [hghex(e) for e in remotemap[branch]]
1021
+ if not check_tip(ref, 'branches', branch, heads):
1022
+ print "error %s fetch first" % ref
1023
+ need_fetch = True
1024
+ continue
1025
+
1026
p_revs[bnode] = ref
1027
print "ok %s" % ref
1028
elif ref.startswith('refs/heads/'):
@@ -1017,6 +1038,14 @@ def do_export(parser):
1038
not (bmark == 'master' and bmark not in parser.repo._bookmarks):
1039
p_bmarks.append((ref, bmark, old, new))
1040
1041
+ if peer:
1042
+ remote_old = peer.listkeys('bookmarks').get(bmark)
1043
+ if remote_old:
1044
+ if not check_tip(ref, 'bookmarks', bmark, remote_old):
1045
+ print "error %s fetch first" % ref
1046
+ need_fetch = True
1047
+ continue
1048
+
1049
p_revs[bnode] = ref
1050
elif ref.startswith('refs/tags/'):
1051
tag = ref[len('refs/tags/'):]
@@ -1037,6 +1066,16 @@ def do_export(parser):
1066
# transport-helper/fast-export bugs
1067
continue
1068
1069
+ if need_fetch:
1070
+ print
1071
+ return
1072
+
1073
+ if dry_run:
1074
+ if peer and not force_push:
1075
+ checkheads(parser.repo, peer, p_revs)
1076
+ print
1077
+ return
1078
+
1079
if peer:
1080
if not push(parser.repo, peer, parsed_refs, p_revs):
1081
# do not update bookmarks
contrib/remote-helpers/test-hg.sh
+70
-1
@@ -65,6 +65,9 @@ check_push () {
65
'non-fast-forward')
66
grep "^ ! \[rejected\] *${branch} -> ${branch} (non-fast-forward)$" error || ref_ret=1
67
;;
68
+ 'fetch-first')
69
+ grep "^ ! \[rejected\] *${branch} -> ${branch} (fetch first)$" error || ref_ret=1
70
+ ;;
71
'')
72
grep "^ [a-f0-9]*\.\.[a-f0-9]* *${branch} -> ${branch}$" error || ref_ret=1
73
;;
@@ -407,7 +410,7 @@ test_expect_success 'remote update bookmark diverge' '
410
echo diverge > content &&
411
git commit -a -m diverge &&
412
check_push 1 <<-EOF
410
- diverge:non-fast-forward
413
+ diverge:fetch-first
414
EOF
415
) &&
416
@@ -525,6 +528,72 @@ test_expect_success 'remote big push' '
528
check_bookmark hgrepo new_bmark ''
529
'
530
531
+test_expect_success 'remote big push fetch first' '
532
+ test_when_finished "rm -rf hgrepo gitrepo*" &&
533
+
534
+ (
535
+ hg init hgrepo &&
536
+ cd hgrepo &&
537
+ echo zero > content &&
538
+ hg add content &&
539
+ hg commit -m zero &&
540
+ hg bookmark bad_bmark &&
541
+ hg bookmark good_bmark &&
542
+ hg bookmark -i good_bmark &&
543
+ hg -q branch good_branch &&
544
+ echo "good branch" > content &&
545
+ hg commit -m "good branch" &&
546
+ hg -q branch bad_branch &&
547
+ echo "bad branch" > content &&
548
+ hg commit -m "bad branch"
549
+ ) &&
550
+
551
+ git clone "hg::hgrepo" gitrepo &&
552
+
553
+ (
554
+ cd hgrepo &&
555
+ hg bookmark -f bad_bmark &&
556
+ echo update_bmark > content &&
557
+ hg commit -m "update bmark"
558
+ ) &&
559
+
560
+ (
561
+ cd gitrepo &&
562
+ echo two > content &&
563
+ git commit -q -a -m two &&
564
+
565
+ git checkout -q good_bmark &&
566
+ echo three > content &&
567
+ git commit -q -a -m three &&
568
+
569
+ git checkout -q bad_bmark &&
570
+ echo four > content &&
571
+ git commit -q -a -m four &&
572
+
573
+ git checkout -q branches/bad_branch &&
574
+ echo five > content &&
575
+ git commit -q -a -m five &&
576
+
577
+ check_push 1 --all <<-EOF
578
+ master
579
+ good_bmark
580
+ new_bmark:new
581
+ new_branch:new
582
+ bad_bmark:fetch-first
583
+ branches/bad_branch:festch-first
584
+ EOF
585
+
586
+ git fetch &&
587
+
588
+ check_push 1 --all <<-EOF
589
+ master
590
+ good_bmark
591
+ bad_bmark:non-fast-forward
592
+ branches/bad_branch:non-fast-forward
593
+ EOF
594
+ )
595
+'
596
+
597
test_expect_success 'remote double failed push' '
598
test_when_finished "rm -rf hgrepo gitrepo*" &&
599