summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-06-24 23:34:40 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2015-06-24 23:34:40 +0200
commitdaacf96d101b9d2100a5028090b5af5249d8893d (patch)
tree450942a1431c22f634f9c16916408bd80f165702
parente1f434f8643f26d48ee8de21d715069de76b14e1 (diff)
parent783672fa5be4f0e9dce72bcd74690258bdbac0a9 (diff)
downloadlibgit2-daacf96d101b9d2100a5028090b5af5249d8893d.tar.gz
Merge pull request #3097 from libgit2/cmn/submodule-config-state
Remove run-time configuration settings from submodules
-rw-r--r--examples/status.c26
-rw-r--r--include/git2/diff.h2
-rw-r--r--include/git2/submodule.h113
-rw-r--r--include/git2/types.h12
-rw-r--r--src/checkout.c10
-rw-r--r--src/config.c20
-rw-r--r--src/config.h6
-rw-r--r--src/diff_file.c2
-rw-r--r--src/repository.c1
-rw-r--r--src/repository.h1
-rw-r--r--src/submodule.c1037
-rw-r--r--src/submodule.h24
-rw-r--r--tests/diff/submodules.c16
-rw-r--r--tests/diff/tree.c2
-rw-r--r--tests/submodule/init.c6
-rw-r--r--tests/submodule/modify.c203
-rw-r--r--tests/submodule/nosubs.c44
-rw-r--r--tests/submodule/status.c65
-rw-r--r--tests/submodule/submodule_helpers.c11
-rw-r--r--tests/submodule/update.c30
20 files changed, 616 insertions, 1015 deletions
diff --git a/examples/status.c b/examples/status.c
index 62cb5b24f..8e242dd39 100644
--- a/examples/status.c
+++ b/examples/status.c
@@ -384,25 +384,19 @@ static void print_short(git_repository *repo, git_status_list *status)
if (s->index_to_workdir &&
s->index_to_workdir->new_file.mode == GIT_FILEMODE_COMMIT)
{
- git_submodule *sm = NULL;
unsigned int smstatus = 0;
- if (!git_submodule_lookup(
- &sm, repo, s->index_to_workdir->new_file.path)) {
-
- if (!git_submodule_status(&smstatus, sm)) {
- if (smstatus & GIT_SUBMODULE_STATUS_WD_MODIFIED)
- extra = " (new commits)";
- else if (smstatus & GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED)
- extra = " (modified content)";
- else if (smstatus & GIT_SUBMODULE_STATUS_WD_WD_MODIFIED)
- extra = " (modified content)";
- else if (smstatus & GIT_SUBMODULE_STATUS_WD_UNTRACKED)
- extra = " (untracked content)";
- }
+ if (!git_submodule_status(&smstatus, repo, s->index_to_workdir->new_file.path,
+ GIT_SUBMODULE_IGNORE_FALLBACK)) {
+ if (smstatus & GIT_SUBMODULE_STATUS_WD_MODIFIED)
+ extra = " (new commits)";
+ else if (smstatus & GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED)
+ extra = " (modified content)";
+ else if (smstatus & GIT_SUBMODULE_STATUS_WD_WD_MODIFIED)
+ extra = " (modified content)";
+ else if (smstatus & GIT_SUBMODULE_STATUS_WD_UNTRACKED)
+ extra = " (untracked content)";
}
-
- git_submodule_free(sm);
}
/**
diff --git a/include/git2/diff.h b/include/git2/diff.h
index 0ecdc1bed..90e2e1b22 100644
--- a/include/git2/diff.h
+++ b/include/git2/diff.h
@@ -399,7 +399,7 @@ typedef struct {
* `git_diff_options_init` programmatic initialization.
*/
#define GIT_DIFF_OPTIONS_INIT \
- {GIT_DIFF_OPTIONS_VERSION, 0, GIT_SUBMODULE_IGNORE_DEFAULT, {NULL,0}, NULL, NULL, 3}
+ {GIT_DIFF_OPTIONS_VERSION, 0, GIT_SUBMODULE_IGNORE_FALLBACK, {NULL,0}, NULL, NULL, 3}
/**
* Initializes a `git_diff_options` with default values. Equivalent to
diff --git a/include/git2/submodule.h b/include/git2/submodule.h
index 48faf8a49..cbafccd1b 100644
--- a/include/git2/submodule.h
+++ b/include/git2/submodule.h
@@ -301,20 +301,6 @@ GIT_EXTERN(int) git_submodule_add_to_index(
int write_index);
/**
- * Write submodule settings to .gitmodules file.
- *
- * This commits any in-memory changes to the submodule to the gitmodules
- * file on disk. You may also be interested in `git_submodule_init()` which
- * writes submodule info to ".git/config" (which is better for local changes
- * to submodule settings) and/or `git_submodule_sync()` which writes
- * settings about remotes to the actual submodule repository.
- *
- * @param submodule The submodule to write.
- * @return 0 on success, <0 on failure.
- */
-GIT_EXTERN(int) git_submodule_save(git_submodule *submodule);
-
-/**
* Get the containing repository for a submodule.
*
* This returns a pointer to the repository that contains the submodule.
@@ -373,36 +359,31 @@ GIT_EXTERN(int) git_submodule_resolve_url(git_buf *out, git_repository *repo, co
GIT_EXTERN(const char *) git_submodule_branch(git_submodule *submodule);
/**
- * Set the branch for the submodule.
+ * Set the branch for the submodule in the configuration
*
- * This sets the branch in memory for the submodule. This will be used for
- * any following submodule actions while this submodule data is in memory.
- *
- * After calling this, you may wish to call `git_submodule_save()` to write
- * the changes back to the ".gitmodules" file and `git_submodule_sync()` to
+ * After calling this, you may wish to call `git_submodule_sync()` to
* write the changes to the checked out submodule repository.
*
- * @param submodule Pointer to the submodule object
+ * @param repo the repository to affect
+ * @param name the name of the submodule to configure
* @param branch Branch that should be used for the submodule
* @return 0 on success, <0 on failure
*/
-GIT_EXTERN(int) git_submodule_set_branch(git_submodule *submodule, const char *branch);
+GIT_EXTERN(int) git_submodule_set_branch(git_repository *repo, const char *name, const char *branch);
/**
- * Set the URL for the submodule.
+ * Set the URL for the submodule in the configuration
*
- * This sets the URL in memory for the submodule. This will be used for
- * any following submodule actions while this submodule data is in memory.
*
- * After calling this, you may wish to call `git_submodule_save()` to write
- * the changes back to the ".gitmodules" file and `git_submodule_sync()` to
+ * After calling this, you may wish to call `git_submodule_sync()` to
* write the changes to the checked out submodule repository.
*
- * @param submodule Pointer to the submodule object
+ * @param repo the repository to affect
+ * @param name the name of the submodule to configure
* @param url URL that should be used for the submodule
* @return 0 on success, <0 on failure
*/
-GIT_EXTERN(int) git_submodule_set_url(git_submodule *submodule, const char *url);
+GIT_EXTERN(int) git_submodule_set_url(git_repository *repo, const char *name, const char *url);
/**
* Get the OID for the submodule in the index.
@@ -452,9 +433,6 @@ GIT_EXTERN(const git_oid *) git_submodule_wd_id(git_submodule *submodule);
* The working directory will be consider clean so long as there is a
* checked out version present.
*
- * plus the special **GIT_SUBMODULE_IGNORE_RESET** which can be used with
- * `git_submodule_set_ignore()` to revert to the on-disk setting.
- *
* @param submodule The submodule to check
* @return The current git_submodule_ignore_t valyue what will be used for
* this submodule.
@@ -463,32 +441,25 @@ GIT_EXTERN(git_submodule_ignore_t) git_submodule_ignore(
git_submodule *submodule);
/**
- * Set the ignore rule for the submodule.
- *
- * This sets the in-memory ignore rule for the submodule which will
- * control the behavior of `git_submodule_status()`.
+ * Set the ignore rule for the submodule in the configuration
*
- * To make changes persistent, call `git_submodule_save()` to write the
- * value to disk (in the ".gitmodules" and ".git/config" files).
+ * This does not affect any currently-loaded instances.
*
- * Call with `GIT_SUBMODULE_IGNORE_RESET` or call `git_submodule_reload()`
- * to revert the in-memory rule to the value that is on disk.
- *
- * @param submodule The submodule to update
+ * @param repo the repository to affect
+ * @param name the name of the submdule
* @param ignore The new value for the ignore rule
- * @return old value for ignore
+ * @return 0 or an error code
*/
-GIT_EXTERN(git_submodule_ignore_t) git_submodule_set_ignore(
- git_submodule *submodule,
+GIT_EXTERN(int) git_submodule_set_ignore(
+ git_repository *repo,
+ const char *name,
git_submodule_ignore_t ignore);
/**
* Get the update rule that will be used for the submodule.
*
* This value controls the behavior of the `git submodule update` command.
- * There are four useful values documented with `git_submodule_update_t`
- * plus the `GIT_SUBMODULE_UPDATE_RESET` which can be used to revert to
- * the on-disk setting.
+ * There are four useful values documented with `git_submodule_update_t`.
*
* @param submodule The submodule to check
* @return The current git_submodule_update_t value that will be used
@@ -498,23 +469,18 @@ GIT_EXTERN(git_submodule_update_t) git_submodule_update_strategy(
git_submodule *submodule);
/**
- * Set the update rule for the submodule.
- *
- * The initial value comes from the ".git/config" setting of
- * `submodule.$name.update` for this submodule (which is initialized from
- * the ".gitmodules" file). Using this function sets the update rule in
- * memory for the submodule. Call `git_submodule_save()` to write out the
- * new update rule.
+ * Set the update rule for the submodule in the configuration
*
- * Calling this again with GIT_SUBMODULE_UPDATE_RESET or calling
- * `git_submodule_reload()` will revert the rule to the on disk value.
+ * This setting won't affect any existing instances.
*
- * @param submodule The submodule to update
+ * @param repo the repository to affect
+ * @param name the name of the submodule to configure
* @param update The new value to use
- * @return old value for update
+ * @return 0 or an error code
*/
-GIT_EXTERN(git_submodule_update_t) git_submodule_set_update(
- git_submodule *submodule,
+GIT_EXTERN(int) git_submodule_set_update(
+ git_repository *repo,
+ const char *name,
git_submodule_update_t update);
/**
@@ -532,18 +498,18 @@ GIT_EXTERN(git_submodule_recurse_t) git_submodule_fetch_recurse_submodules(
git_submodule *submodule);
/**
- * Set the fetchRecurseSubmodules rule for a submodule.
+ * Set the fetchRecurseSubmodules rule for a submodule in the configuration
*
- * This sets the submodule.<name>.fetchRecurseSubmodules value for
- * the submodule. You should call `git_submodule_save()` if you want
- * to persist the new value.
+ * This setting won't affect any existing instances.
*
- * @param submodule The submodule to modify
+ * @param repo the repository to affect
+ * @param name the submodule to configure
* @param fetch_recurse_submodules Boolean value
* @return old value for fetchRecurseSubmodules
*/
-GIT_EXTERN(git_submodule_recurse_t) git_submodule_set_fetch_recurse_submodules(
- git_submodule *submodule,
+GIT_EXTERN(int) git_submodule_set_fetch_recurse_submodules(
+ git_repository *repo,
+ const char *name,
git_submodule_recurse_t fetch_recurse_submodules);
/**
@@ -634,16 +600,19 @@ GIT_EXTERN(int) git_submodule_reload_all(git_repository *repo, int force);
* This looks at a submodule and tries to determine the status. It
* will return a combination of the `GIT_SUBMODULE_STATUS` values above.
* How deeply it examines the working directory to do this will depend
- * on the `git_submodule_ignore_t` value for the submodule - which can be
- * set either temporarily or permanently with `git_submodule_set_ignore()`.
+ * on the `git_submodule_ignore_t` value for the submodule.
*
* @param status Combination of `GIT_SUBMODULE_STATUS` flags
- * @param submodule Submodule for which to get status
+ * @param repo the repository in which to look
+ * @param name name of the submodule
+ * @param ignore the ignore rules to follow
* @return 0 on success, <0 on error
*/
GIT_EXTERN(int) git_submodule_status(
unsigned int *status,
- git_submodule *submodule);
+ git_repository *repo,
+ const char *name,
+ git_submodule_ignore_t ignore);
/**
* Get the locations of submodule information.
diff --git a/include/git2/types.h b/include/git2/types.h
index c97e5ba61..e975c6097 100644
--- a/include/git2/types.h
+++ b/include/git2/types.h
@@ -349,7 +349,6 @@ typedef struct git_submodule git_submodule;
*
* The values are:
*
- * - GIT_SUBMODULE_UPDATE_RESET: reset to the on-disk value.
* - GIT_SUBMODULE_UPDATE_CHECKOUT: the default; when a submodule is
* updated, checkout the new detached HEAD to the submodule directory.
* - GIT_SUBMODULE_UPDATE_REBASE: update by rebasing the current checked
@@ -362,8 +361,6 @@ typedef struct git_submodule git_submodule;
* when we don't want any particular update rule to be specified.
*/
typedef enum {
- GIT_SUBMODULE_UPDATE_RESET = -1,
-
GIT_SUBMODULE_UPDATE_CHECKOUT = 1,
GIT_SUBMODULE_UPDATE_REBASE = 2,
GIT_SUBMODULE_UPDATE_MERGE = 3,
@@ -386,7 +383,7 @@ typedef enum {
*
* The values are:
*
- * - GIT_SUBMODULE_IGNORE_RESET: reset to the on-disk value.
+ * - GIT_SUBMODULE_IGNORE_FALLBACK: use the submodule's configuration
* - GIT_SUBMODULE_IGNORE_NONE: don't ignore any change - i.e. even an
* untracked file, will mark the submodule as dirty. Ignored files are
* still ignored, of course.
@@ -400,14 +397,12 @@ typedef enum {
* when we don't want any particular ignore rule to be specified.
*/
typedef enum {
- GIT_SUBMODULE_IGNORE_RESET = -1, /**< reset to on-disk value */
+ GIT_SUBMODULE_IGNORE_FALLBACK = -1, /**< use the submodule's configuration */
GIT_SUBMODULE_IGNORE_NONE = 1, /**< any change or untracked == dirty */
GIT_SUBMODULE_IGNORE_UNTRACKED = 2, /**< dirty if tracked files change */
GIT_SUBMODULE_IGNORE_DIRTY = 3, /**< only dirty if HEAD moved */
GIT_SUBMODULE_IGNORE_ALL = 4, /**< never dirty */
-
- GIT_SUBMODULE_IGNORE_DEFAULT = 0
} git_submodule_ignore_t;
/**
@@ -415,15 +410,12 @@ typedef enum {
*
* Represent the value of `submodule.$name.fetchRecurseSubmodules`
*
- * * GIT_SUBMODULE_RECURSE_RESET - reset to the on-disk value
* * GIT_SUBMODULE_RECURSE_NO - do no recurse into submodules
* * GIT_SUBMODULE_RECURSE_YES - recurse into submodules
* * GIT_SUBMODULE_RECURSE_ONDEMAND - recurse into submodules only when
* commit not already in local clone
*/
typedef enum {
- GIT_SUBMODULE_RECURSE_RESET = -1,
-
GIT_SUBMODULE_RECURSE_NO = 0,
GIT_SUBMODULE_RECURSE_YES = 1,
GIT_SUBMODULE_RECURSE_ONDEMAND = 2,
diff --git a/src/checkout.c b/src/checkout.c
index 2893c63de..351e8b0ef 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -180,7 +180,7 @@ static bool checkout_is_workdir_modified(
return true;
}
- if (git_submodule_status(&sm_status, sm) < 0 ||
+ if (git_submodule_status(&sm_status, data->repo, wditem->path, GIT_SUBMODULE_IGNORE_FALLBACK) < 0 ||
GIT_SUBMODULE_STATUS_IS_WD_DIRTY(sm_status))
rval = true;
else if ((sm_oid = git_submodule_wd_id(sm)) == NULL)
@@ -1860,11 +1860,6 @@ static int checkout_create_submodules(
git_diff_delta *delta;
size_t i;
- /* initial reload of submodules if .gitmodules was changed */
- if (data->reload_submodules &&
- (error = git_submodule_reload_all(data->repo, 1)) < 0)
- return error;
-
git_vector_foreach(&data->diff->deltas, i, delta) {
if (actions[i] & CHECKOUT_ACTION__DEFER_REMOVE) {
/* this has a blocker directory that should only be removed iff
@@ -1885,8 +1880,7 @@ static int checkout_create_submodules(
}
}
- /* final reload once submodules have been updated */
- return git_submodule_reload_all(data->repo, 1);
+ return 0;
}
static int checkout_lookup_head_tree(git_tree **out, git_repository *repo)
diff --git a/src/config.c b/src/config.c
index 1400b9513..77cf573e6 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1194,6 +1194,26 @@ fail_parse:
return -1;
}
+int git_config_lookup_map_enum(git_cvar_t *type_out, const char **str_out,
+ const git_cvar_map *maps, size_t map_n, int enum_val)
+{
+ size_t i;
+
+ for (i = 0; i < map_n; i++) {
+ const git_cvar_map *m = &maps[i];
+
+ if (m->map_value != enum_val)
+ continue;
+
+ *type_out = m->cvar_type;
+ *str_out = m->str_match;
+ return 0;
+ }
+
+ giterr_set(GITERR_CONFIG, "invalid enum value");
+ return GIT_ENOTFOUND;
+}
+
int git_config_parse_bool(int *out, const char *value)
{
if (git__parse_bool(out, value) == 0)
diff --git a/src/config.h b/src/config.h
index 691868b1d..f257cc90f 100644
--- a/src/config.h
+++ b/src/config.h
@@ -82,4 +82,10 @@ extern int git_config__get_int_force(
extern int git_config__cvar(
int *out, git_config *config, git_cvar_cached cvar);
+/**
+ * The opposite of git_config_lookup_map_value, we take an enum value
+ * and map it to the string or bool value on the config.
+ */
+int git_config_lookup_map_enum(git_cvar_t *type_out, const char **str_out,
+ const git_cvar_map *maps, size_t map_n, int enum_val);
#endif
diff --git a/src/diff_file.c b/src/diff_file.c
index cef4bc169..28edcd4c1 100644
--- a/src/diff_file.c
+++ b/src/diff_file.c
@@ -186,7 +186,7 @@ static int diff_file_content_commit_to_str(
return error;
}
- if ((error = git_submodule_status(&sm_status, sm)) < 0) {
+ if ((error = git_submodule_status(&sm_status, fc->repo, fc->file->path, GIT_SUBMODULE_IGNORE_FALLBACK)) < 0) {
git_submodule_free(sm);
return error;
}
diff --git a/src/repository.c b/src/repository.c
index de1c0dc1f..82d998124 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -111,7 +111,6 @@ void git_repository__cleanup(git_repository *repo)
git_cache_clear(&repo->objects);
git_attr_cache_flush(repo);
- git_submodule_cache_free(repo);
set_config(repo, NULL);
set_index(repo, NULL);
diff --git a/src/repository.h b/src/repository.h
index 253287368..fd679b483 100644
--- a/src/repository.h
+++ b/src/repository.h
@@ -121,7 +121,6 @@ struct git_repository {
git_refdb *_refdb;
git_config *_config;
git_index *_index;
- git_submodule_cache *_submodules;
git_cache objects;
git_attr_cache *attrcache;
diff --git a/src/submodule.c b/src/submodule.c
index 246502e99..45163da1b 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -87,17 +87,16 @@ __KHASH_IMPL(
str, static kh_inline, const char *, void *, 1,
str_hash_no_trailing_slash, str_equal_no_trailing_slash)
-static int submodule_cache_init(git_repository *repo, int refresh);
-static void submodule_cache_free(git_submodule_cache *cache);
-
-static git_config_backend *open_gitmodules(git_submodule_cache *, int gitmod);
+static int submodule_alloc(git_submodule **out, git_repository *repo, const char *name);
+static git_config_backend *open_gitmodules(git_repository *repo, int gitmod);
static int get_url_base(git_buf *url, git_repository *repo);
static int lookup_head_remote_key(git_buf *remote_key, git_repository *repo);
-static int submodule_get(git_submodule **, git_submodule_cache *, const char *, const char *);
static int submodule_load_from_config(const git_config_entry *, void *);
static int submodule_load_from_wd_lite(git_submodule *);
static void submodule_get_index_status(unsigned int *, git_submodule *);
static void submodule_get_wd_status(unsigned int *, git_submodule *, git_repository *, git_submodule_ignore_t);
+static void submodule_update_from_index_entry(git_submodule *sm, const git_index_entry *ie);
+static void submodule_update_from_head_data(git_submodule *sm, mode_t mode, const git_oid *id);
static int submodule_cmp(const void *a, const void *b)
{
@@ -111,69 +110,10 @@ static int submodule_config_key_trunc_puts(git_buf *key, const char *suffix)
return git_buf_puts(key, suffix);
}
-/* lookup submodule or return ENOTFOUND if it doesn't exist */
-static int submodule_lookup(
- git_submodule **out,
- git_submodule_cache *cache,
- const char *name,
- const char *alternate)
-{
- khiter_t pos;
-
- /* lock cache */
-
- pos = git_strmap_lookup_index(cache->submodules, name);
-
- if (!git_strmap_valid_index(cache->submodules, pos) && alternate)
- pos = git_strmap_lookup_index(cache->submodules, alternate);
-
- if (!git_strmap_valid_index(cache->submodules, pos)) {
- /* unlock cache */
- return GIT_ENOTFOUND; /* don't set error - caller will cope */
- }
-
- if (out != NULL) {
- git_submodule *sm = git_strmap_value_at(cache->submodules, pos);
- GIT_REFCOUNT_INC(sm);
- *out = sm;
- }
-
- /* unlock cache */
-
- return 0;
-}
-
-/* clear a set of flags on all submodules */
-static void submodule_cache_clear_flags(
- git_submodule_cache *cache, uint32_t mask)
-{
- git_submodule *sm;
- uint32_t inverted_mask = ~mask;
-
- git_strmap_foreach_value(cache->submodules, sm, {
- sm->flags &= inverted_mask;
- });
-}
-
/*
* PUBLIC APIS
*/
-bool git_submodule__is_submodule(git_repository *repo, const char *name)
-{
- git_strmap *map;
-
- if (submodule_cache_init(repo, CACHE_OK) < 0) {
- giterr_clear();
- return false;
- }
-
- if (!repo->_submodules || !(map = repo->_submodules->submodules))
- return false;
-
- return git_strmap_valid_index(map, git_strmap_lookup_index(map, name));
-}
-
static void submodule_set_lookup_error(int error, const char *name)
{
if (!error)
@@ -184,22 +124,24 @@ static void submodule_set_lookup_error(int error, const char *name)
"Submodule '%s' has not been added yet", name);
}
-int git_submodule__lookup(
- git_submodule **out, /* NULL if user only wants to test existence */
- git_repository *repo,
- const char *name) /* trailing slash is allowed */
-{
- int error;
+typedef struct {
+ const char *path;
+ char *name;
+} fbp_data;
- assert(repo && name);
-
- if ((error = submodule_cache_init(repo, CACHE_OK)) < 0)
- return error;
+static int find_by_path(const git_config_entry *entry, void *payload)
+{
+ fbp_data *data = payload;
- if ((error = submodule_lookup(out, repo->_submodules, name, NULL)) < 0)
- submodule_set_lookup_error(error, name);
+ if (!strcmp(entry->value, data->path)) {
+ const char *fdot, *ldot;
+ fdot = strchr(entry->name, '.');
+ ldot = strrchr(entry->name, '.');
+ data->name = git__strndup(fdot + 1, ldot - fdot - 1);
+ GITERR_CHECK_ALLOC(data->name);
+ }
- return error;
+ return 0;
}
int git_submodule_lookup(
@@ -208,20 +150,71 @@ int git_submodule_lookup(
const char *name) /* trailing slash is allowed */
{
int error;
+ unsigned int location;
+ git_submodule *sm;
assert(repo && name);
- if ((error = submodule_cache_init(repo, CACHE_REFRESH)) < 0)
+ if ((error = submodule_alloc(&sm, repo, name)) < 0)
+ return error;
+
+ if ((error = git_submodule_reload(sm, false)) < 0) {
+ git_submodule_free(sm);
+ return error;
+ }
+
+ if ((error = git_submodule_location(&location, sm)) < 0) {
+ git_submodule_free(sm);
return error;
+ }
+
+ /* If it's not configured, we need to check for the path */
+ if (location == 0 || location == GIT_SUBMODULE_STATUS_IN_WD) {
+ git_config_backend *mods;
+ const char *pattern = "submodule\\..*\\.path";
+ fbp_data data = { name, NULL };
+
+ mods = open_gitmodules(repo, GITMODULES_EXISTING);
+
+ if (mods)
+ error = git_config_file_foreach_match(mods, pattern, find_by_path, &data);
- if ((error = submodule_lookup(out, repo->_submodules, name, NULL)) < 0) {
+ git_config_file_free(mods);
+
+ if (error < 0) {
+ git_submodule_free(sm);
+ return error;
+ }
+
+ if (data.name) {
+ git__free(sm->name);
+ sm->name = data.name;
+ sm->path = git__strdup(name);
+ GITERR_CHECK_ALLOC(sm->path);
- /* check if a plausible submodule exists at path */
+ /* Try to load again with the right name */
+ if ((error = git_submodule_reload(sm, false)) < 0) {
+ git_submodule_free(sm);
+ return error;
+ }
+ }
+ }
+
+ if ((error = git_submodule_location(&location, sm)) < 0) {
+ git_submodule_free(sm);
+ return error;
+ }
+
+ /* If we still haven't found it, do the WD check */
+ if (location == 0 || location == GIT_SUBMODULE_STATUS_IN_WD) {
+ git_submodule_free(sm);
+ error = GIT_ENOTFOUND;
+
+ /* If it's not configured, we still check if there's a repo at the path */
if (git_repository_workdir(repo)) {
git_buf path = GIT_BUF_INIT;
-
if (git_buf_join3(&path,
- '/', git_repository_workdir(repo), name, DOT_GIT) < 0)
+ '/', git_repository_workdir(repo), name, DOT_GIT) < 0)
return -1;
if (git_path_exists(path.ptr))
@@ -231,9 +224,15 @@ int git_submodule_lookup(
}
submodule_set_lookup_error(error, name);
+ return error;
}
- return error;
+ if (out)
+ *out = sm;
+ else
+ git_submodule_free(sm);
+
+ return 0;
}
static void submodule_free_dup(void *sm)
@@ -241,41 +240,221 @@ static void submodule_free_dup(void *sm)
git_submodule_free(sm);
}
+static int submodule_get_or_create(git_submodule **out, git_repository *repo, git_strmap *map, const char *name)
+{
+ int error = 0;
+ khiter_t pos;
+ git_submodule *sm = NULL;
+
+ pos = git_strmap_lookup_index(map, name);
+ if (git_strmap_valid_index(map, pos)) {
+ sm = git_strmap_value_at(map, pos);
+ goto done;
+ }
+
+ /* if the submodule doesn't exist yet in the map, create it */
+ if ((error = submodule_alloc(&sm, repo, name)) < 0)
+ return error;
+
+ pos = kh_put(str, map, sm->name, &error);
+ /* nobody can beat us to adding it */
+ assert(error != 0);
+ if (error < 0) {
+ git_submodule_free(sm);
+ return error;
+ }
+
+ git_strmap_set_value_at(map, pos, sm);
+
+done:
+ GIT_REFCOUNT_INC(sm);
+ *out = sm;
+ return 0;
+}
+
+static int submodules_from_index(git_strmap *map, git_index *idx)
+{
+ int error;
+ git_iterator *i;
+ const git_index_entry *entry;
+
+ if ((error = git_iterator_for_index(&i, idx, 0, NULL, NULL)) < 0)
+ return error;
+
+ while (!(error = git_iterator_advance(&entry, i))) {
+ khiter_t pos = git_strmap_lookup_index(map, entry->path);
+ git_submodule *sm;
+
+ if (git_strmap_valid_index(map, pos)) {
+ sm = git_strmap_value_at(map, pos);
+
+ if (S_ISGITLINK(entry->mode))
+ submodule_update_from_index_entry(sm, entry);
+ else
+ sm->flags |= GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE;
+ } else if (S_ISGITLINK(entry->mode)) {
+ if (!submodule_get_or_create(&sm, git_index_owner(idx), map, entry->path)) {
+ submodule_update_from_index_entry(sm, entry);
+ git_submodule_free(sm);
+ }
+ }
+ }
+
+ if (error == GIT_ITEROVER)
+ error = 0;
+
+ git_iterator_free(i);
+
+ return error;
+}
+
+static int submodules_from_head(git_strmap *map, git_tree *head)
+{
+ int error;
+ git_iterator *i;
+ const git_index_entry *entry;
+
+ if ((error = git_iterator_for_tree(&i, head, 0, NULL, NULL)) < 0)
+ return error;
+
+ while (!(error = git_iterator_advance(&entry, i))) {
+ khiter_t pos = git_strmap_lookup_index(map, entry->path);
+ git_submodule *sm;
+
+ if (git_strmap_valid_index(map, pos)) {
+ sm = git_strmap_value_at(map, pos);
+
+ if (S_ISGITLINK(entry->mode))
+ submodule_update_from_head_data(sm, entry->mode, &entry->id);
+ else
+ sm->flags |= GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE;
+ } else if (S_ISGITLINK(entry->mode)) {
+ if (!submodule_get_or_create(&sm, git_tree_owner(head), map, entry->path)) {
+ submodule_update_from_head_data(
+ sm, entry->mode, &entry->id);
+ git_submodule_free(sm);
+ }
+ }
+ }
+
+ if (error == GIT_ITEROVER)
+ error = 0;
+
+ git_iterator_free(i);
+
+ return error;
+}
+
+/* If have_sm is true, sm is populated, otherwise map an repo are. */
+typedef struct {
+ int have_sm;
+ git_submodule *sm;
+ git_strmap *map;
+ git_repository *repo;
+} lfc_data;
+
+static int all_submodules(git_repository *repo, git_strmap *map)
+{
+ int error = 0;
+ git_index *idx = NULL;
+ git_tree *head = NULL;
+ const char *wd = NULL;
+ git_buf path = GIT_BUF_INIT;
+ git_submodule *sm;
+ git_config_backend *mods = NULL;
+ uint32_t mask;
+
+ assert(repo && map);
+
+ /* get sources that we will need to check */
+ if (git_repository_index(&idx, repo) < 0)
+ giterr_clear();
+ if (git_repository_head_tree(&head, repo) < 0)
+ giterr_clear();
+
+ wd = git_repository_workdir(repo);
+ if (wd && (error = git_buf_joinpath(&path, wd, GIT_MODULES_FILE)) < 0)
+ goto cleanup;
+
+ /* clear submodule flags that are to be refreshed */
+ mask = 0;
+ mask |= GIT_SUBMODULE_STATUS_IN_INDEX |
+ GIT_SUBMODULE_STATUS__INDEX_FLAGS |
+ GIT_SUBMODULE_STATUS__INDEX_OID_VALID |
+ GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES;
+
+ mask |= GIT_SUBMODULE_STATUS_IN_HEAD |
+ GIT_SUBMODULE_STATUS__HEAD_OID_VALID;
+ mask |= GIT_SUBMODULE_STATUS_IN_CONFIG;
+ if (mask != 0)
+ mask |= GIT_SUBMODULE_STATUS_IN_WD |
+ GIT_SUBMODULE_STATUS__WD_SCANNED |
+ GIT_SUBMODULE_STATUS__WD_FLAGS |
+ GIT_SUBMODULE_STATUS__WD_OID_VALID;
+
+ /* add back submodule information from index */
+ if (idx) {
+ if ((error = submodules_from_index(map, idx)) < 0)
+ goto cleanup;
+ }
+ /* add submodule information from HEAD */
+ if (head) {
+ if ((error = submodules_from_head(map, head)) < 0)
+ goto cleanup;
+ }
+ /* add submodule information from .gitmodules */
+ if (wd) {
+ lfc_data data = { 0 };
+ data.map = map;
+ data.repo = repo;
+ if ((mods = open_gitmodules(repo, false)) != NULL &&
+ (error = git_config_file_foreach(
+ mods, submodule_load_from_config, &data)) < 0)
+ goto cleanup;
+ }
+ /* shallow scan submodules in work tree as needed */
+ if (wd && mask != 0) {
+ git_strmap_foreach_value(map, sm, {
+ submodule_load_from_wd_lite(sm);
+ });
+ }
+
+cleanup:
+ git_config_file_free(mods);
+ /* TODO: if we got an error, mark submodule config as invalid? */
+ git_index_free(idx);
+ git_tree_free(head);
+ git_buf_free(&path);
+ return error;
+}
+
int git_submodule_foreach(
git_repository *repo,
int (*callback)(git_submodule *sm, const char *name, void *payload),
void *payload)
{
+ git_vector snapshot = GIT_VECTOR_INIT;
+ git_strmap *submodules;
+ git_submodule *sm;
int error;
size_t i;
- git_submodule *sm;
- git_submodule_cache *cache;
- git_vector snapshot = GIT_VECTOR_INIT;
-
- assert(repo && callback);
- if ((error = submodule_cache_init(repo, CACHE_REFRESH)) < 0)
+ if ((error = git_strmap_alloc(&submodules)) < 0)
return error;
- cache = repo->_submodules;
-
- if (git_mutex_lock(&cache->lock) < 0) {
- giterr_set(GITERR_OS, "Unable to acquire lock on submodule cache");
- return -1;
- }
+ if ((error = all_submodules(repo, submodules)) < 0)
+ goto done;
if (!(error = git_vector_init(
- &snapshot, kh_size(cache->submodules), submodule_cmp))) {
+ &snapshot, kh_size(submodules), submodule_cmp))) {
- git_strmap_foreach_value(cache->submodules, sm, {
+ git_strmap_foreach_value(submodules, sm, {
if ((error = git_vector_insert(&snapshot, sm)) < 0)
break;
GIT_REFCOUNT_INC(sm);
});
}
- git_mutex_unlock(&cache->lock);
-
if (error < 0)
goto done;
@@ -293,17 +472,12 @@ done:
git_submodule_free(sm);
git_vector_free(&snapshot);
- return error;
-}
-
-void git_submodule_cache_free(git_repository *repo)
-{
- git_submodule_cache *cache;
-
- assert(repo);
+ git_strmap_foreach_value(submodules, sm, {
+ git_submodule_free(sm);
+ });
+ git_strmap_free(submodules);
- if ((cache = git__swap(repo->_submodules, NULL)) != NULL)
- submodule_cache_free(cache);
+ return error;
}
static int submodule_repo_init(
@@ -394,7 +568,7 @@ int git_submodule_add_setup(
/* update .gitmodules */
- if (!(mods = open_gitmodules(repo->_submodules, GITMODULES_CREATE))) {
+ if (!(mods = open_gitmodules(repo, GITMODULES_CREATE))) {
giterr_set(GITERR_SUBMODULE,
"Adding submodules to a bare repository is not supported");
return -1;
@@ -430,19 +604,10 @@ int git_submodule_add_setup(
goto cleanup;
}
- /* add submodule to hash and "reload" it */
-
- if (git_mutex_lock(&repo->_submodules->lock) < 0) {
- giterr_set(GITERR_OS, "Unable to acquire lock on submodule cache");
- error = -1;
+ if ((error = git_submodule_lookup(&sm, repo, path)) < 0)
goto cleanup;
- }
- if (!(error = submodule_get(&sm, repo->_submodules, path, NULL)) &&
- !(error = git_submodule_reload(sm, false)))
- error = git_submodule_init(sm, false);
-
- git_mutex_unlock(&repo->_submodules->lock);
+ error = git_submodule_init(sm, false);
cleanup:
if (error && sm) {
@@ -572,15 +737,6 @@ cleanup:
return error;
}
-const char *git_submodule_ignore_to_str(git_submodule_ignore_t ignore)
-{
- int i;
- for (i = 0; i < (int)ARRAY_SIZE(_sm_ignore_map); ++i)
- if (_sm_ignore_map[i].map_value == ignore)
- return _sm_ignore_map[i].str_match;
- return NULL;
-}
-
const char *git_submodule_update_to_str(git_submodule_update_t update)
{
int i;
@@ -590,89 +746,6 @@ const char *git_submodule_update_to_str(git_submodule_update_t update)
return NULL;
}
-const char *git_submodule_recurse_to_str(git_submodule_recurse_t recurse)
-{
- int i;
- for (i = 0; i < (int)ARRAY_SIZE(_sm_recurse_map); ++i)
- if (_sm_recurse_map[i].map_value == recurse)
- return _sm_recurse_map[i].str_match;
- return NULL;
-}
-
-int git_submodule_save(git_submodule *submodule)
-{
- int error = 0;
- git_config_backend *mods;
- git_buf key = GIT_BUF_INIT;
- const char *val;
-
- assert(submodule);
-
- mods = open_gitmodules(submodule->repo->_submodules, GITMODULES_CREATE);
- if (!mods) {
- giterr_set(GITERR_SUBMODULE,
- "Adding submodules to a bare repository is not supported");
- return -1;
- }
-
- if ((error = git_buf_printf(&key, "submodule.%s.", submodule->name)) < 0)
- goto cleanup;
-
- /* save values for path, url, update, ignore, fetchRecurseSubmodules */
-
- if ((error = submodule_config_key_trunc_puts(&key, "path")) < 0 ||
- (error = git_config_file_set_string(mods, key.ptr, submodule->path)) < 0)
- goto cleanup;
-
- if ((error = submodule_config_key_trunc_puts(&key, "url")) < 0 ||
- (error = git_config_file_set_string(mods, key.ptr, submodule->url)) < 0)
- goto cleanup;
-
- if ((error = submodule_config_key_trunc_puts(&key, "branch")) < 0)
- goto cleanup;
- if (submodule->branch == NULL)
- error = git_config_file_delete(mods, key.ptr);
- else
- error = git_config_file_set_string(mods, key.ptr, submodule->branch);
- if (error == GIT_ENOTFOUND) {
- error = 0;
- giterr_clear();
- }
- if (error < 0)
- goto cleanup;
-
- if (!(error = submodule_config_key_trunc_puts(&key, "update")) &&
- (val = git_submodule_update_to_str(submodule->update)) != NULL)
- error = git_config_file_set_string(mods, key.ptr, val);
- if (error < 0)
- goto cleanup;
-
- if (!(error = submodule_config_key_trunc_puts(&key, "ignore")) &&
- (val = git_submodule_ignore_to_str(submodule->ignore)) != NULL)
- error = git_config_file_set_string(mods, key.ptr, val);
- if (error < 0)
- goto cleanup;
-
- if (!(error = submodule_config_key_trunc_puts(&key, "fetchRecurseSubmodules")) &&
- (val = git_submodule_recurse_to_str(submodule->fetch_recurse)) != NULL)
- error = git_config_file_set_string(mods, key.ptr, val);
- if (error < 0)
- goto cleanup;
-
- /* update internal defaults */
-
- submodule->ignore_default = submodule->ignore;
- submodule->update_default = submodule->update;
- submodule->fetch_recurse_default = submodule->fetch_recurse;
- submodule->flags |= GIT_SUBMODULE_STATUS_IN_CONFIG;
-
-cleanup:
- git_config_file_free(mods);
- git_buf_free(&key);
-
- return error;
-}
-
git_repository *git_submodule_owner(git_submodule *submodule)
{
assert(submodule);
@@ -718,37 +791,66 @@ int git_submodule_resolve_url(git_buf *out, git_repository *repo, const char *ur
return error;
}
-const char *git_submodule_branch(git_submodule *submodule)
+static int write_var(git_repository *repo, const char *name, const char *var, const char *val)
{
- assert(submodule);
- return submodule->branch;
+ git_buf key = GIT_BUF_INIT;
+ git_config_backend *mods;
+ int error;
+
+ mods = open_gitmodules(repo, GITMODULES_CREATE);
+ if (!mods)
+ return -1;
+
+ if ((error = git_buf_printf(&key, "submodule.%s.%s", name, var)) < 0)
+ goto cleanup;
+
+ if (val)
+ error = git_config_file_set_string(mods, key.ptr, val);
+ else
+ error = git_config_file_delete(mods, key.ptr);
+
+ git_buf_free(&key);
+
+cleanup:
+ git_config_file_free(mods);
+ return error;
}
-int git_submodule_set_branch(git_submodule *submodule, const char *branch)
+static int write_mapped_var(git_repository *repo, const char *name, git_cvar_map *maps, size_t nmaps, const char *var, int ival)
{
- assert(submodule);
-
- git__free(submodule->branch);
- submodule->branch = NULL;
+ git_cvar_t type;
+ const char *val;
- if (branch != NULL) {
- submodule->branch = git__strdup(branch);
- GITERR_CHECK_ALLOC(submodule->branch);
+ if (git_config_lookup_map_enum(&type, &val, maps, nmaps, ival) < 0) {
+ giterr_set(GITERR_SUBMODULE, "invalid value for %s", var);
+ return -1;
}
- return 0;
+ if (type == GIT_CVAR_TRUE)
+ val = "true";
+
+ return write_var(repo, name, var, val);
}
-int git_submodule_set_url(git_submodule *submodule, const char *url)
+const char *git_submodule_branch(git_submodule *submodule)
{
- assert(submodule && url);
+ assert(submodule);
+ return submodule->branch;
+}
- git__free(submodule->url);
+int git_submodule_set_branch(git_repository *repo, const char *name, const char *branch)
+{
- submodule->url = git__strdup(url);
- GITERR_CHECK_ALLOC(submodule->url);
+ assert(repo && name);
- return 0;
+ return write_var(repo, name, "branch", branch);
+}
+
+int git_submodule_set_url(git_repository *repo, const char *name, const char *url)
+{
+ assert(repo && name && url);
+
+ return write_var(repo, name, "url", url);
}
const git_oid *git_submodule_index_id(git_submodule *submodule)
@@ -799,19 +901,11 @@ git_submodule_ignore_t git_submodule_ignore(git_submodule *submodule)
GIT_SUBMODULE_IGNORE_NONE : submodule->ignore;
}
-git_submodule_ignore_t git_submodule_set_ignore(
- git_submodule *submodule, git_submodule_ignore_t ignore)
+int git_submodule_set_ignore(git_repository *repo, const char *name, git_submodule_ignore_t ignore)
{
- git_submodule_ignore_t old;
-
- assert(submodule);
-
- if (ignore == GIT_SUBMODULE_IGNORE_RESET)
- ignore = submodule->ignore_default;
+ assert(repo && name);
- old = submodule->ignore;
- submodule->ignore = ignore;
- return old;
+ return write_mapped_var(repo, name, _sm_ignore_map, ARRAY_SIZE(_sm_ignore_map), "ignore", ignore);
}
git_submodule_update_t git_submodule_update_strategy(git_submodule *submodule)
@@ -821,19 +915,11 @@ git_submodule_update_t git_submodule_update_strategy(git_submodule *submodule)
GIT_SUBMODULE_UPDATE_CHECKOUT : submodule->update;
}
-git_submodule_update_t git_submodule_set_update(
- git_submodule *submodule, git_submodule_update_t update)
+int git_submodule_set_update(git_repository *repo, const char *name, git_submodule_update_t update)
{
- git_submodule_update_t old;
-
- assert(submodule);
-
- if (update == GIT_SUBMODULE_UPDATE_RESET)
- update = submodule->update_default;
+ assert(repo && name);
- old = submodule->update;
- submodule->update = update;
- return old;
+ return write_mapped_var(repo, name, _sm_update_map, ARRAY_SIZE(_sm_update_map), "update", update);
}
git_submodule_recurse_t git_submodule_fetch_recurse_submodules(
@@ -843,20 +929,11 @@ git_submodule_recurse_t git_submodule_fetch_recurse_submodules(
return submodule->fetch_recurse;
}
-git_submodule_recurse_t git_submodule_set_fetch_recurse_submodules(
- git_submodule *submodule,
- git_submodule_recurse_t fetch_recurse_submodules)
+int git_submodule_set_fetch_recurse_submodules(git_repository *repo, const char *name, git_submodule_recurse_t recurse)
{
- git_submodule_recurse_t old;
-
- assert(submodule);
-
- if (fetch_recurse_submodules == GIT_SUBMODULE_RECURSE_RESET)
- fetch_recurse_submodules = submodule->fetch_recurse_default;
+ assert(repo && name);
- old = submodule->fetch_recurse;
- submodule->fetch_recurse = fetch_recurse_submodules;
- return old;
+ return write_mapped_var(repo, name, _sm_recurse_map, ARRAY_SIZE(_sm_recurse_map), "fetchRecurseSubmodules", recurse);
}
static int submodule_repo_create(
@@ -953,7 +1030,7 @@ int git_submodule_update(git_submodule *sm, int init, git_submodule_update_optio
memcpy(&clone_options.fetch_opts, &update_options.fetch_opts, sizeof(git_fetch_options));
/* Get the status of the submodule to determine if it is already initialized */
- if ((error = git_submodule_status(&submodule_status, sm)) < 0)
+ if ((error = git_submodule_status(&submodule_status, sm->repo, sm->name, GIT_SUBMODULE_IGNORE_FALLBACK)) < 0)
goto done;
/*
@@ -1197,11 +1274,6 @@ int git_submodule_open(git_repository **subrepo, git_submodule *sm)
return git_submodule__open(subrepo, sm, false);
}
-int git_submodule_reload_all(git_repository *repo, int force)
-{
- return submodule_cache_init(repo, force ? CACHE_FLUSH : CACHE_REFRESH);
-}
-
static void submodule_update_from_index_entry(
git_submodule *sm, const git_index_entry *ie)
{
@@ -1280,14 +1352,12 @@ int git_submodule_reload(git_submodule *sm, int force)
{
int error = 0;
git_config_backend *mods;
- git_submodule_cache *cache;
+ lfc_data data = { 0 };
GIT_UNUSED(force);
assert(sm);
- cache = sm->repo->_submodules;
-
/* refresh index data */
if ((error = submodule_update_index(sm)) < 0)
return error;
@@ -1301,7 +1371,7 @@ int git_submodule_reload(git_submodule *sm, int force)
return error;
/* refresh config data */
- mods = open_gitmodules(cache, GITMODULES_EXISTING);
+ mods = open_gitmodules(sm->repo, GITMODULES_EXISTING);
if (mods != NULL) {
git_buf path = GIT_BUF_INIT;
@@ -1309,11 +1379,14 @@ int git_submodule_reload(git_submodule *sm, int force)
git_buf_text_puts_escape_regex(&path, sm->name);
git_buf_puts(&path, ".*");
- if (git_buf_oom(&path))
+ if (git_buf_oom(&path)) {
error = -1;
- else
+ } else {
+ data.have_sm = 1;
+ data.sm = sm;
error = git_config_file_foreach_match(
- mods, path.ptr, submodule_load_from_config, cache);
+ mods, path.ptr, submodule_load_from_config, &data);
+ }
git_buf_free(&path);
git_config_file_free(mods);
@@ -1352,7 +1425,7 @@ int git_submodule__status(
unsigned int status;
git_repository *smrepo = NULL;
- if (ign < GIT_SUBMODULE_IGNORE_NONE)
+ if (ign == GIT_SUBMODULE_IGNORE_FALLBACK)
ign = sm->ignore;
/* only return location info if ignore == all */
@@ -1401,11 +1474,20 @@ int git_submodule__status(
return 0;
}
-int git_submodule_status(unsigned int *status, git_submodule *sm)
+int git_submodule_status(unsigned int *status, git_repository *repo, const char *name, git_submodule_ignore_t ignore)
{
- assert(status && sm);
+ git_submodule *sm;
+ int error;
+
+ assert(status && repo && name);
- return git_submodule__status(status, NULL, NULL, NULL, sm, 0);
+ if ((error = git_submodule_lookup(&sm, repo, name)) < 0)
+ return error;
+
+ error = git_submodule__status(status, NULL, NULL, NULL, sm, ignore);
+ git_submodule_free(sm);
+
+ return error;
}
int git_submodule_location(unsigned int *location, git_submodule *sm)
@@ -1422,7 +1504,7 @@ int git_submodule_location(unsigned int *location, git_submodule *sm)
*/
static int submodule_alloc(
- git_submodule **out, git_submodule_cache *cache, const char *name)
+ git_submodule **out, git_repository *repo, const char *name)
{
size_t namelen;
git_submodule *sm;
@@ -1445,56 +1527,20 @@ static int submodule_alloc(
sm->ignore = sm->ignore_default = GIT_SUBMODULE_IGNORE_NONE;
sm->update = sm->update_default = GIT_SUBMODULE_UPDATE_CHECKOUT;
sm->fetch_recurse = sm->fetch_recurse_default = GIT_SUBMODULE_RECURSE_NO;
- sm->repo = cache->repo;
+ sm->repo = repo;
sm->branch = NULL;
*out = sm;
return 0;
}
-static void submodule_cache_remove_item(
- git_submodule_cache *cache,
- git_submodule *item,
- bool free_after_remove)
-{
- git_strmap *map;
- const char *name, *alt;
-
- if (!cache || !(map = cache->submodules) || !item)
- return;
-
- name = item->name;
- alt = (item->path != item->name) ? item->path : NULL;
-
- for (; name; name = alt, alt = NULL) {
- khiter_t pos = git_strmap_lookup_index(map, name);
- git_submodule *found;
-
- if (!git_strmap_valid_index(map, pos))
- continue;
-
- found = git_strmap_value_at(map, pos);
-
- if (found != item)
- continue;
-
- git_strmap_set_value_at(map, pos, NULL);
- git_strmap_delete_at(map, pos);
-
- if (free_after_remove)
- git_submodule_free(found);
- }
-}
-
static void submodule_release(git_submodule *sm)
{
if (!sm)
return;
if (sm->repo) {
- git_submodule_cache *cache = sm->repo->_submodules;
sm->repo = NULL;
- submodule_cache_remove_item(cache, sm, false);
}
if (sm->path != sm->name)
@@ -1513,54 +1559,6 @@ void git_submodule_free(git_submodule *sm)
GIT_REFCOUNT_DEC(sm, submodule_release);
}
-static int submodule_get(
- git_submodule **out,
- git_submodule_cache *cache,
- const char *name,
- const char *alternate)
-{
- int error = 0;
- khiter_t pos;
- git_submodule *sm;
-
- pos = git_strmap_lookup_index(cache->submodules, name);
-
- if (!git_strmap_valid_index(cache->submodules, pos) && alternate)
- pos = git_strmap_lookup_index(cache->submodules, alternate);
-
- if (!git_strmap_valid_index(cache->submodules, pos)) {
- if ((error = submodule_alloc(&sm, cache, name)) < 0)
- return error;
-
- /* insert value at name - if another thread beats us to it, then use
- * their record and release our own.
- */
- pos = kh_put(str, cache->submodules, sm->name, &error);
-
- if (error < 0)
- goto done;
- else if (error == 0) {
- git_submodule_free(sm);
- sm = git_strmap_value_at(cache->submodules, pos);
- } else {
- error = 0;
- git_strmap_set_value_at(cache->submodules, pos, sm);
- }
- } else {
- sm = git_strmap_value_at(cache->submodules, pos);
- }
-
-done:
- if (error < 0)
- git_submodule_free(sm);
- else if (out) {
- GIT_REFCOUNT_INC(sm);
- *out = sm;
- }
-
- return error;
-}
-
static int submodule_config_error(const char *property, const char *value)
{
giterr_set(GITERR_INVALID,
@@ -1613,12 +1611,12 @@ int git_submodule_parse_recurse(git_submodule_recurse_t *out, const char *value)
static int submodule_load_from_config(
const git_config_entry *entry, void *payload)
{
- git_submodule_cache *cache = payload;
const char *namestart, *property;
const char *key = entry->name, *value = entry->value, *path;
char *alternate = NULL, *replaced = NULL;
git_buf name = GIT_BUF_INIT;
- git_submodule *sm = NULL;
+ lfc_data *data = payload;
+ git_submodule *sm;
int error = 0;
if (git__prefixcmp(key, "submodule.") != 0)
@@ -1633,10 +1631,29 @@ static int submodule_load_from_config(
property++;
path = !strcasecmp(property, "path") ? value : NULL;
- if ((error = git_buf_set(&name, namestart, property - namestart - 1)) < 0 ||
- (error = submodule_get(&sm, cache, name.ptr, path)) < 0)
+ if ((error = git_buf_set(&name, namestart, property - namestart -1)) < 0)
goto done;
+ if (data->have_sm) {
+ sm = data->sm;
+ } else {
+ khiter_t pos;
+ git_strmap *map = data->map;
+ pos = git_strmap_lookup_index(map, name.ptr);
+ if (git_strmap_valid_index(map, pos)) {
+ sm = git_strmap_value_at(map, pos);
+ } else {
+ if ((error = submodule_alloc(&sm, data->repo, name.ptr)) < 0)
+ goto done;
+
+ git_strmap_insert(map, sm->name, sm, error);
+ assert(error != 0);
+ if (error < 0)
+ goto done;
+ error = 0;
+ }
+ }
+
sm->flags |= GIT_SUBMODULE_STATUS_IN_CONFIG;
/* Only from config might we get differing names & paths. If so, then
@@ -1648,7 +1665,7 @@ static int submodule_load_from_config(
*/
if (strcmp(sm->name, name.ptr) != 0) { /* name changed */
- if (!strcmp(sm->path, name.ptr)) { /* already set as path */
+ if (sm->path && !strcmp(sm->path, name.ptr)) { /* already set as path */
replaced = sm->name;
sm->name = sm->path;
} else {
@@ -1674,7 +1691,6 @@ static int submodule_load_from_config(
/* Deregister under name being replaced */
if (replaced) {
- git_strmap_delete(cache->submodules, replaced);
git_submodule_free(sm);
git__free(replaced);
}
@@ -1682,7 +1698,6 @@ static int submodule_load_from_config(
/* Insert under alternate key */
if (alternate) {
void *old_sm = NULL;
- git_strmap_insert2(cache->submodules, alternate, sm, old_sm, error);
if (error < 0)
goto done;
@@ -1742,7 +1757,6 @@ static int submodule_load_from_config(
/* ignore other unknown submodule properties */
done:
- git_submodule_free(sm); /* offset refcount inc from submodule_get() */
git_buf_free(&name);
return error;
}
@@ -1764,86 +1778,11 @@ static int submodule_load_from_wd_lite(git_submodule *sm)
return 0;
}
-static int submodule_cache_refresh_from_index(
- git_submodule_cache *cache, git_index *idx)
-{
- int error;
- git_iterator *i;
- const git_index_entry *entry;
-
- if ((error = git_iterator_for_index(&i, idx, 0, NULL, NULL)) < 0)
- return error;
-
- while (!(error = git_iterator_advance(&entry, i))) {
- khiter_t pos = git_strmap_lookup_index(cache->submodules, entry->path);
- git_submodule *sm;
-
- if (git_strmap_valid_index(cache->submodules, pos)) {
- sm = git_strmap_value_at(cache->submodules, pos);
-
- if (S_ISGITLINK(entry->mode))
- submodule_update_from_index_entry(sm, entry);
- else
- sm->flags |= GIT_SUBMODULE_STATUS__INDEX_NOT_SUBMODULE;
- } else if (S_ISGITLINK(entry->mode)) {
- if (!submodule_get(&sm, cache, entry->path, NULL)) {
- submodule_update_from_index_entry(sm, entry);
- git_submodule_free(sm);
- }
- }
- }
-
- if (error == GIT_ITEROVER)
- error = 0;
-
- git_iterator_free(i);
-
- return error;
-}
-
-static int submodule_cache_refresh_from_head(
- git_submodule_cache *cache, git_tree *head)
-{
- int error;
- git_iterator *i;
- const git_index_entry *entry;
-
- if ((error = git_iterator_for_tree(&i, head, 0, NULL, NULL)) < 0)
- return error;
-
- while (!(error = git_iterator_advance(&entry, i))) {
- khiter_t pos = git_strmap_lookup_index(cache->submodules, entry->path);
- git_submodule *sm;
-
- if (git_strmap_valid_index(cache->submodules, pos)) {
- sm = git_strmap_value_at(cache->submodules, pos);
-
- if (S_ISGITLINK(entry->mode))
- submodule_update_from_head_data(sm, entry->mode, &entry->id);
- else
- sm->flags |= GIT_SUBMODULE_STATUS__HEAD_NOT_SUBMODULE;
- } else if (S_ISGITLINK(entry->mode)) {
- if (!submodule_get(&sm, cache, entry->path, NULL)) {
- submodule_update_from_head_data(
- sm, entry->mode, &entry->id);
- git_submodule_free(sm);
- }
- }
- }
-
- if (error == GIT_ITEROVER)
- error = 0;
-
- git_iterator_free(i);
-
- return error;
-}
-
static git_config_backend *open_gitmodules(
- git_submodule_cache *cache,
+ git_repository *repo,
int okay_to_create)
{
- const char *workdir = git_repository_workdir(cache->repo);
+ const char *workdir = git_repository_workdir(repo);
git_buf path = GIT_BUF_INIT;
git_config_backend *mods = NULL;
@@ -1868,198 +1807,6 @@ static git_config_backend *open_gitmodules(
return mods;
}
-static void submodule_cache_free(git_submodule_cache *cache)
-{
- git_submodule *sm;
-
- if (!cache)
- return;
-
- git_strmap_foreach_value(cache->submodules, sm, {
- sm->repo = NULL; /* disconnect from repo */
- git_submodule_free(sm);
- });
- git_strmap_free(cache->submodules);
-
- git_buf_free(&cache->gitmodules_path);
- git_mutex_free(&cache->lock);
- git__free(cache);
-}
-
-static int submodule_cache_alloc(
- git_submodule_cache **out, git_repository *repo)
-{
- git_submodule_cache *cache = git__calloc(1, sizeof(git_submodule_cache));
- GITERR_CHECK_ALLOC(cache);
-
- if (git_mutex_init(&cache->lock) < 0) {
- giterr_set(GITERR_OS, "Unable to initialize submodule cache lock");
- git__free(cache);
- return -1;
- }
-
- if (git_strmap_alloc(&cache->submodules) < 0) {
- submodule_cache_free(cache);
- return -1;
- }
-
- cache->repo = repo;
- git_buf_init(&cache->gitmodules_path, 0);
-
- *out = cache;
- return 0;
-}
-
-static int submodule_cache_refresh(git_submodule_cache *cache, int refresh)
-{
- int error = 0, update_index, update_head, update_gitmod;
- git_index *idx = NULL;
- git_tree *head = NULL;
- const char *wd = NULL;
- git_buf path = GIT_BUF_INIT;
- git_submodule *sm;
- git_config_backend *mods = NULL;
- uint32_t mask;
-
- if (!cache || !cache->repo || !refresh)
- return 0;
-
- if (git_mutex_lock(&cache->lock) < 0) {
- giterr_set(GITERR_OS, "Unable to acquire lock on submodule cache");
- return -1;
- }
-
- /* get sources that we will need to check */
-
- if (git_repository_index(&idx, cache->repo) < 0)
- giterr_clear();
- if (git_repository_head_tree(&head, cache->repo) < 0)
- giterr_clear();
-
- wd = git_repository_workdir(cache->repo);
- if (wd && (error = git_buf_joinpath(&path, wd, GIT_MODULES_FILE)) < 0)
- goto cleanup;
-
- /* check for invalidation */
-
- if (refresh == CACHE_FLUSH)
- update_index = update_head = update_gitmod = true;
- else {
- update_index =
- !idx || git_index__changed_relative_to(idx, &cache->index_checksum);
- update_head =
- !head || !git_oid_equal(&cache->head_id, git_tree_id(head));
-
- update_gitmod = (wd != NULL) ?
- git_futils_filestamp_check(&cache->gitmodules_stamp, path.ptr) :
- (cache->gitmodules_stamp.mtime != 0);
- }
-
- /* clear submodule flags that are to be refreshed */
-
- mask = 0;
- if (!idx || update_index)
- mask |= GIT_SUBMODULE_STATUS_IN_INDEX |
- GIT_SUBMODULE_STATUS__INDEX_FLAGS |
- GIT_SUBMODULE_STATUS__INDEX_OID_VALID |
- GIT_SUBMODULE_STATUS__INDEX_MULTIPLE_ENTRIES;
- if (!head || update_head)
- mask |= GIT_SUBMODULE_STATUS_IN_HEAD |
- GIT_SUBMODULE_STATUS__HEAD_OID_VALID;
- if (update_gitmod)
- mask |= GIT_SUBMODULE_STATUS_IN_CONFIG;
- if (mask != 0)
- mask |= GIT_SUBMODULE_STATUS_IN_WD |
- GIT_SUBMODULE_STATUS__WD_SCANNED |
- GIT_SUBMODULE_STATUS__WD_FLAGS |
- GIT_SUBMODULE_STATUS__WD_OID_VALID;
- else
- goto cleanup; /* nothing to do */
-
- submodule_cache_clear_flags(cache, mask);
-
- /* add back submodule information from index */
-
- if (idx && update_index) {
- if ((error = submodule_cache_refresh_from_index(cache, idx)) < 0)
- goto cleanup;
-
- git_oid_cpy(&cache->index_checksum, git_index_checksum(idx));
- }
-
- /* add submodule information from HEAD */
-
- if (head && update_head) {
- if ((error = submodule_cache_refresh_from_head(cache, head)) < 0)
- goto cleanup;
-
- git_oid_cpy(&cache->head_id, git_tree_id(head));
- }
-
- /* add submodule information from .gitmodules */
-
- if (wd && update_gitmod > 0) {
- if ((mods = open_gitmodules(cache, false)) != NULL &&
- (error = git_config_file_foreach(
- mods, submodule_load_from_config, cache)) < 0)
- goto cleanup;
- }
-
- /* shallow scan submodules in work tree as needed */
-
- if (wd && mask != 0) {
- git_strmap_foreach_value(cache->submodules, sm, {
- submodule_load_from_wd_lite(sm);
- });
- }
-
- /* remove submodules that no longer exist */
-
- git_strmap_foreach_value(cache->submodules, sm, {
- /* purge unless in HEAD, index, or .gitmodules; no sm for wd only */
- if (sm != NULL &&
- !(sm->flags &
- (GIT_SUBMODULE_STATUS_IN_HEAD |
- GIT_SUBMODULE_STATUS_IN_INDEX |
- GIT_SUBMODULE_STATUS_IN_CONFIG)))
- submodule_cache_remove_item(cache, sm, true);
- });
-
-cleanup:
- git_config_file_free(mods);
-
- /* TODO: if we got an error, mark submodule config as invalid? */
-
- git_mutex_unlock(&cache->lock);
-
- git_index_free(idx);
- git_tree_free(head);
- git_buf_free(&path);
-
- return error;
-}
-
-static int submodule_cache_init(git_repository *repo, int cache_refresh)
-{
- int error = 0;
- git_submodule_cache *cache = NULL;
-
- /* if submodules already exist, just refresh as requested */
- if (repo->_submodules)
- return submodule_cache_refresh(repo->_submodules, cache_refresh);
-
- /* otherwise create a new cache, load it, and atomically swap it in */
- if (!(error = submodule_cache_alloc(&cache, repo)) &&
- !(error = submodule_cache_refresh(cache, CACHE_FLUSH)))
- cache = git__compare_and_swap(&repo->_submodules, NULL, cache);
-
- /* might have raced with another thread to set cache, so free if needed */
- if (cache)
- submodule_cache_free(cache);
-
- return error;
-}
-
/* Lookup name of remote of the local tracking branch HEAD points to */
static int lookup_head_remote_key(git_buf *remote_name, git_repository *repo)
{
diff --git a/src/submodule.h b/src/submodule.h
index 7a9bf9c92..2ef2031b3 100644
--- a/src/submodule.h
+++ b/src/submodule.h
@@ -99,23 +99,6 @@ struct git_submodule {
git_oid wd_oid;
};
-/**
- * The git_submodule_cache stores known submodules along with timestamps,
- * etc. about when they were loaded
- */
-typedef struct {
- git_repository *repo;
- git_strmap *submodules;
- git_mutex lock;
-
- /* cache invalidation data */
- git_oid head_id;
- git_oid index_checksum;
- git_buf gitmodules_path;
- git_futils_filestamp gitmodules_stamp;
- git_futils_filestamp config_stamp;
-} git_submodule_cache;
-
/* Force revalidation of submodule data cache (alloc as needed) */
extern int git_submodule_cache_refresh(git_repository *repo);
@@ -137,9 +120,6 @@ enum {
#define GIT_SUBMODULE_STATUS__CLEAR_INTERNAL(S) \
((S) & ~(0xFFFFFFFFu << 20))
-/* Internal submodule check does not attempt to refresh cached data */
-extern bool git_submodule__is_submodule(git_repository *repo, const char *name);
-
/* Internal lookup does not attempt to refresh cached data */
extern int git_submodule__lookup(
git_submodule **out, git_repository *repo, const char *path);
@@ -163,8 +143,4 @@ extern int git_submodule_parse_ignore(
extern int git_submodule_parse_update(
git_submodule_update_t *out, const char *value);
-extern const char *git_submodule_ignore_to_str(git_submodule_ignore_t);
-extern const char *git_submodule_update_to_str(git_submodule_update_t);
-extern const char *git_submodule_recurse_to_str(git_submodule_recurse_t);
-
#endif
diff --git a/tests/diff/submodules.c b/tests/diff/submodules.c
index e2169583b..08682cd4b 100644
--- a/tests/diff/submodules.c
+++ b/tests/diff/submodules.c
@@ -273,13 +273,13 @@ void test_diff_submodules__invalid_cache(void)
/* create untracked file in submodule working directory */
cl_git_mkfile("submod2/sm_changed_head/new_around_here", "hello");
- git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_NONE);
+ git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_NONE);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_dirty);
git_diff_free(diff);
- git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_UNTRACKED);
+ git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_UNTRACKED);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_unchanged);
@@ -301,7 +301,7 @@ void test_diff_submodules__invalid_cache(void)
check_diff_patches(diff, expected_dirty);
git_diff_free(diff);
- git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_DIRTY);
+ git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_DIRTY);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_unchanged);
@@ -312,13 +312,13 @@ void test_diff_submodules__invalid_cache(void)
cl_git_pass(git_repository_index(&smindex, smrepo));
cl_git_pass(git_index_add_bypath(smindex, "file_to_modify"));
- git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_UNTRACKED);
+ git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_UNTRACKED);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_dirty);
git_diff_free(diff);
- git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_DIRTY);
+ git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_DIRTY);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_unchanged);
@@ -327,19 +327,19 @@ void test_diff_submodules__invalid_cache(void)
/* commit changed index of submodule */
cl_repo_commit_from_index(NULL, smrepo, NULL, 1372350000, "Move it");
- git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_DIRTY);
+ git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_DIRTY);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_moved);
git_diff_free(diff);
- git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_ALL);
+ git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_ALL);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_unchanged);
git_diff_free(diff);
- git_submodule_set_ignore(sm, GIT_SUBMODULE_IGNORE_NONE);
+ git_submodule_set_ignore(g_repo, git_submodule_name(sm), GIT_SUBMODULE_IGNORE_NONE);
cl_git_pass(git_diff_index_to_workdir(&diff, g_repo, NULL, &opts));
check_diff_patches(diff, expected_moved_dirty);
diff --git a/tests/diff/tree.c b/tests/diff/tree.c
index 6dd17203d..977e21f5b 100644
--- a/tests/diff/tree.c
+++ b/tests/diff/tree.c
@@ -89,7 +89,7 @@ void test_diff_tree__0(void)
}
#define DIFF_OPTS(FLAGS, CTXT) \
- {GIT_DIFF_OPTIONS_VERSION, (FLAGS), GIT_SUBMODULE_IGNORE_DEFAULT, \
+ {GIT_DIFF_OPTIONS_VERSION, (FLAGS), GIT_SUBMODULE_IGNORE_FALLBACK, \
{NULL,0}, NULL, NULL, (CTXT), 1}
void test_diff_tree__options(void)
diff --git a/tests/submodule/init.c b/tests/submodule/init.c
index dbde0f284..9e0cf5753 100644
--- a/tests/submodule/init.c
+++ b/tests/submodule/init.c
@@ -23,10 +23,10 @@ void test_submodule_init__absolute_url(void)
cl_assert(git_path_dirname_r(&absolute_url, git_repository_workdir(g_repo)) > 0);
cl_git_pass(git_buf_joinpath(&absolute_url, absolute_url.ptr, "testrepo.git"));
- cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
-
/* write the absolute url to the .gitmodules file*/
- cl_git_pass(git_submodule_set_url(sm, absolute_url.ptr));
+ cl_git_pass(git_submodule_set_url(g_repo, "testrepo", absolute_url.ptr));
+
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
/* verify that the .gitmodules is set with an absolute path*/
cl_assert_equal_s(absolute_url.ptr, git_submodule_url(sm));
diff --git a/tests/submodule/modify.c b/tests/submodule/modify.c
index bbbb2d56e..f7a089e72 100644
--- a/tests/submodule/modify.c
+++ b/tests/submodule/modify.c
@@ -41,17 +41,15 @@ void test_submodule_modify__init(void)
git_config_free(cfg);
/* confirm no submodule data in config */
- cl_git_pass(git_repository_config(&cfg, g_repo));
- cl_git_fail(git_config_get_string(&str, cfg, "submodule.sm_unchanged.url"));
- cl_git_fail(git_config_get_string(&str, cfg, "submodule.sm_changed_head.url"));
- cl_git_fail(git_config_get_string(&str, cfg, "submodule.sm_added_and_uncommited.url"));
+ cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
+ cl_git_fail_with(GIT_ENOTFOUND, git_config_get_string(&str, cfg, "submodule.sm_unchanged.url"));
+ cl_git_fail_with(GIT_ENOTFOUND, git_config_get_string(&str, cfg, "submodule.sm_changed_head.url"));
+ cl_git_fail_with(GIT_ENOTFOUND, git_config_get_string(&str, cfg, "submodule.sm_added_and_uncommited.url"));
git_config_free(cfg);
/* call init and see that settings are copied */
cl_git_pass(git_submodule_foreach(g_repo, init_one_submodule, NULL));
- git_submodule_reload_all(g_repo, 1);
-
/* confirm submodule data in config */
cl_git_pass(git_repository_config_snapshot(&cfg, g_repo));
cl_git_pass(git_config_get_string(&str, cfg, "submodule.sm_unchanged.url"));
@@ -130,132 +128,85 @@ void test_submodule_modify__sync(void)
git_submodule_free(sm3);
}
-void test_submodule_modify__edit_and_save(void)
+void assert_ignore_change(git_submodule_ignore_t ignore)
{
- git_submodule *sm1, *sm2;
- char *old_url, *old_branch;
- git_submodule_ignore_t old_ignore;
- git_submodule_update_t old_update;
- git_repository *r2;
- git_submodule_recurse_t old_fetchrecurse;
-
- cl_git_pass(git_submodule_lookup(&sm1, g_repo, "sm_changed_head"));
-
- old_url = git__strdup(git_submodule_url(sm1));
- old_branch = NULL;
-
- /* modify properties of submodule */
- cl_git_pass(git_submodule_set_url(sm1, SM_LIBGIT2_URL));
- cl_git_pass(git_submodule_set_branch(sm1, SM_LIBGIT2_BRANCH));
- old_ignore = git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_UNTRACKED);
- old_update = git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_REBASE);
- old_fetchrecurse = git_submodule_set_fetch_recurse_submodules(
- sm1, GIT_SUBMODULE_RECURSE_YES);
-
- cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm1));
- cl_assert_equal_s(SM_LIBGIT2_BRANCH, git_submodule_branch(sm1));
- cl_assert_equal_i(
- GIT_SUBMODULE_IGNORE_UNTRACKED, git_submodule_ignore(sm1));
- cl_assert_equal_i(
- GIT_SUBMODULE_UPDATE_REBASE, git_submodule_update_strategy(sm1));
- cl_assert_equal_i(
- GIT_SUBMODULE_RECURSE_YES, git_submodule_fetch_recurse_submodules(sm1));
-
- /* revert without saving (and confirm setters return old value) */
- cl_git_pass(git_submodule_set_url(sm1, old_url));
- cl_git_pass(git_submodule_set_branch(sm1, old_branch));
- cl_assert_equal_i(
- GIT_SUBMODULE_IGNORE_UNTRACKED,
- git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_RESET));
- cl_assert_equal_i(
- GIT_SUBMODULE_UPDATE_REBASE,
- git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_RESET));
- cl_assert_equal_i(
- GIT_SUBMODULE_RECURSE_YES, git_submodule_set_fetch_recurse_submodules(
- sm1, GIT_SUBMODULE_RECURSE_RESET));
-
- /* check that revert was successful */
- cl_assert_equal_s(old_url, git_submodule_url(sm1));
- cl_assert_equal_s(old_branch, git_submodule_branch(sm1));
- cl_assert_equal_i((int)old_ignore, (int)git_submodule_ignore(sm1));
- cl_assert_equal_i((int)old_update, (int)git_submodule_update_strategy(sm1));
- cl_assert_equal_i(
- old_fetchrecurse, git_submodule_fetch_recurse_submodules(sm1));
-
- /* modify properties of submodule (again) */
- cl_git_pass(git_submodule_set_url(sm1, SM_LIBGIT2_URL));
- cl_git_pass(git_submodule_set_branch(sm1, SM_LIBGIT2_BRANCH));
- git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_UNTRACKED);
- git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_REBASE);
- git_submodule_set_fetch_recurse_submodules(sm1, GIT_SUBMODULE_RECURSE_YES);
-
- /* call save */
- cl_git_pass(git_submodule_save(sm1));
-
- /* attempt to "revert" values */
- git_submodule_set_ignore(sm1, GIT_SUBMODULE_IGNORE_RESET);
- git_submodule_set_update(sm1, GIT_SUBMODULE_UPDATE_RESET);
-
- /* but ignore and update should NOT revert because the RESET
- * should now be the newly saved value...
- */
- cl_assert_equal_i(
- (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1));
- cl_assert_equal_i(
- (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update_strategy(sm1));
- cl_assert_equal_i(GIT_SUBMODULE_RECURSE_YES, git_submodule_fetch_recurse_submodules(sm1));
-
- /* call reload and check that the new values are loaded */
- cl_git_pass(git_submodule_reload(sm1, 0));
-
- cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm1));
- cl_assert_equal_s(SM_LIBGIT2_BRANCH, git_submodule_branch(sm1));
- cl_assert_equal_i(
- (int)GIT_SUBMODULE_IGNORE_UNTRACKED, (int)git_submodule_ignore(sm1));
- cl_assert_equal_i(
- (int)GIT_SUBMODULE_UPDATE_REBASE, (int)git_submodule_update_strategy(sm1));
- cl_assert_equal_i(GIT_SUBMODULE_RECURSE_YES, git_submodule_fetch_recurse_submodules(sm1));
-
- /* unset branch again and verify that the property is deleted in config */
- cl_git_pass(git_submodule_set_branch(sm1, NULL));
- cl_git_pass(git_submodule_save(sm1));
- cl_git_pass(git_submodule_reload(sm1, 0));
- cl_assert_equal_s(NULL, git_submodule_branch(sm1));
-
- /* open a second copy of the repo and compare submodule */
- cl_git_pass(git_repository_open(&r2, "submod2"));
- cl_git_pass(git_submodule_lookup(&sm2, r2, "sm_changed_head"));
-
- cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm2));
- cl_assert_equal_i(
- GIT_SUBMODULE_IGNORE_UNTRACKED, git_submodule_ignore(sm2));
- cl_assert_equal_i(
- GIT_SUBMODULE_UPDATE_REBASE, git_submodule_update_strategy(sm2));
- cl_assert_equal_i(
- GIT_SUBMODULE_RECURSE_NO, git_submodule_fetch_recurse_submodules(sm2));
-
- /* set fetchRecurseSubmodules on-demand */
- cl_git_pass(git_submodule_reload(sm1, 0));
- git_submodule_set_fetch_recurse_submodules(sm1, GIT_SUBMODULE_RECURSE_ONDEMAND);
- cl_assert_equal_i(
- GIT_SUBMODULE_RECURSE_ONDEMAND, git_submodule_fetch_recurse_submodules(sm1));
- /* call save */
- cl_git_pass(git_submodule_save(sm1));
- cl_git_pass(git_submodule_reload(sm1, 0));
- cl_assert_equal_i(
- GIT_SUBMODULE_RECURSE_ONDEMAND, git_submodule_fetch_recurse_submodules(sm1));
+ git_submodule *sm;
- git_submodule_free(sm1);
- git_submodule_free(sm2);
- git_repository_free(r2);
- git__free(old_url);
+ cl_git_pass(git_submodule_set_ignore(g_repo, "sm_changed_head", ignore));
+
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+ cl_assert_equal_i(ignore, git_submodule_ignore(sm));
+ git_submodule_free(sm);
+}
+
+void test_submodule_modify__set_ignore(void)
+{
+ assert_ignore_change(GIT_SUBMODULE_IGNORE_UNTRACKED);
+ assert_ignore_change(GIT_SUBMODULE_IGNORE_NONE);
+ assert_ignore_change(GIT_SUBMODULE_IGNORE_ALL);
+}
+
+void assert_update_change(git_submodule_update_t update)
+{
+ git_submodule *sm;
+
+ cl_git_pass(git_submodule_set_update(g_repo, "sm_changed_head", update));
+
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+ cl_assert_equal_i(update, git_submodule_update_strategy(sm));
+ git_submodule_free(sm);
+}
+
+void test_submodule_modify__set_update(void)
+{
+ assert_update_change(GIT_SUBMODULE_UPDATE_REBASE);
+ assert_update_change(GIT_SUBMODULE_UPDATE_NONE);
+ assert_update_change(GIT_SUBMODULE_UPDATE_CHECKOUT);
+}
+
+void assert_recurse_change(git_submodule_recurse_t recurse)
+{
+ git_submodule *sm;
+
+ cl_git_pass(git_submodule_set_fetch_recurse_submodules(g_repo, "sm_changed_head", recurse));
+
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+ cl_assert_equal_i(recurse, git_submodule_fetch_recurse_submodules(sm));
+ git_submodule_free(sm);
+}
+
+void test_submodule_modify__set_fetch_recurse_submodules(void)
+{
+ assert_recurse_change(GIT_SUBMODULE_RECURSE_YES);
+ assert_recurse_change(GIT_SUBMODULE_RECURSE_NO);
+ assert_recurse_change(GIT_SUBMODULE_RECURSE_ONDEMAND);
+}
+
+void test_submodule_modify__set_branch(void)
+{
+ git_submodule *sm;
+
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+ cl_assert(git_submodule_branch(sm) == NULL);
+ git_submodule_free(sm);
+
+ cl_git_pass(git_submodule_set_branch(g_repo, "sm_changed_head", SM_LIBGIT2_BRANCH));
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+ cl_assert_equal_s(SM_LIBGIT2_BRANCH, git_submodule_branch(sm));
+ git_submodule_free(sm);
+
+ cl_git_pass(git_submodule_set_branch(g_repo, "sm_changed_head", NULL));
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+ cl_assert(git_submodule_branch(sm) == NULL);
+ git_submodule_free(sm);
}
-void test_submodule_modify__save_last(void)
+void test_submodule_modify__set_url(void)
{
git_submodule *sm;
- cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_gitmodules_only"));
- cl_git_pass(git_submodule_save(sm));
+ cl_git_pass(git_submodule_set_url(g_repo, "sm_changed_head", SM_LIBGIT2_URL));
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "sm_changed_head"));
+ cl_assert_equal_s(SM_LIBGIT2_URL, git_submodule_url(sm));
git_submodule_free(sm);
}
diff --git a/tests/submodule/nosubs.c b/tests/submodule/nosubs.c
index e343c1620..538825c1c 100644
--- a/tests/submodule/nosubs.c
+++ b/tests/submodule/nosubs.c
@@ -21,19 +21,11 @@ void test_submodule_nosubs__lookup(void)
cl_assert_equal_i(GIT_EEXISTS, git_submodule_lookup(&sm, repo, "subrepo"));
- cl_git_pass(git_submodule_reload_all(repo, 0));
-
cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, repo, "subdir"));
cl_assert_equal_i(GIT_EEXISTS, git_submodule_lookup(&sm, repo, "subrepo"));
}
-void test_submodule_nosubs__immediate_reload(void)
-{
- git_repository *repo = cl_git_sandbox_init("status");
- cl_git_pass(git_submodule_reload_all(repo, 0));
-}
-
static int fake_submod_cb(git_submodule *sm, const char *n, void *p)
{
GIT_UNUSED(sm); GIT_UNUSED(n); GIT_UNUSED(p);
@@ -57,41 +49,7 @@ void test_submodule_nosubs__add(void)
git_submodule_free(sm2);
cl_git_pass(git_submodule_foreach(repo, fake_submod_cb, NULL));
- cl_git_pass(git_submodule_reload_all(repo, 0));
-
- git_submodule_free(sm);
-}
-
-void test_submodule_nosubs__reload_add_reload(void)
-{
- git_repository *repo = cl_git_sandbox_init("status");
- git_submodule *sm;
-
- cl_git_pass(git_submodule_reload_all(repo, 0));
-
- /* try one add with a reload (to make sure no errors happen) */
-
- cl_git_pass(git_submodule_add_setup(&sm, repo,
- "https://github.com/libgit2/libgit2.git", "submodules/libgit2", 1));
-
- cl_git_pass(git_submodule_reload_all(repo, 0));
-
- cl_assert_equal_s("submodules/libgit2", git_submodule_name(sm));
- git_submodule_free(sm);
-
- cl_git_pass(git_submodule_lookup(&sm, repo, "submodules/libgit2"));
- cl_assert_equal_s("submodules/libgit2", git_submodule_name(sm));
- git_submodule_free(sm);
-
- /* try one add without a reload (to make sure cache inval works, too) */
-
- cl_git_pass(git_submodule_add_setup(&sm, repo,
- "https://github.com/libgit2/libgit2.git", "libgit2-again", 1));
- cl_assert_equal_s("libgit2-again", git_submodule_name(sm));
- git_submodule_free(sm);
- cl_git_pass(git_submodule_lookup(&sm, repo, "libgit2-again"));
- cl_assert_equal_s("libgit2-again", git_submodule_name(sm));
git_submodule_free(sm);
}
@@ -100,10 +58,8 @@ void test_submodule_nosubs__bad_gitmodules(void)
git_repository *repo = cl_git_sandbox_init("status");
cl_git_mkfile("status/.gitmodules", "[submodule \"foobar\"]\tpath=blargle\n\turl=\n\tbranch=\n\tupdate=flooble\n\n");
- cl_git_fail(git_submodule_reload_all(repo, 0));
cl_git_rewritefile("status/.gitmodules", "[submodule \"foobar\"]\tpath=blargle\n\turl=\n\tbranch=\n\tupdate=rebase\n\n");
- cl_git_pass(git_submodule_reload_all(repo, 0));
cl_git_pass(git_submodule_lookup(NULL, repo, "foobar"));
cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(NULL, repo, "subdir"));
diff --git a/tests/submodule/status.c b/tests/submodule/status.c
index 6efae35c6..6721ee92a 100644
--- a/tests/submodule/status.c
+++ b/tests/submodule/status.c
@@ -107,56 +107,47 @@ void test_submodule_status__ignore_none(void)
cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_DELETED) != 0);
}
-static int set_sm_ignore(git_submodule *sm, const char *name, void *payload)
-{
- git_submodule_ignore_t ignore = *(git_submodule_ignore_t *)payload;
- GIT_UNUSED(name);
- git_submodule_set_ignore(sm, ignore);
- return 0;
-}
-
void test_submodule_status__ignore_untracked(void)
{
unsigned int status;
git_submodule_ignore_t ign = GIT_SUBMODULE_IGNORE_UNTRACKED;
rm_submodule("sm_unchanged");
- cl_git_pass(git_submodule_foreach(g_repo, set_sm_ignore, &ign));
refute_submodule_exists(g_repo, "just_a_dir", GIT_ENOTFOUND);
refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
refute_submodule_exists(g_repo, "not", GIT_EEXISTS);
- status = get_submodule_status(g_repo, "sm_changed_index");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_index", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED) != 0);
- status = get_submodule_status(g_repo, "sm_changed_head");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0);
- status = get_submodule_status(g_repo, "sm_changed_file");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_file", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_WD_WD_MODIFIED) != 0);
- status = get_submodule_status(g_repo, "sm_changed_untracked_file");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_untracked_file", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
- status = get_submodule_status(g_repo, "sm_missing_commits");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_missing_commits", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0);
- status = get_submodule_status(g_repo, "sm_added_and_uncommited");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_added_and_uncommited", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_ADDED) != 0);
/* removed sm_unchanged for deleted workdir */
- status = get_submodule_status(g_repo, "sm_unchanged");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_WD_DELETED) != 0);
/* now mkdir sm_unchanged to test uninitialized */
cl_git_pass(git_futils_mkdir("sm_unchanged", "submod2", 0755, 0));
- status = get_submodule_status(g_repo, "sm_unchanged");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_WD_UNINITIALIZED) != 0);
/* update sm_changed_head in index */
add_submodule_to_index("sm_changed_head");
- status = get_submodule_status(g_repo, "sm_changed_head");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_MODIFIED) != 0);
}
@@ -166,42 +157,41 @@ void test_submodule_status__ignore_dirty(void)
git_submodule_ignore_t ign = GIT_SUBMODULE_IGNORE_DIRTY;
rm_submodule("sm_unchanged");
- cl_git_pass(git_submodule_foreach(g_repo, set_sm_ignore, &ign));
refute_submodule_exists(g_repo, "just_a_dir", GIT_ENOTFOUND);
refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
refute_submodule_exists(g_repo, "not", GIT_EEXISTS);
- status = get_submodule_status(g_repo, "sm_changed_index");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_index", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
- status = get_submodule_status(g_repo, "sm_changed_head");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0);
- status = get_submodule_status(g_repo, "sm_changed_file");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_file", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
- status = get_submodule_status(g_repo, "sm_changed_untracked_file");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_untracked_file", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
- status = get_submodule_status(g_repo, "sm_missing_commits");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_missing_commits", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_WD_MODIFIED) != 0);
- status = get_submodule_status(g_repo, "sm_added_and_uncommited");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_added_and_uncommited", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_ADDED) != 0);
/* removed sm_unchanged for deleted workdir */
- status = get_submodule_status(g_repo, "sm_unchanged");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_WD_DELETED) != 0);
/* now mkdir sm_unchanged to test uninitialized */
cl_git_pass(git_futils_mkdir("sm_unchanged", "submod2", 0755, 0));
- status = get_submodule_status(g_repo, "sm_unchanged");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_WD_UNINITIALIZED) != 0);
/* update sm_changed_head in index */
add_submodule_to_index("sm_changed_head");
- status = get_submodule_status(g_repo, "sm_changed_head");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
cl_assert((status & GIT_SUBMODULE_STATUS_INDEX_MODIFIED) != 0);
}
@@ -211,42 +201,41 @@ void test_submodule_status__ignore_all(void)
git_submodule_ignore_t ign = GIT_SUBMODULE_IGNORE_ALL;
rm_submodule("sm_unchanged");
- cl_git_pass(git_submodule_foreach(g_repo, set_sm_ignore, &ign));
refute_submodule_exists(g_repo, "just_a_dir", GIT_ENOTFOUND);
refute_submodule_exists(g_repo, "not-submodule", GIT_EEXISTS);
refute_submodule_exists(g_repo, "not", GIT_EEXISTS);
- status = get_submodule_status(g_repo, "sm_changed_index");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_index", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
- status = get_submodule_status(g_repo, "sm_changed_head");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
- status = get_submodule_status(g_repo, "sm_changed_file");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_file", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
- status = get_submodule_status(g_repo, "sm_changed_untracked_file");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_untracked_file", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
- status = get_submodule_status(g_repo, "sm_missing_commits");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_missing_commits", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
- status = get_submodule_status(g_repo, "sm_added_and_uncommited");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_added_and_uncommited", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
/* removed sm_unchanged for deleted workdir */
- status = get_submodule_status(g_repo, "sm_unchanged");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
/* now mkdir sm_unchanged to test uninitialized */
cl_git_pass(git_futils_mkdir("sm_unchanged", "submod2", 0755, 0));
- status = get_submodule_status(g_repo, "sm_unchanged");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_unchanged", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
/* update sm_changed_head in index */
add_submodule_to_index("sm_changed_head");
- status = get_submodule_status(g_repo, "sm_changed_head");
+ cl_git_pass(git_submodule_status(&status, g_repo,"sm_changed_head", ign));
cl_assert(GIT_SUBMODULE_STATUS_IS_UNMODIFIED(status));
}
diff --git a/tests/submodule/submodule_helpers.c b/tests/submodule/submodule_helpers.c
index 19bb04f75..2647e1514 100644
--- a/tests/submodule/submodule_helpers.c
+++ b/tests/submodule/submodule_helpers.c
@@ -156,21 +156,18 @@ void refute__submodule_exists(
git_repository *repo, const char *name, int expected_error,
const char *msg, const char *file, int line)
{
- git_submodule *sm;
clar__assert_equal(
file, line, msg, 1, "%i",
- expected_error, (int)(git_submodule_lookup(&sm, repo, name)));
+ expected_error, (int)(git_submodule_lookup(NULL, repo, name)));
}
unsigned int get_submodule_status(git_repository *repo, const char *name)
{
- git_submodule *sm = NULL;
unsigned int status = 0;
- cl_git_pass(git_submodule_lookup(&sm, repo, name));
- cl_assert(sm);
- cl_git_pass(git_submodule_status(&status, sm));
- git_submodule_free(sm);
+ assert(repo && name);
+
+ cl_git_pass(git_submodule_status(&status, repo, name, GIT_SUBMODULE_IGNORE_FALLBACK));
return status;
}
diff --git a/tests/submodule/update.c b/tests/submodule/update.c
index e7f1b76b8..fed6d38b3 100644
--- a/tests/submodule/update.c
+++ b/tests/submodule/update.c
@@ -103,7 +103,7 @@ void test_submodule_update__update_submodule(void)
cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
/* verify the initial state of the submodule */
- cl_git_pass(git_submodule_status(&submodule_status, sm));
+ cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_FALLBACK));
cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
GIT_SUBMODULE_STATUS_IN_INDEX |
GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -114,7 +114,7 @@ void test_submodule_update__update_submodule(void)
cl_git_pass(git_submodule_update(sm, 0, &update_options));
/* verify state */
- cl_git_pass(git_submodule_status(&submodule_status, sm));
+ cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_FALLBACK));
cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
GIT_SUBMODULE_STATUS_IN_INDEX |
GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -142,7 +142,7 @@ void test_submodule_update__update_and_init_submodule(void)
/* get the submodule */
cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
- cl_git_pass(git_submodule_status(&submodule_status, sm));
+ cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_FALLBACK));
cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
GIT_SUBMODULE_STATUS_IN_INDEX |
GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -177,7 +177,7 @@ void test_submodule_update__update_already_checked_out_submodule(void)
/* Initialize and update the sub repository */
cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
- cl_git_pass(git_submodule_status(&submodule_status, sm));
+ cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_FALLBACK));
cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
GIT_SUBMODULE_STATUS_IN_INDEX |
GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -203,7 +203,11 @@ void test_submodule_update__update_already_checked_out_submodule(void)
* HEAD commit and index should be updated, but not the workdir.
*/
- cl_git_pass(git_submodule_status(&submodule_status, sm));
+ cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_FALLBACK));
+
+ git_submodule_free(sm);
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
GIT_SUBMODULE_STATUS_IN_INDEX |
GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -251,7 +255,7 @@ void test_submodule_update__update_blocks_on_dirty_wd(void)
/* Initialize and update the sub repository */
cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
- cl_git_pass(git_submodule_status(&submodule_status, sm));
+ cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_FALLBACK));
cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
GIT_SUBMODULE_STATUS_IN_INDEX |
GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -277,7 +281,11 @@ void test_submodule_update__update_blocks_on_dirty_wd(void)
* HEAD commit and index should be updated, but not the workdir.
*/
- cl_git_pass(git_submodule_status(&submodule_status, sm));
+ cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_FALLBACK));
+
+ git_submodule_free(sm);
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
GIT_SUBMODULE_STATUS_IN_INDEX |
GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -324,7 +332,7 @@ void test_submodule_update__can_force_update(void)
/* Initialize and update the sub repository */
cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
- cl_git_pass(git_submodule_status(&submodule_status, sm));
+ cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_FALLBACK));
cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
GIT_SUBMODULE_STATUS_IN_INDEX |
GIT_SUBMODULE_STATUS_IN_CONFIG |
@@ -349,7 +357,11 @@ void test_submodule_update__can_force_update(void)
* Verify state after checkout of parent repository. The submodule ID in the
* HEAD commit and index should be updated, but not the workdir.
*/
- cl_git_pass(git_submodule_status(&submodule_status, sm));
+ cl_git_pass(git_submodule_status(&submodule_status, g_repo, "testrepo", GIT_SUBMODULE_IGNORE_FALLBACK));
+
+ git_submodule_free(sm);
+ cl_git_pass(git_submodule_lookup(&sm, g_repo, "testrepo"));
+
cl_assert_equal_i(submodule_status, GIT_SUBMODULE_STATUS_IN_HEAD |
GIT_SUBMODULE_STATUS_IN_INDEX |
GIT_SUBMODULE_STATUS_IN_CONFIG |