submodule: do not pass null OID to setup_revisions
If "git pull --recurse-submodules --rebase" is invoked when the current
branch and its corresponding remote-tracking branch have no merge base,
a "bad object" fatal error occurs. This issue was introduced with commit
a6d7eb2c7a ("pull: optionally rebase submodules (remote submodule
changes only)", 2017-06-23), which also introduced this feature.
This is because cmd_pull() in builtin/pull.c thus invokes
submodule_touches_in_range() with a null OID as the first parameter.
Ensure that this case works, and document what happens in this case.
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Reviewed-by: Stefan Beller <sbeller@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
			
			
This commit is contained in:
		 Jonathan Tan
					Jonathan Tan
				
			
				
					committed by
					
						 Junio C Hamano
						Junio C Hamano
					
				
			
			
				
	
			
			
			 Junio C Hamano
						Junio C Hamano
					
				
			
						parent
						
							468165c1d8
						
					
				
				
					commit
					4d36f88be7
				
			| @ -1166,8 +1166,10 @@ int submodule_touches_in_range(struct object_id *excl_oid, | ||||
|  | ||||
| 	argv_array_push(&args, "--"); /* args[0] program name */ | ||||
| 	argv_array_push(&args, oid_to_hex(incl_oid)); | ||||
| 	argv_array_push(&args, "--not"); | ||||
| 	argv_array_push(&args, oid_to_hex(excl_oid)); | ||||
| 	if (!is_null_oid(excl_oid)) { | ||||
| 		argv_array_push(&args, "--not"); | ||||
| 		argv_array_push(&args, oid_to_hex(excl_oid)); | ||||
| 	} | ||||
|  | ||||
| 	collect_changed_submodules(&subs, &args); | ||||
| 	ret = subs.nr; | ||||
|  | ||||
| @ -94,7 +94,10 @@ extern int merge_submodule(struct object_id *result, const char *path, | ||||
| 			   const struct object_id *a, | ||||
| 			   const struct object_id *b, int search); | ||||
|  | ||||
| /* Checks if there are submodule changes in a..b. */ | ||||
| /* | ||||
|  * Checks if there are submodule changes in a..b. If a is the null OID, | ||||
|  * checks b and all its ancestors instead. | ||||
|  */ | ||||
| extern int submodule_touches_in_range(struct object_id *a, | ||||
| 				      struct object_id *b); | ||||
| extern int find_unpushed_submodules(struct oid_array *commits, | ||||
|  | ||||
| @ -132,4 +132,25 @@ test_expect_success 'pull rebase recursing fails with conflicts' ' | ||||
| 	test_i18ngrep "locally recorded submodule modifications" err | ||||
| ' | ||||
|  | ||||
| test_expect_success 'branch has no merge base with remote-tracking counterpart' ' | ||||
| 	rm -rf parent child && | ||||
|  | ||||
| 	test_create_repo a-submodule && | ||||
| 	test_commit -C a-submodule foo && | ||||
|  | ||||
| 	test_create_repo parent && | ||||
| 	git -C parent submodule add "$(pwd)/a-submodule" && | ||||
| 	git -C parent commit -m foo && | ||||
|  | ||||
| 	git clone parent child && | ||||
|  | ||||
| 	# Reset master so that it has no merge base with | ||||
| 	# refs/remotes/origin/master. | ||||
| 	OTHER=$(git -C child commit-tree -m bar \ | ||||
| 		$(git -C child rev-parse HEAD^{tree})) && | ||||
| 	git -C child reset --hard "$OTHER" && | ||||
|  | ||||
| 	git -C child pull --recurse-submodules --rebase | ||||
| ' | ||||
|  | ||||
| test_done | ||||
|  | ||||
		Reference in New Issue
	
	Block a user