]> git.ipfire.org Git - thirdparty/git.git/blobdiff - entry.c
unpack-trees: add basic support for parallel checkout
[thirdparty/git.git] / entry.c
diff --git a/entry.c b/entry.c
index 6339d5484348d5ff9756237e8ed7be73f8c0799b..d7ed38aa407990b3a14f1a3598cecc4b5e8ddd8b 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -7,6 +7,7 @@
 #include "progress.h"
 #include "fsmonitor.h"
 #include "entry.h"
+#include "parallel-checkout.h"
 
 static void create_directories(const char *path, int path_len,
                               const struct checkout *state)
@@ -426,8 +427,17 @@ static void mark_colliding_entries(const struct checkout *state,
        for (i = 0; i < state->istate->cache_nr; i++) {
                struct cache_entry *dup = state->istate->cache[i];
 
-               if (dup == ce)
-                       break;
+               if (dup == ce) {
+                       /*
+                        * Parallel checkout doesn't create the files in index
+                        * order. So the other side of the collision may appear
+                        * after the given cache_entry in the array.
+                        */
+                       if (parallel_checkout_status() == PC_RUNNING)
+                               continue;
+                       else
+                               break;
+               }
 
                if (dup->ce_flags & (CE_MATCHED | CE_VALID | CE_SKIP_WORKTREE))
                        continue;
@@ -440,12 +450,13 @@ static void mark_colliding_entries(const struct checkout *state,
        }
 }
 
-int checkout_entry(struct cache_entry *ce, const struct checkout *state,
-                  char *topath, int *nr_checkouts)
+int checkout_entry_ca(struct cache_entry *ce, struct conv_attrs *ca,
+                     const struct checkout *state, char *topath,
+                     int *nr_checkouts)
 {
        static struct strbuf path = STRBUF_INIT;
        struct stat st;
-       struct conv_attrs ca_buf, *ca = NULL;
+       struct conv_attrs ca_buf;
 
        if (ce->ce_flags & CE_WT_REMOVE) {
                if (topath)
@@ -459,7 +470,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state,
        }
 
        if (topath) {
-               if (S_ISREG(ce->ce_mode)) {
+               if (S_ISREG(ce->ce_mode) && !ca) {
                        convert_attrs(state->istate, &ca_buf, ce->name);
                        ca = &ca_buf;
                }
@@ -530,11 +541,14 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state,
        if (nr_checkouts)
                (*nr_checkouts)++;
 
-       if (S_ISREG(ce->ce_mode)) {
+       if (S_ISREG(ce->ce_mode) && !ca) {
                convert_attrs(state->istate, &ca_buf, ce->name);
                ca = &ca_buf;
        }
 
+       if (!enqueue_checkout(ce, ca))
+               return 0;
+
        return write_entry(ce, path.buf, ca, state, 0);
 }
 
@@ -546,7 +560,7 @@ void unlink_entry(const struct cache_entry *ce)
                submodule_move_head(ce->name, "HEAD", NULL,
                                    SUBMODULE_MOVE_HEAD_FORCE);
        }
-       if (!check_leading_path(ce->name, ce_namelen(ce)))
+       if (check_leading_path(ce->name, ce_namelen(ce), 1) >= 0)
                return;
        if (remove_or_warn(ce->ce_mode, ce->name))
                return;