unpack-trees: improve loading of .gitmodules
When recursing submodules 'check_updates()' needs to have strict control over the submodule-config subsystem to ensure that the gitmodules file has been read before checking cache entries which are marked for removal as well ensuring the proper gitmodules file is read before updating cache entries. Because of this let's not rely on callers of 'check_updates()' to read the gitmodules file before calling 'check_updates()' and handle the reading explicitly. Signed-off-by: Brandon Williams <bmwill@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Brandon Williams committed
Aug 3, 2017 at 11:19 UTC
33028713206c3f59709617d8af5ba4212920a5f0
1 file changed
+27
-16
unpack-trees.c
+27
-16
@@ -1,5 +1,6 @@
1
#define NO_THE_INDEX_COMPATIBILITY_MACROS
2
#include "cache.h"
3
+#include "repository.h"
4
#include "config.h"
5
#include "dir.h"
6
#include "tree.h"
@@ -268,22 +269,28 @@ static int check_submodule_move_head(const struct cache_entry *ce,
269
return 0;
270
}
271
271
-static void reload_gitmodules_file(struct index_state *index,
272
- struct checkout *state)
272
+/*
273
+ * Preform the loading of the repository's gitmodules file. This function is
274
+ * used by 'check_update()' to perform loading of the gitmodules file in two
275
+ * differnt situations:
276
+ * (1) before removing entries from the working tree if the gitmodules file has
277
+ * been marked for removal. This situation is specified by 'state' == NULL.
278
+ * (2) before checking out entries to the working tree if the gitmodules file
279
+ * has been marked for update. This situation is specified by 'state' != NULL.
280
+ */
281
+static void load_gitmodules_file(struct index_state *index,
282
+ struct checkout *state)
283
{
274
- int i;
275
- for (i = 0; i < index->cache_nr; i++) {
276
- struct cache_entry *ce = index->cache[i];
277
- if (ce->ce_flags & CE_UPDATE) {
278
- int r = strcmp(ce->name, GITMODULES_FILE);
279
- if (r < 0)
280
- continue;
281
- else if (r == 0) {
282
- submodule_free();
283
- checkout_entry(ce, state, NULL);
284
- gitmodules_config();
285
- } else
286
- break;
284
+ int pos = index_name_pos(index, GITMODULES_FILE, strlen(GITMODULES_FILE));
285
+
286
+ if (pos >= 0) {
287
+ struct cache_entry *ce = index->cache[pos];
288
+ if (!state && ce->ce_flags & CE_WT_REMOVE) {
289
+ repo_read_gitmodules(the_repository);
290
+ } else if (state && (ce->ce_flags & CE_UPDATE)) {
291
+ submodule_free();
292
+ checkout_entry(ce, state, NULL);
293
+ repo_read_gitmodules(the_repository);
294
}
295
}
296
}
@@ -343,6 +350,10 @@ static int check_updates(struct unpack_trees_options *o)
350
351
if (o->update)
352
git_attr_set_direction(GIT_ATTR_CHECKOUT, index);
353
+
354
+ if (should_update_submodules() && o->update && !o->dry_run)
355
+ load_gitmodules_file(index, NULL);
356
+
357
for (i = 0; i < index->cache_nr; i++) {
358
const struct cache_entry *ce = index->cache[i];
359
@@ -356,7 +367,7 @@ static int check_updates(struct unpack_trees_options *o)
367
remove_scheduled_dirs();
368
369
if (should_update_submodules() && o->update && !o->dry_run)
359
- reload_gitmodules_file(index, &state);
370
+ load_gitmodules_file(index, &state);
371
372
for (i = 0; i < index->cache_nr; i++) {
373
struct cache_entry *ce = index->cache[i];