As we introduce a submodule UX with branches, we would like to be able to get the submodule commit ids in a superproject tree because those ids are the source of truth e.g. "git branch --recurse-submodules topic start-point" should create branches based off the commit ids recorded in the superproject's 'start-point' tree. To make this easy, introduce a submodules_of_tree() helper function that iterates through a tree and returns the tree's gitlink entries as a list. Signed-off-by: Glen Choo <chooglen@xxxxxxxxxx> --- submodule-config.c | 19 +++++++++++++++++++ submodule-config.h | 13 +++++++++++++ 2 files changed, 32 insertions(+) diff --git a/submodule-config.c b/submodule-config.c index f95344028b..97da373301 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -7,6 +7,7 @@ #include "strbuf.h" #include "object-store.h" #include "parse-options.h" +#include "tree-walk.h" /* * submodule cache lookup structure @@ -726,6 +727,24 @@ const struct submodule *submodule_from_path(struct repository *r, return config_from(r->submodule_cache, treeish_name, path, lookup_path); } +struct submodule_entry_list * +submodules_of_tree(struct repository *r, const struct object_id *treeish_name) +{ + struct tree_desc tree; + struct name_entry entry; + struct submodule_entry_list *ret; + + CALLOC_ARRAY(ret, 1); + fill_tree_descriptor(r, &tree, treeish_name); + while (tree_entry(&tree, &entry)) { + if (!S_ISGITLINK(entry.mode)) + continue; + ALLOC_GROW(ret->name_entries, ret->entry_nr + 1, ret->entry_alloc); + ret->name_entries[ret->entry_nr++] = entry; + } + return ret; +} + void submodule_free(struct repository *r) { if (r->submodule_cache) diff --git a/submodule-config.h b/submodule-config.h index 65875b94ea..4379ec77e3 100644 --- a/submodule-config.h +++ b/submodule-config.h @@ -6,6 +6,7 @@ #include "hashmap.h" #include "submodule.h" #include "strbuf.h" +#include "tree-walk.h" /** * The submodule config cache API allows to read submodule @@ -67,6 +68,18 @@ const struct submodule *submodule_from_name(struct repository *r, const struct object_id *commit_or_tree, const char *name); +struct submodule_entry_list { + struct name_entry *name_entries; + int entry_nr; + int entry_alloc; +}; + +/** + * Given a tree-ish, return all submodules in the tree. + */ +struct submodule_entry_list * +submodules_of_tree(struct repository *r, const struct object_id *treeish_name); + /** * Given a tree-ish in the superproject and a path, return the submodule that * is bound at the path in the named tree. -- 2.33.GIT