]> git.ipfire.org Git - thirdparty/git.git/blobdiff - unpack-trees.c
Sync with 2.16.6
[thirdparty/git.git] / unpack-trees.c
index 26028b7e45edd49f17e52d64a099d45c93ff4c82..88a0b5d250ef1da36747fe0b736df4305979977d 100644 (file)
@@ -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
@@ -193,10 +195,10 @@ static int do_add_entry(struct unpack_trees_options *o, struct cache_entry *ce,
 static struct cache_entry *dup_entry(const struct cache_entry *ce)
 {
        unsigned int size = ce_size(ce);
-       struct cache_entry *new = xmalloc(size);
+       struct cache_entry *new_entry = xmalloc(size);
 
-       memcpy(new, ce, size);
-       return new;
+       memcpy(new_entry, ce, size);
+       return new_entry;
 }
 
 static void add_entry(struct unpack_trees_options *o,
@@ -369,6 +371,28 @@ 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;
+               oid_array_clear(&to_fetch);
+       }
        for (i = 0; i < index->cache_nr; i++) {
                struct cache_entry *ce = index->cache[i];
 
@@ -408,6 +432,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 +1529,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 +1566,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);
        }
 
@@ -2138,6 +2163,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;
        }