]> git.ipfire.org Git - thirdparty/git.git/commitdiff
mv: update sparsity after moving from out-of-cone to in-cone
authorShaoxuan Yuan <shaoxuan.yuan02@gmail.com>
Thu, 30 Jun 2022 02:37:32 +0000 (10:37 +0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 1 Jul 2022 21:50:16 +0000 (14:50 -0700)
Originally, "git mv" a sparse file from out-of-cone to
in-cone does not update the moved file's sparsity (remove its
SKIP_WORKTREE bit). And the corresponding cache entry is, unexpectedly,
not checked out in the working tree.

Update the behavior so that:
1. Moving from out-of-cone to in-cone removes the SKIP_WORKTREE bit from
   corresponding cache entry.
2. The moved cache entry is checked out in the working tree to reflect
   the updated sparsity.

Helped-by: Victoria Dye <vdye@github.com>
Signed-off-by: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com>
Acked-by: Derrick Stolee <derrickstolee@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/mv.c

index 83a465ba831adf94561a13f3d358926f516fe9ac..5f4eeadd5d0894eeaeada1ae98a8dcc82aab2d6b 100644 (file)
@@ -13,6 +13,7 @@
 #include "string-list.h"
 #include "parse-options.h"
 #include "submodule.h"
+#include "entry.h"
 
 static const char * const builtin_mv_usage[] = {
        N_("git mv [<options>] <source>... <destination>"),
@@ -304,6 +305,11 @@ remove_entry:
                const char *src = source[i], *dst = destination[i];
                enum update_mode mode = modes[i];
                int pos;
+               struct checkout state = CHECKOUT_INIT;
+               state.istate = &the_index;
+
+               if (force)
+                       state.force = 1;
                if (show_only || verbose)
                        printf(_("Renaming %s to %s\n"), src, dst);
                if (show_only)
@@ -328,6 +334,17 @@ remove_entry:
                pos = cache_name_pos(src, strlen(src));
                assert(pos >= 0);
                rename_cache_entry_at(pos, dst);
+
+               if ((mode & SPARSE) &&
+                   (path_in_sparse_checkout(dst, &the_index))) {
+                       int dst_pos;
+
+                       dst_pos = cache_name_pos(dst, strlen(dst));
+                       active_cache[dst_pos]->ce_flags &= ~CE_SKIP_WORKTREE;
+
+                       if (checkout_entry(active_cache[dst_pos], &state, NULL, NULL))
+                               die(_("cannot checkout %s"), active_cache[dst_pos]->name);
+               }
        }
 
        if (gitmodules_modified)