Merge branch 'jt/no-abuse-alternate-odb-for-submodules'
Follow through the work to use the repo interface to access
submodule objects in-process, instead of abusing the alternate
object database interface.
* jt/no-abuse-alternate-odb-for-submodules:
  submodule: trace adding submodule ODB as alternate
  submodule: pass repo to check_has_commit()
  object-file: only register submodule ODB if needed
  merge-{ort,recursive}: remove add_submodule_odb()
  refs: peeling non-the_repository iterators is BUG
  refs: teach arbitrary repo support to iterators
  refs: plumb repo into ref stores
			
			
				maint
			
			
		
						commit
						162a13b855
					
				
							
								
								
									
										18
									
								
								merge-ort.c
								
								
								
								
							
							
						
						
									
										18
									
								
								merge-ort.c
								
								
								
								
							|  | @ -609,6 +609,7 @@ static int err(struct merge_options *opt, const char *err, ...) | |||
|  | ||||
| static void format_commit(struct strbuf *sb, | ||||
| 			  int indent, | ||||
| 			  struct repository *repo, | ||||
| 			  struct commit *commit) | ||||
| { | ||||
| 	struct merge_remote_desc *desc; | ||||
|  | @ -622,7 +623,7 @@ static void format_commit(struct strbuf *sb, | |||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	format_commit_message(commit, "%h %s", sb, &ctx); | ||||
| 	repo_format_commit_message(repo, commit, "%h %s", sb, &ctx); | ||||
| 	strbuf_addch(sb, '\n'); | ||||
| } | ||||
|  | ||||
|  | @ -1578,17 +1579,6 @@ static int merge_submodule(struct merge_options *opt, | |||
| 	if (is_null_oid(b)) | ||||
| 		return 0; | ||||
|  | ||||
| 	/* | ||||
| 	 * NEEDSWORK: Remove this when all submodule object accesses are | ||||
| 	 * through explicitly specified repositores. | ||||
| 	 */ | ||||
| 	if (add_submodule_odb(path)) { | ||||
| 		path_msg(opt, path, 0, | ||||
| 			 _("Failed to merge submodule %s (not checked out)"), | ||||
| 			 path); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (repo_submodule_init(&subrepo, opt->repo, path, null_oid())) { | ||||
| 		path_msg(opt, path, 0, | ||||
| 				_("Failed to merge submodule %s (not checked out)"), | ||||
|  | @ -1653,7 +1643,7 @@ static int merge_submodule(struct merge_options *opt, | |||
| 		break; | ||||
|  | ||||
| 	case 1: | ||||
| 		format_commit(&sb, 4, | ||||
| 		format_commit(&sb, 4, &subrepo, | ||||
| 			      (struct commit *)merges.objects[0].item); | ||||
| 		path_msg(opt, path, 0, | ||||
| 			 _("Failed to merge submodule %s, but a possible merge " | ||||
|  | @ -1670,7 +1660,7 @@ static int merge_submodule(struct merge_options *opt, | |||
| 		break; | ||||
| 	default: | ||||
| 		for (i = 0; i < merges.nr; i++) | ||||
| 			format_commit(&sb, 4, | ||||
| 			format_commit(&sb, 4, &subrepo, | ||||
| 				      (struct commit *)merges.objects[i].item); | ||||
| 		path_msg(opt, path, 0, | ||||
| 			 _("Failed to merge submodule %s, but multiple " | ||||
|  |  | |||
|  | @ -334,7 +334,9 @@ static void output(struct merge_options *opt, int v, const char *fmt, ...) | |||
| 		flush_output(opt); | ||||
| } | ||||
|  | ||||
| static void output_commit_title(struct merge_options *opt, struct commit *commit) | ||||
| static void repo_output_commit_title(struct merge_options *opt, | ||||
| 				     struct repository *repo, | ||||
| 				     struct commit *commit) | ||||
| { | ||||
| 	struct merge_remote_desc *desc; | ||||
|  | ||||
|  | @ -343,23 +345,29 @@ static void output_commit_title(struct merge_options *opt, struct commit *commit | |||
| 	if (desc) | ||||
| 		strbuf_addf(&opt->obuf, "virtual %s\n", desc->name); | ||||
| 	else { | ||||
| 		strbuf_add_unique_abbrev(&opt->obuf, &commit->object.oid, | ||||
| 					 DEFAULT_ABBREV); | ||||
| 		strbuf_repo_add_unique_abbrev(&opt->obuf, repo, | ||||
| 					      &commit->object.oid, | ||||
| 					      DEFAULT_ABBREV); | ||||
| 		strbuf_addch(&opt->obuf, ' '); | ||||
| 		if (parse_commit(commit) != 0) | ||||
| 		if (repo_parse_commit(repo, commit) != 0) | ||||
| 			strbuf_addstr(&opt->obuf, _("(bad commit)\n")); | ||||
| 		else { | ||||
| 			const char *title; | ||||
| 			const char *msg = get_commit_buffer(commit, NULL); | ||||
| 			const char *msg = repo_get_commit_buffer(repo, commit, NULL); | ||||
| 			int len = find_commit_subject(msg, &title); | ||||
| 			if (len) | ||||
| 				strbuf_addf(&opt->obuf, "%.*s\n", len, title); | ||||
| 			unuse_commit_buffer(commit, msg); | ||||
| 			repo_unuse_commit_buffer(repo, commit, msg); | ||||
| 		} | ||||
| 	} | ||||
| 	flush_output(opt); | ||||
| } | ||||
|  | ||||
| static void output_commit_title(struct merge_options *opt, struct commit *commit) | ||||
| { | ||||
| 	repo_output_commit_title(opt, the_repository, commit); | ||||
| } | ||||
|  | ||||
| static int add_cacheinfo(struct merge_options *opt, | ||||
| 			 const struct diff_filespec *blob, | ||||
| 			 const char *path, int stage, int refresh, int options) | ||||
|  | @ -1152,14 +1160,14 @@ static int find_first_merges(struct repository *repo, | |||
| 	return result->nr; | ||||
| } | ||||
|  | ||||
| static void print_commit(struct commit *commit) | ||||
| static void print_commit(struct repository *repo, struct commit *commit) | ||||
| { | ||||
| 	struct strbuf sb = STRBUF_INIT; | ||||
| 	struct pretty_print_context ctx = {0}; | ||||
| 	ctx.date_mode.type = DATE_NORMAL; | ||||
| 	/* FIXME: Merge this with output_commit_title() */ | ||||
| 	assert(!merge_remote_util(commit)); | ||||
| 	format_commit_message(commit, " %h: %m %s", &sb, &ctx); | ||||
| 	repo_format_commit_message(repo, commit, " %h: %m %s", &sb, &ctx); | ||||
| 	fprintf(stderr, "%s\n", sb.buf); | ||||
| 	strbuf_release(&sb); | ||||
| } | ||||
|  | @ -1199,15 +1207,6 @@ static int merge_submodule(struct merge_options *opt, | |||
| 	if (is_null_oid(b)) | ||||
| 		return 0; | ||||
|  | ||||
| 	/* | ||||
| 	 * NEEDSWORK: Remove this when all submodule object accesses are | ||||
| 	 * through explicitly specified repositores. | ||||
| 	 */ | ||||
| 	if (add_submodule_odb(path)) { | ||||
| 		output(opt, 1, _("Failed to merge submodule %s (not checked out)"), path); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	if (repo_submodule_init(&subrepo, opt->repo, path, null_oid())) { | ||||
| 		output(opt, 1, _("Failed to merge submodule %s (not checked out)"), path); | ||||
| 		return 0; | ||||
|  | @ -1232,7 +1231,7 @@ static int merge_submodule(struct merge_options *opt, | |||
| 		oidcpy(result, b); | ||||
| 		if (show(opt, 3)) { | ||||
| 			output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path); | ||||
| 			output_commit_title(opt, commit_b); | ||||
| 			repo_output_commit_title(opt, &subrepo, commit_b); | ||||
| 		} else if (show(opt, 2)) | ||||
| 			output(opt, 2, _("Fast-forwarding submodule %s"), path); | ||||
| 		else | ||||
|  | @ -1245,7 +1244,7 @@ static int merge_submodule(struct merge_options *opt, | |||
| 		oidcpy(result, a); | ||||
| 		if (show(opt, 3)) { | ||||
| 			output(opt, 3, _("Fast-forwarding submodule %s to the following commit:"), path); | ||||
| 			output_commit_title(opt, commit_a); | ||||
| 			repo_output_commit_title(opt, &subrepo, commit_a); | ||||
| 		} else if (show(opt, 2)) | ||||
| 			output(opt, 2, _("Fast-forwarding submodule %s"), path); | ||||
| 		else | ||||
|  | @ -1277,7 +1276,7 @@ static int merge_submodule(struct merge_options *opt, | |||
| 	case 1: | ||||
| 		output(opt, 1, _("Failed to merge submodule %s (not fast-forward)"), path); | ||||
| 		output(opt, 2, _("Found a possible merge resolution for the submodule:\n")); | ||||
| 		print_commit((struct commit *) merges.objects[0].item); | ||||
| 		print_commit(&subrepo, (struct commit *) merges.objects[0].item); | ||||
| 		output(opt, 2, _( | ||||
| 		       "If this is correct simply add it to the index " | ||||
| 		       "for example\n" | ||||
|  | @ -1290,7 +1289,7 @@ static int merge_submodule(struct merge_options *opt, | |||
| 	default: | ||||
| 		output(opt, 1, _("Failed to merge submodule %s (multiple merges found)"), path); | ||||
| 		for (i = 0; i < merges.nr; i++) | ||||
| 			print_commit((struct commit *) merges.objects[i].item); | ||||
| 			print_commit(&subrepo, (struct commit *) merges.objects[i].item); | ||||
| 	} | ||||
|  | ||||
| 	object_array_clear(&merges); | ||||
|  |  | |||
|  | @ -1528,7 +1528,14 @@ static int do_oid_object_info_extended(struct repository *r, | |||
| 				break; | ||||
| 		} | ||||
|  | ||||
| 		if (register_all_submodule_odb_as_alternates()) | ||||
| 		/* | ||||
| 		 * If r is the_repository, this might be an attempt at | ||||
| 		 * accessing a submodule object as if it were in the_repository | ||||
| 		 * (having called add_submodule_odb() on that submodule's ODB). | ||||
| 		 * If any such ODBs exist, register them and try again. | ||||
| 		 */ | ||||
| 		if (r == the_repository && | ||||
| 		    register_all_submodule_odb_as_alternates()) | ||||
| 			/* We added some alternates; retry */ | ||||
| 			continue; | ||||
|  | ||||
|  |  | |||
							
								
								
									
										32
									
								
								refs.c
								
								
								
								
							
							
						
						
									
										32
									
								
								refs.c
								
								
								
								
							|  | @ -251,12 +251,13 @@ int refname_is_safe(const char *refname) | |||
|  * does not exist, emit a warning and return false. | ||||
|  */ | ||||
| int ref_resolves_to_object(const char *refname, | ||||
| 			   struct repository *repo, | ||||
| 			   const struct object_id *oid, | ||||
| 			   unsigned int flags) | ||||
| { | ||||
| 	if (flags & REF_ISBROKEN) | ||||
| 		return 0; | ||||
| 	if (!has_object_file(oid)) { | ||||
| 	if (!repo_has_object_file(repo, oid)) { | ||||
| 		error(_("%s does not point to a valid object!"), refname); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | @ -1870,7 +1871,8 @@ static struct ref_store *lookup_ref_store_map(struct hashmap *map, | |||
|  * Create, record, and return a ref_store instance for the specified | ||||
|  * gitdir. | ||||
|  */ | ||||
| static struct ref_store *ref_store_init(const char *gitdir, | ||||
| static struct ref_store *ref_store_init(struct repository *repo, | ||||
| 					const char *gitdir, | ||||
| 					unsigned int flags) | ||||
| { | ||||
| 	const char *be_name = "files"; | ||||
|  | @ -1880,7 +1882,7 @@ static struct ref_store *ref_store_init(const char *gitdir, | |||
| 	if (!be) | ||||
| 		BUG("reference backend %s is unknown", be_name); | ||||
|  | ||||
| 	refs = be->init(gitdir, flags); | ||||
| 	refs = be->init(repo, gitdir, flags); | ||||
| 	return refs; | ||||
| } | ||||
|  | ||||
|  | @ -1892,7 +1894,7 @@ struct ref_store *get_main_ref_store(struct repository *r) | |||
| 	if (!r->gitdir) | ||||
| 		BUG("attempting to get main_ref_store outside of repository"); | ||||
|  | ||||
| 	r->refs_private = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS); | ||||
| 	r->refs_private = ref_store_init(r, r->gitdir, REF_STORE_ALL_CAPS); | ||||
| 	r->refs_private = maybe_debug_wrap_ref_store(r->gitdir, r->refs_private); | ||||
| 	return r->refs_private; | ||||
| } | ||||
|  | @ -1922,6 +1924,7 @@ struct ref_store *get_submodule_ref_store(const char *submodule) | |||
| 	struct ref_store *refs; | ||||
| 	char *to_free = NULL; | ||||
| 	size_t len; | ||||
| 	struct repository *subrepo; | ||||
|  | ||||
| 	if (!submodule) | ||||
| 		return NULL; | ||||
|  | @ -1947,8 +1950,19 @@ struct ref_store *get_submodule_ref_store(const char *submodule) | |||
| 	if (submodule_to_gitdir(&submodule_sb, submodule)) | ||||
| 		goto done; | ||||
|  | ||||
| 	/* assume that add_submodule_odb() has been called */ | ||||
| 	refs = ref_store_init(submodule_sb.buf, | ||||
| 	subrepo = xmalloc(sizeof(*subrepo)); | ||||
| 	/* | ||||
| 	 * NEEDSWORK: Make get_submodule_ref_store() work with arbitrary | ||||
| 	 * superprojects other than the_repository. This probably should be | ||||
| 	 * done by making it take a struct repository * parameter instead of a | ||||
| 	 * submodule path. | ||||
| 	 */ | ||||
| 	if (repo_submodule_init(subrepo, the_repository, submodule, | ||||
| 				null_oid())) { | ||||
| 		free(subrepo); | ||||
| 		goto done; | ||||
| 	} | ||||
| 	refs = ref_store_init(subrepo, submodule_sb.buf, | ||||
| 			      REF_STORE_READ | REF_STORE_ODB); | ||||
| 	register_ref_store_map(&submodule_ref_stores, "submodule", | ||||
| 			       refs, submodule); | ||||
|  | @ -1974,10 +1988,12 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt) | |||
| 		return refs; | ||||
|  | ||||
| 	if (wt->id) | ||||
| 		refs = ref_store_init(git_common_path("worktrees/%s", wt->id), | ||||
| 		refs = ref_store_init(the_repository, | ||||
| 				      git_common_path("worktrees/%s", wt->id), | ||||
| 				      REF_STORE_ALL_CAPS); | ||||
| 	else | ||||
| 		refs = ref_store_init(get_git_common_dir(), | ||||
| 		refs = ref_store_init(the_repository, | ||||
| 				      get_git_common_dir(), | ||||
| 				      REF_STORE_ALL_CAPS); | ||||
|  | ||||
| 	if (refs) | ||||
|  |  | |||
|  | @ -79,13 +79,15 @@ static void clear_loose_ref_cache(struct files_ref_store *refs) | |||
|  * Create a new submodule ref cache and add it to the internal | ||||
|  * set of caches. | ||||
|  */ | ||||
| static struct ref_store *files_ref_store_create(const char *gitdir, | ||||
| static struct ref_store *files_ref_store_create(struct repository *repo, | ||||
| 						const char *gitdir, | ||||
| 						unsigned int flags) | ||||
| { | ||||
| 	struct files_ref_store *refs = xcalloc(1, sizeof(*refs)); | ||||
| 	struct ref_store *ref_store = (struct ref_store *)refs; | ||||
| 	struct strbuf sb = STRBUF_INIT; | ||||
|  | ||||
| 	ref_store->repo = repo; | ||||
| 	ref_store->gitdir = xstrdup(gitdir); | ||||
| 	base_ref_store_init(ref_store, &refs_be_files); | ||||
| 	refs->store_flags = flags; | ||||
|  | @ -93,7 +95,7 @@ static struct ref_store *files_ref_store_create(const char *gitdir, | |||
| 	get_common_dir_noenv(&sb, gitdir); | ||||
| 	refs->gitcommondir = strbuf_detach(&sb, NULL); | ||||
| 	strbuf_addf(&sb, "%s/packed-refs", refs->gitcommondir); | ||||
| 	refs->packed_ref_store = packed_ref_store_create(sb.buf, flags); | ||||
| 	refs->packed_ref_store = packed_ref_store_create(repo, sb.buf, flags); | ||||
| 	strbuf_release(&sb); | ||||
|  | ||||
| 	chdir_notify_reparent("files-backend $GIT_DIR", &refs->base.gitdir); | ||||
|  | @ -730,6 +732,7 @@ struct files_ref_iterator { | |||
| 	struct ref_iterator base; | ||||
|  | ||||
| 	struct ref_iterator *iter0; | ||||
| 	struct repository *repo; | ||||
| 	unsigned int flags; | ||||
| }; | ||||
|  | ||||
|  | @ -751,6 +754,7 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator) | |||
|  | ||||
| 		if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) && | ||||
| 		    !ref_resolves_to_object(iter->iter0->refname, | ||||
| 					    iter->repo, | ||||
| 					    iter->iter0->oid, | ||||
| 					    iter->iter0->flags)) | ||||
| 			continue; | ||||
|  | @ -829,7 +833,7 @@ static struct ref_iterator *files_ref_iterator_begin( | |||
| 	 */ | ||||
|  | ||||
| 	loose_iter = cache_ref_iterator_begin(get_loose_ref_cache(refs), | ||||
| 					      prefix, 1); | ||||
| 					      prefix, ref_store->repo, 1); | ||||
|  | ||||
| 	/* | ||||
| 	 * The packed-refs file might contain broken references, for | ||||
|  | @ -853,6 +857,7 @@ static struct ref_iterator *files_ref_iterator_begin( | |||
| 	base_ref_iterator_init(ref_iterator, &files_ref_iterator_vtable, | ||||
| 			       overlay_iter->ordered); | ||||
| 	iter->iter0 = overlay_iter; | ||||
| 	iter->repo = ref_store->repo; | ||||
| 	iter->flags = flags; | ||||
|  | ||||
| 	return ref_iterator; | ||||
|  | @ -1169,7 +1174,7 @@ static int should_pack_ref(const char *refname, | |||
| 		return 0; | ||||
|  | ||||
| 	/* Do not pack broken refs: */ | ||||
| 	if (!ref_resolves_to_object(refname, oid, ref_flags)) | ||||
| 	if (!ref_resolves_to_object(refname, the_repository, oid, ref_flags)) | ||||
| 		return 0; | ||||
|  | ||||
| 	return 1; | ||||
|  | @ -1192,7 +1197,8 @@ static int files_pack_refs(struct ref_store *ref_store, unsigned int flags) | |||
|  | ||||
| 	packed_refs_lock(refs->packed_ref_store, LOCK_DIE_ON_ERROR, &err); | ||||
|  | ||||
| 	iter = cache_ref_iterator_begin(get_loose_ref_cache(refs), NULL, 0); | ||||
| 	iter = cache_ref_iterator_begin(get_loose_ref_cache(refs), NULL, | ||||
| 					the_repository, 0); | ||||
| 	while ((ok = ref_iterator_advance(iter)) == ITER_OK) { | ||||
| 		/* | ||||
| 		 * If the loose reference can be packed, add an entry | ||||
|  |  | |||
|  | @ -193,13 +193,15 @@ static int release_snapshot(struct snapshot *snapshot) | |||
| 	} | ||||
| } | ||||
|  | ||||
| struct ref_store *packed_ref_store_create(const char *path, | ||||
| struct ref_store *packed_ref_store_create(struct repository *repo, | ||||
| 					  const char *path, | ||||
| 					  unsigned int store_flags) | ||||
| { | ||||
| 	struct packed_ref_store *refs = xcalloc(1, sizeof(*refs)); | ||||
| 	struct ref_store *ref_store = (struct ref_store *)refs; | ||||
|  | ||||
| 	base_ref_store_init(ref_store, &refs_be_packed); | ||||
| 	ref_store->repo = repo; | ||||
| 	ref_store->gitdir = xstrdup(path); | ||||
| 	refs->store_flags = store_flags; | ||||
|  | ||||
|  | @ -776,6 +778,7 @@ struct packed_ref_iterator { | |||
| 	struct object_id oid, peeled; | ||||
| 	struct strbuf refname_buf; | ||||
|  | ||||
| 	struct repository *repo; | ||||
| 	unsigned int flags; | ||||
| }; | ||||
|  | ||||
|  | @ -864,8 +867,8 @@ static int packed_ref_iterator_advance(struct ref_iterator *ref_iterator) | |||
| 			continue; | ||||
|  | ||||
| 		if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) && | ||||
| 		    !ref_resolves_to_object(iter->base.refname, &iter->oid, | ||||
| 					    iter->flags)) | ||||
| 		    !ref_resolves_to_object(iter->base.refname, iter->repo, | ||||
| 					    &iter->oid, iter->flags)) | ||||
| 			continue; | ||||
|  | ||||
| 		return ITER_OK; | ||||
|  | @ -883,6 +886,9 @@ static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator, | |||
| 	struct packed_ref_iterator *iter = | ||||
| 		(struct packed_ref_iterator *)ref_iterator; | ||||
|  | ||||
| 	if (iter->repo != the_repository) | ||||
| 		BUG("peeling for non-the_repository is not supported"); | ||||
|  | ||||
| 	if ((iter->base.flags & REF_KNOWS_PEELED)) { | ||||
| 		oidcpy(peeled, &iter->peeled); | ||||
| 		return is_null_oid(&iter->peeled) ? -1 : 0; | ||||
|  | @ -954,6 +960,7 @@ static struct ref_iterator *packed_ref_iterator_begin( | |||
|  | ||||
| 	iter->base.oid = &iter->oid; | ||||
|  | ||||
| 	iter->repo = ref_store->repo; | ||||
| 	iter->flags = flags; | ||||
|  | ||||
| 	if (prefix && *prefix) | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| #ifndef REFS_PACKED_BACKEND_H | ||||
| #define REFS_PACKED_BACKEND_H | ||||
|  | ||||
| struct repository; | ||||
| struct ref_transaction; | ||||
|  | ||||
| /* | ||||
|  | @ -12,7 +13,8 @@ struct ref_transaction; | |||
|  * even among packed refs. | ||||
|  */ | ||||
|  | ||||
| struct ref_store *packed_ref_store_create(const char *path, | ||||
| struct ref_store *packed_ref_store_create(struct repository *repo, | ||||
| 					  const char *path, | ||||
| 					  unsigned int store_flags); | ||||
|  | ||||
| /* | ||||
|  |  | |||
|  | @ -378,6 +378,8 @@ struct cache_ref_iterator { | |||
| 	 * on from there.) | ||||
| 	 */ | ||||
| 	struct cache_ref_iterator_level *levels; | ||||
|  | ||||
| 	struct repository *repo; | ||||
| }; | ||||
|  | ||||
| static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator) | ||||
|  | @ -434,6 +436,11 @@ static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator) | |||
| static int cache_ref_iterator_peel(struct ref_iterator *ref_iterator, | ||||
| 				   struct object_id *peeled) | ||||
| { | ||||
| 	struct cache_ref_iterator *iter = | ||||
| 		(struct cache_ref_iterator *)ref_iterator; | ||||
|  | ||||
| 	if (iter->repo != the_repository) | ||||
| 		BUG("peeling for non-the_repository is not supported"); | ||||
| 	return peel_object(ref_iterator->oid, peeled) ? -1 : 0; | ||||
| } | ||||
|  | ||||
|  | @ -456,6 +463,7 @@ static struct ref_iterator_vtable cache_ref_iterator_vtable = { | |||
|  | ||||
| struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache, | ||||
| 					      const char *prefix, | ||||
| 					      struct repository *repo, | ||||
| 					      int prime_dir) | ||||
| { | ||||
| 	struct ref_dir *dir; | ||||
|  | @ -490,5 +498,7 @@ struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache, | |||
| 		level->prefix_state = PREFIX_CONTAINS_DIR; | ||||
| 	} | ||||
|  | ||||
| 	iter->repo = repo; | ||||
|  | ||||
| 	return ref_iterator; | ||||
| } | ||||
|  |  | |||
|  | @ -214,6 +214,7 @@ struct ref_entry *find_ref_entry(struct ref_dir *dir, const char *refname); | |||
|  */ | ||||
| struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache, | ||||
| 					      const char *prefix, | ||||
| 					      struct repository *repo, | ||||
| 					      int prime_dir); | ||||
|  | ||||
| #endif /* REFS_REF_CACHE_H */ | ||||
|  |  | |||
|  | @ -66,6 +66,7 @@ int refname_is_safe(const char *refname); | |||
|  * referred-to object does not exist, emit a warning and return false. | ||||
|  */ | ||||
| int ref_resolves_to_object(const char *refname, | ||||
| 			   struct repository *repo, | ||||
| 			   const struct object_id *oid, | ||||
| 			   unsigned int flags); | ||||
|  | ||||
|  | @ -539,7 +540,8 @@ struct ref_store; | |||
|  * should call base_ref_store_init() to initialize the shared part of | ||||
|  * the ref_store and to record the ref_store for later lookup. | ||||
|  */ | ||||
| typedef struct ref_store *ref_store_init_fn(const char *gitdir, | ||||
| typedef struct ref_store *ref_store_init_fn(struct repository *repo, | ||||
| 					    const char *gitdir, | ||||
| 					    unsigned int flags); | ||||
|  | ||||
| typedef int ref_init_db_fn(struct ref_store *refs, struct strbuf *err); | ||||
|  | @ -701,7 +703,12 @@ struct ref_store { | |||
| 	/* The backend describing this ref_store's storage scheme: */ | ||||
| 	const struct ref_storage_be *be; | ||||
|  | ||||
| 	/* The gitdir that this ref_store applies to: */ | ||||
| 	struct repository *repo; | ||||
|  | ||||
| 	/* | ||||
| 	 * The gitdir that this ref_store applies to. Note that this is not | ||||
| 	 * necessarily repo->gitdir if the repo has multiple worktrees. | ||||
| 	 */ | ||||
| 	char *gitdir; | ||||
| }; | ||||
|  | ||||
|  |  | |||
							
								
								
									
										12
									
								
								strbuf.c
								
								
								
								
							
							
						
						
									
										12
									
								
								strbuf.c
								
								
								
								
							|  | @ -1059,15 +1059,21 @@ void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm, | |||
| 	strbuf_setlen(sb, sb->len + len); | ||||
| } | ||||
|  | ||||
| void strbuf_add_unique_abbrev(struct strbuf *sb, const struct object_id *oid, | ||||
| 			      int abbrev_len) | ||||
| void strbuf_repo_add_unique_abbrev(struct strbuf *sb, struct repository *repo, | ||||
| 				   const struct object_id *oid, int abbrev_len) | ||||
| { | ||||
| 	int r; | ||||
| 	strbuf_grow(sb, GIT_MAX_HEXSZ + 1); | ||||
| 	r = find_unique_abbrev_r(sb->buf + sb->len, oid, abbrev_len); | ||||
| 	r = repo_find_unique_abbrev_r(repo, sb->buf + sb->len, oid, abbrev_len); | ||||
| 	strbuf_setlen(sb, sb->len + r); | ||||
| } | ||||
|  | ||||
| void strbuf_add_unique_abbrev(struct strbuf *sb, const struct object_id *oid, | ||||
| 			      int abbrev_len) | ||||
| { | ||||
| 	strbuf_repo_add_unique_abbrev(sb, the_repository, oid, abbrev_len); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Returns the length of a line, without trailing spaces. | ||||
|  * | ||||
|  |  | |||
							
								
								
									
										6
									
								
								strbuf.h
								
								
								
								
							
							
						
						
									
										6
									
								
								strbuf.h
								
								
								
								
							|  | @ -634,8 +634,10 @@ void strbuf_list_free(struct strbuf **list); | |||
|  * Add the abbreviation, as generated by find_unique_abbrev, of `sha1` to | ||||
|  * the strbuf `sb`. | ||||
|  */ | ||||
| void strbuf_add_unique_abbrev(struct strbuf *sb, | ||||
| 			      const struct object_id *oid, | ||||
| struct repository; | ||||
| void strbuf_repo_add_unique_abbrev(struct strbuf *sb, struct repository *repo, | ||||
| 				   const struct object_id *oid, int abbrev_len); | ||||
| void strbuf_add_unique_abbrev(struct strbuf *sb, const struct object_id *oid, | ||||
| 			      int abbrev_len); | ||||
|  | ||||
| /** | ||||
|  |  | |||
							
								
								
									
										18
									
								
								submodule.c
								
								
								
								
							
							
						
						
									
										18
									
								
								submodule.c
								
								
								
								
							|  | @ -201,6 +201,8 @@ int register_all_submodule_odb_as_alternates(void) | |||
| 		add_to_alternates_memory(added_submodule_odb_paths.items[i].string); | ||||
| 	if (ret) { | ||||
| 		string_list_clear(&added_submodule_odb_paths, 0); | ||||
| 		trace2_data_intmax("submodule", the_repository, | ||||
| 				   "register_all_submodule_odb_as_alternates/registered", ret); | ||||
| 		if (git_env_bool("GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB", 0)) | ||||
| 			BUG("register_all_submodule_odb_as_alternates() called"); | ||||
| 	} | ||||
|  | @ -928,23 +930,33 @@ struct has_commit_data { | |||
| static int check_has_commit(const struct object_id *oid, void *data) | ||||
| { | ||||
| 	struct has_commit_data *cb = data; | ||||
| 	struct repository subrepo; | ||||
| 	enum object_type type; | ||||
|  | ||||
| 	enum object_type type = oid_object_info(cb->repo, oid, NULL); | ||||
| 	if (repo_submodule_init(&subrepo, cb->repo, cb->path, null_oid())) { | ||||
| 		cb->result = 0; | ||||
| 		goto cleanup; | ||||
| 	} | ||||
|  | ||||
| 	type = oid_object_info(&subrepo, oid, NULL); | ||||
|  | ||||
| 	switch (type) { | ||||
| 	case OBJ_COMMIT: | ||||
| 		return 0; | ||||
| 		goto cleanup; | ||||
| 	case OBJ_BAD: | ||||
| 		/* | ||||
| 		 * Object is missing or invalid. If invalid, an error message | ||||
| 		 * has already been printed. | ||||
| 		 */ | ||||
| 		cb->result = 0; | ||||
| 		return 0; | ||||
| 		goto cleanup; | ||||
| 	default: | ||||
| 		die(_("submodule entry '%s' (%s) is a %s, not a commit"), | ||||
| 		    cb->path, oid_to_hex(oid), type_name(type)); | ||||
| 	} | ||||
| cleanup: | ||||
| 	repo_clear(&subrepo); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| static int submodule_has_commits(struct repository *r, | ||||
|  |  | |||
							
								
								
									
										7
									
								
								t/README
								
								
								
								
							
							
						
						
									
										7
									
								
								t/README
								
								
								
								
							|  | @ -463,11 +463,8 @@ GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=<boolean>, when true, makes | |||
| registering submodule ODBs as alternates a fatal action. Support for | ||||
| this environment variable can be removed once the migration to | ||||
| explicitly providing repositories when accessing submodule objects is | ||||
| complete (in which case we might want to replace this with a trace2 | ||||
| call so that users can make it visible if accessing submodule objects | ||||
| without an explicit repository still happens) or needs to be abandoned | ||||
| for whatever reason (in which case the migrated codepaths still retain | ||||
| their performance benefits). | ||||
| complete or needs to be abandoned for whatever reason (in which case the | ||||
| migrated codepaths still retain their performance benefits). | ||||
|  | ||||
| Naming Tests | ||||
| ------------ | ||||
|  |  | |||
|  | @ -6,6 +6,9 @@ test_description='Recursive "git fetch" for submodules' | |||
| GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master | ||||
| export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME | ||||
|  | ||||
| GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 | ||||
| export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB | ||||
|  | ||||
| . ./test-lib.sh | ||||
|  | ||||
| pwd=$(pwd) | ||||
|  |  | |||
|  | @ -5,6 +5,9 @@ test_description='test push with submodules' | |||
| GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main | ||||
| export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME | ||||
|  | ||||
| GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 | ||||
| export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB | ||||
|  | ||||
| . ./test-lib.sh | ||||
|  | ||||
| test_expect_success setup ' | ||||
|  |  | |||
|  | @ -5,6 +5,9 @@ test_description='pushing to a repository using push options' | |||
| GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main | ||||
| export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME | ||||
|  | ||||
| GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 | ||||
| export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB | ||||
|  | ||||
| . ./test-lib.sh | ||||
|  | ||||
| mk_repo_pair () { | ||||
|  |  | |||
|  | @ -2,6 +2,9 @@ | |||
|  | ||||
| test_description='pull can handle submodules' | ||||
|  | ||||
| GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 | ||||
| export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB | ||||
|  | ||||
| . ./test-lib.sh | ||||
| . "$TEST_DIRECTORY"/lib-submodule-update.sh | ||||
|  | ||||
|  |  | |||
|  | @ -5,6 +5,9 @@ test_description='merging with submodules' | |||
| GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main | ||||
| export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME | ||||
|  | ||||
| GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 | ||||
| export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB | ||||
|  | ||||
| . ./test-lib.sh | ||||
| . "$TEST_DIRECTORY"/lib-merge.sh | ||||
|  | ||||
|  |  | |||
|  | @ -12,6 +12,9 @@ The test setup uses a sparse checkout, however the same scenario can be set up | |||
| also by committing .gitmodules and then just removing it from the filesystem. | ||||
| ' | ||||
|  | ||||
| GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB=1 | ||||
| export GIT_TEST_FATAL_REGISTER_SUBMODULE_ODB | ||||
|  | ||||
| . ./test-lib.sh | ||||
|  | ||||
| test_expect_success 'sparse checkout setup which hides .gitmodules' ' | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano