entry: support CE_WT_REMOVE flag in checkout_entry
[gitweb.git] / entry.c
diff --git a/entry.c b/entry.c
index 5d136c5d55e0811b70fdb10f59ea506ceb1b273b..3d3701e7ae148b623e353ad2874e9dce28cca32b 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -404,7 +404,7 @@ static void mark_colliding_entries(const struct checkout *state,
 {
        int i, trust_ino = check_stat;
 
-#if defined(GIT_WINDOWS_NATIVE)
+#if defined(GIT_WINDOWS_NATIVE) || defined(__CYGWIN__)
        trust_ino = 0;
 #endif
 
@@ -419,7 +419,7 @@ static void mark_colliding_entries(const struct checkout *state,
                if (dup->ce_flags & (CE_MATCHED | CE_VALID | CE_SKIP_WORKTREE))
                        continue;
 
-               if ((trust_ino && dup->ce_stat_data.sd_ino == st->st_ino) ||
+               if ((trust_ino && !match_stat_data(&dup->ce_stat_data, st)) ||
                    (!trust_ino && !fspathcmp(ce->name, dup->name))) {
                        dup->ce_flags |= CE_MATCHED;
                        break;
@@ -441,6 +441,17 @@ int checkout_entry(struct cache_entry *ce,
        static struct strbuf path = STRBUF_INIT;
        struct stat st;
 
+       if (ce->ce_flags & CE_WT_REMOVE) {
+               if (topath)
+                       /*
+                        * No content and thus no path to create, so we have
+                        * no pathname to return.
+                        */
+                       BUG("Can't remove entry to a path");
+               unlink_entry(ce);
+               return 0;
+       }
+
        if (topath)
                return write_entry(ce, topath, state, 1);
 
@@ -508,3 +519,18 @@ int checkout_entry(struct cache_entry *ce,
        create_directories(path.buf, path.len, state);
        return write_entry(ce, path.buf, state, 0);
 }
+
+void unlink_entry(const struct cache_entry *ce)
+{
+       const struct submodule *sub = submodule_from_ce(ce);
+       if (sub) {
+               /* state.force is set at the caller. */
+               submodule_move_head(ce->name, "HEAD", NULL,
+                                   SUBMODULE_MOVE_HEAD_FORCE);
+       }
+       if (!check_leading_path(ce->name, ce_namelen(ce)))
+               return;
+       if (remove_or_warn(ce->ce_mode, ce->name))
+               return;
+       schedule_dir_for_removal(ce->name, ce_namelen(ce));
+}