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 |     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): | def do_export(parser): | ||||||
|     global parsed_refs, bmarks, peer |     global parsed_refs, bmarks, peer | ||||||
|  |  | ||||||
| @ -995,6 +1004,8 @@ def do_export(parser): | |||||||
|         else: |         else: | ||||||
|             die('unhandled export command: %s' % line) |             die('unhandled export command: %s' % line) | ||||||
|  |  | ||||||
|  |     need_fetch = False | ||||||
|  |  | ||||||
|     for ref, node in parsed_refs.iteritems(): |     for ref, node in parsed_refs.iteritems(): | ||||||
|         bnode = hgbin(node) |         bnode = hgbin(node) | ||||||
|         if ref.startswith('refs/heads/branches'): |         if ref.startswith('refs/heads/branches'): | ||||||
| @ -1002,6 +1013,16 @@ def do_export(parser): | |||||||
|             if branch in branches and bnode in branches[branch]: |             if branch in branches and bnode in branches[branch]: | ||||||
|                 # up to date |                 # up to date | ||||||
|                 continue |                 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 |             p_revs[bnode] = ref | ||||||
|             print "ok %s" % ref |             print "ok %s" % ref | ||||||
|         elif ref.startswith('refs/heads/'): |         elif ref.startswith('refs/heads/'): | ||||||
| @ -1017,6 +1038,14 @@ def do_export(parser): | |||||||
|                     not (bmark == 'master' and bmark not in parser.repo._bookmarks): |                     not (bmark == 'master' and bmark not in parser.repo._bookmarks): | ||||||
|                 p_bmarks.append((ref, bmark, old, new)) |                 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 |             p_revs[bnode] = ref | ||||||
|         elif ref.startswith('refs/tags/'): |         elif ref.startswith('refs/tags/'): | ||||||
|             tag = ref[len('refs/tags/'):] |             tag = ref[len('refs/tags/'):] | ||||||
| @ -1037,6 +1066,16 @@ def do_export(parser): | |||||||
|             # transport-helper/fast-export bugs |             # transport-helper/fast-export bugs | ||||||
|             continue |             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 peer: | ||||||
|         if not push(parser.repo, peer, parsed_refs, p_revs): |         if not push(parser.repo, peer, parsed_refs, p_revs): | ||||||
|             # do not update bookmarks |             # do not update bookmarks | ||||||
|  | |||||||
| @ -65,6 +65,9 @@ check_push () { | |||||||
| 		'non-fast-forward') | 		'non-fast-forward') | ||||||
| 			grep "^ ! \[rejected\] *${branch} -> ${branch} (non-fast-forward)$" error || ref_ret=1 | 			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 | 			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 && | 	echo diverge > content && | ||||||
| 	git commit -a -m diverge && | 	git commit -a -m diverge && | ||||||
| 	check_push 1 <<-EOF | 	check_push 1 <<-EOF | ||||||
| 	diverge:non-fast-forward | 	diverge:fetch-first | ||||||
| 	EOF | 	EOF | ||||||
| 	) && | 	) && | ||||||
|  |  | ||||||
| @ -525,6 +528,72 @@ test_expect_success 'remote big push' ' | |||||||
| 	check_bookmark hgrepo new_bmark '' | 	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_expect_success 'remote double failed push' ' | ||||||
| 	test_when_finished "rm -rf hgrepo gitrepo*" && | 	test_when_finished "rm -rf hgrepo gitrepo*" && | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user