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>
This commit is contained in:
		 Felipe Contreras
					Felipe Contreras
				
			
				
					committed by
					
						 Junio C Hamano
						Junio C Hamano
					
				
			
			
				
	
			
			
			 Junio C Hamano
						Junio C Hamano
					
				
			
						parent
						
							ab64bc9d21
						
					
				
				
					commit
					ba091c200d
				
			| @ -973,6 +973,15 @@ def push(repo, remote, parsed_refs, p_revs): | ||||
|  | ||||
|     return ret | ||||
|  | ||||
| def check_tip(ref, kind, name, heads): | ||||
|     try: | ||||
|         ename = '%s/%s' % (kind, name) | ||||
|         tip = marks.get_tip(ename) | ||||
|     except KeyError: | ||||
|         return True | ||||
|     else: | ||||
|         return tip in heads | ||||
|  | ||||
| def do_export(parser): | ||||
|     global parsed_refs, bmarks, peer | ||||
|  | ||||
| @ -995,6 +1004,8 @@ def do_export(parser): | ||||
|         else: | ||||
|             die('unhandled export command: %s' % line) | ||||
|  | ||||
|     need_fetch = False | ||||
|  | ||||
|     for ref, node in parsed_refs.iteritems(): | ||||
|         bnode = hgbin(node) | ||||
|         if ref.startswith('refs/heads/branches'): | ||||
| @ -1002,6 +1013,16 @@ def do_export(parser): | ||||
|             if branch in branches and bnode in branches[branch]: | ||||
|                 # up to date | ||||
|                 continue | ||||
|  | ||||
|             if peer: | ||||
|                 remotemap = peer.branchmap() | ||||
|                 if remotemap and branch in remotemap: | ||||
|                     heads = [hghex(e) for e in remotemap[branch]] | ||||
|                     if not check_tip(ref, 'branches', branch, heads): | ||||
|                         print "error %s fetch first" % ref | ||||
|                         need_fetch = True | ||||
|                         continue | ||||
|  | ||||
|             p_revs[bnode] = ref | ||||
|             print "ok %s" % ref | ||||
|         elif ref.startswith('refs/heads/'): | ||||
| @ -1017,6 +1038,14 @@ def do_export(parser): | ||||
|                     not (bmark == 'master' and bmark not in parser.repo._bookmarks): | ||||
|                 p_bmarks.append((ref, bmark, old, new)) | ||||
|  | ||||
|             if peer: | ||||
|                 remote_old = peer.listkeys('bookmarks').get(bmark) | ||||
|                 if remote_old: | ||||
|                     if not check_tip(ref, 'bookmarks', bmark, remote_old): | ||||
|                         print "error %s fetch first" % ref | ||||
|                         need_fetch = True | ||||
|                         continue | ||||
|  | ||||
|             p_revs[bnode] = ref | ||||
|         elif ref.startswith('refs/tags/'): | ||||
|             tag = ref[len('refs/tags/'):] | ||||
| @ -1037,6 +1066,16 @@ def do_export(parser): | ||||
|             # transport-helper/fast-export bugs | ||||
|             continue | ||||
|  | ||||
|     if need_fetch: | ||||
|         print | ||||
|         return | ||||
|  | ||||
|     if dry_run: | ||||
|         if peer and not force_push: | ||||
|             checkheads(parser.repo, peer, p_revs) | ||||
|         print | ||||
|         return | ||||
|  | ||||
|     if peer: | ||||
|         if not push(parser.repo, peer, parsed_refs, p_revs): | ||||
|             # do not update bookmarks | ||||
|  | ||||
| @ -65,6 +65,9 @@ check_push () { | ||||
| 		'non-fast-forward') | ||||
| 			grep "^ ! \[rejected\] *${branch} -> ${branch} (non-fast-forward)$" error || ref_ret=1 | ||||
| 			;; | ||||
| 		'fetch-first') | ||||
| 			grep "^ ! \[rejected\] *${branch} -> ${branch} (fetch first)$" error || ref_ret=1 | ||||
| 			;; | ||||
| 		'') | ||||
| 			grep "^   [a-f0-9]*\.\.[a-f0-9]* *${branch} -> ${branch}$" error || ref_ret=1 | ||||
| 			;; | ||||
| @ -407,7 +410,7 @@ test_expect_success 'remote update bookmark diverge' ' | ||||
| 	echo diverge > content && | ||||
| 	git commit -a -m diverge && | ||||
| 	check_push 1 <<-EOF | ||||
| 	diverge:non-fast-forward | ||||
| 	diverge:fetch-first | ||||
| 	EOF | ||||
| 	) && | ||||
|  | ||||
| @ -525,6 +528,72 @@ test_expect_success 'remote big push' ' | ||||
| 	check_bookmark hgrepo new_bmark '' | ||||
| ' | ||||
|  | ||||
| test_expect_success 'remote big push fetch first' ' | ||||
| 	test_when_finished "rm -rf hgrepo gitrepo*" && | ||||
|  | ||||
| 	( | ||||
| 	hg init hgrepo && | ||||
| 	cd hgrepo && | ||||
| 	echo zero > content && | ||||
| 	hg add content && | ||||
| 	hg commit -m zero && | ||||
| 	hg bookmark bad_bmark && | ||||
| 	hg bookmark good_bmark && | ||||
| 	hg bookmark -i good_bmark && | ||||
| 	hg -q branch good_branch && | ||||
| 	echo "good branch" > content && | ||||
| 	hg commit -m "good branch" && | ||||
| 	hg -q branch bad_branch && | ||||
| 	echo "bad branch" > content && | ||||
| 	hg commit -m "bad branch" | ||||
| 	) && | ||||
|  | ||||
| 	git clone "hg::hgrepo" gitrepo && | ||||
|  | ||||
| 	( | ||||
| 	cd hgrepo && | ||||
| 	hg bookmark -f bad_bmark && | ||||
| 	echo update_bmark > content && | ||||
| 	hg commit -m "update bmark" | ||||
| 	) && | ||||
|  | ||||
| 	( | ||||
| 	cd gitrepo && | ||||
| 	echo two > content && | ||||
| 	git commit -q -a -m two && | ||||
|  | ||||
| 	git checkout -q good_bmark && | ||||
| 	echo three > content && | ||||
| 	git commit -q -a -m three && | ||||
|  | ||||
| 	git checkout -q bad_bmark && | ||||
| 	echo four > content && | ||||
| 	git commit -q -a -m four && | ||||
|  | ||||
| 	git checkout -q branches/bad_branch && | ||||
| 	echo five > content && | ||||
| 	git commit -q -a -m five && | ||||
|  | ||||
| 	check_push 1 --all <<-EOF | ||||
| 	master | ||||
| 	good_bmark | ||||
| 	new_bmark:new | ||||
| 	new_branch:new | ||||
| 	bad_bmark:fetch-first | ||||
| 	branches/bad_branch:festch-first | ||||
| 	EOF | ||||
|  | ||||
| 	git fetch && | ||||
|  | ||||
| 	check_push 1 --all <<-EOF | ||||
| 	master | ||||
| 	good_bmark | ||||
| 	bad_bmark:non-fast-forward | ||||
| 	branches/bad_branch:non-fast-forward | ||||
| 	EOF | ||||
| 	) | ||||
| ' | ||||
|  | ||||
| test_expect_success 'remote double failed push' ' | ||||
| 	test_when_finished "rm -rf hgrepo gitrepo*" && | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user