summaryrefslogtreecommitdiff
path: root/unpack-trees.c
diff options
context:
space:
mode:
Diffstat (limited to 'unpack-trees.c')
-rw-r--r--unpack-trees.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/unpack-trees.c b/unpack-trees.c
index 71b70ccb12..c9f6e314d5 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -14,6 +14,8 @@
#include "dir.h"
#include "submodule.h"
#include "submodule-config.h"
+#include "fsmonitor.h"
+#include "fetch-object.h"
/*
* Error messages expected by scripts out of plumbing commands such as
@@ -369,6 +371,27 @@ static int check_updates(struct unpack_trees_options *o)
load_gitmodules_file(index, &state);
enable_delayed_checkout(&state);
+ if (repository_format_partial_clone && o->update && !o->dry_run) {
+ /*
+ * Prefetch the objects that are to be checked out in the loop
+ * below.
+ */
+ struct oid_array to_fetch = OID_ARRAY_INIT;
+ int fetch_if_missing_store = fetch_if_missing;
+ fetch_if_missing = 0;
+ for (i = 0; i < index->cache_nr; i++) {
+ struct cache_entry *ce = index->cache[i];
+ if ((ce->ce_flags & CE_UPDATE) &&
+ !S_ISGITLINK(ce->ce_mode)) {
+ if (!has_object_file(&ce->oid))
+ oid_array_append(&to_fetch, &ce->oid);
+ }
+ }
+ if (to_fetch.nr)
+ fetch_objects(repository_format_partial_clone,
+ &to_fetch);
+ fetch_if_missing = fetch_if_missing_store;
+ }
for (i = 0; i < index->cache_nr; i++) {
struct cache_entry *ce = index->cache[i];
@@ -408,6 +431,7 @@ static int apply_sparse_checkout(struct index_state *istate,
ce->ce_flags &= ~CE_SKIP_WORKTREE;
if (was_skip_worktree != ce_skip_worktree(ce)) {
ce->ce_flags |= CE_UPDATE_IN_BASE;
+ mark_fsmonitor_invalid(istate, ce);
istate->cache_changed |= CE_ENTRY_CHANGED;
}
@@ -1504,7 +1528,7 @@ static void invalidate_ce_path(const struct cache_entry *ce,
if (!ce)
return;
cache_tree_invalidate_path(o->src_index, ce->name);
- untracked_cache_invalidate_path(o->src_index, ce->name);
+ untracked_cache_invalidate_path(o->src_index, ce->name, 1);
}
/*
@@ -1541,15 +1565,15 @@ static int verify_clean_subdirectory(const struct cache_entry *ce,
int cnt = 0;
if (S_ISGITLINK(ce->ce_mode)) {
- unsigned char sha1[20];
- int sub_head = resolve_gitlink_ref(ce->name, "HEAD", sha1);
+ struct object_id oid;
+ int sub_head = resolve_gitlink_ref(ce->name, "HEAD", &oid);
/*
* If we are not going to update the submodule, then
* we don't care.
*/
- if (!sub_head && !hashcmp(sha1, ce->oid.hash))
+ if (!sub_head && !oidcmp(&oid, &ce->oid))
return 0;
- return verify_clean_submodule(sub_head ? NULL : sha1_to_hex(sha1),
+ return verify_clean_submodule(sub_head ? NULL : oid_to_hex(&oid),
ce, error_type, o);
}
@@ -2137,6 +2161,9 @@ int oneway_merge(const struct cache_entry * const *src,
ie_match_stat(o->src_index, old, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE))
update |= CE_UPDATE;
}
+ if (o->update && S_ISGITLINK(old->ce_mode) &&
+ should_update_submodules() && !verify_uptodate(old, o))
+ update |= CE_UPDATE;
add_entry(o, old, update, 0);
return 0;
}