[WIP v2 5/5] mv: use update_sparsity() after touching sparse contents

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Originally, "git mv" a sparse file/directory from out/in-cone to
in/out-cone does not update the sparsity following the sparse-checkout
patterns.

Use update_sparsity() after touching sparse contents, so the sparsity
will be updated after the move.

Signed-off-by: Shaoxuan Yuan <shaoxuan.yuan02@xxxxxxxxx>
---
 builtin/mv.c                  | 19 +++++++++++++++++++
 t/t7002-mv-sparse-checkout.sh | 16 ++++++++++++++++
 2 files changed, 35 insertions(+)

diff --git a/builtin/mv.c b/builtin/mv.c
index e64f251a69..2c02120941 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -13,6 +13,7 @@
 #include "string-list.h"
 #include "parse-options.h"
 #include "submodule.h"
+#include "unpack-trees.h"
 
 static const char * const builtin_mv_usage[] = {
 	N_("git mv [<options>] <source>... <destination>"),
@@ -158,6 +159,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 {
 	int i, flags, gitmodules_modified = 0;
 	int verbose = 0, show_only = 0, force = 0, ignore_errors = 0, ignore_sparse = 0;
+	int sparse_moved = 0;
 	struct option builtin_mv_options[] = {
 		OPT__VERBOSE(&verbose, N_("be verbose")),
 		OPT__DRY_RUN(&show_only, N_("dry run")),
@@ -376,6 +378,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 		const char *src = source[i], *dst = destination[i];
 		enum update_mode mode = modes[i];
 		int pos;
+		if (!sparse_moved && mode & (SPARSE | SKIP_WORKTREE_DIR))
+			sparse_moved = 1;
 		if (show_only || verbose)
 			printf(_("Renaming %s to %s\n"), src, dst);
 		if (show_only)
@@ -403,6 +407,21 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 		rename_cache_entry_at(pos, dst);
 	}
 
+	if (sparse_moved) {
+		struct unpack_trees_options o;
+		memset(&o, 0, sizeof(o));
+		o.verbose_update = isatty(2);
+		o.update = 1;
+		o.head_idx = -1;
+		o.src_index = &the_index;
+		o.dst_index = &the_index;
+		o.skip_sparse_checkout = 0;
+		o.pl = the_index.sparse_checkout_patterns;
+		setup_unpack_trees_porcelain(&o, "mv");
+		update_sparsity(&o);
+		clear_unpack_trees_porcelain(&o);
+	}
+
 	if (gitmodules_modified)
 		stage_updated_gitmodules(&the_index);
 
diff --git a/t/t7002-mv-sparse-checkout.sh b/t/t7002-mv-sparse-checkout.sh
index cf2f5dc46f..1fd3e3c0fc 100755
--- a/t/t7002-mv-sparse-checkout.sh
+++ b/t/t7002-mv-sparse-checkout.sh
@@ -287,6 +287,22 @@ test_expect_success 'refuse to move sparse file to existing destination' '
 	test_cmp expect stderr
 '
 
+# Need fix.
+#
+# The *expected* behavior:
+#
+# Using --sparse to accept a sparse file, --force to overwrite the destination.
+# The folder1/file1 should replace the sub/file1 without error.
+#
+# The *actual* behavior:
+#
+# It emits a warning:
+#
+# warning: Path ' sub/file1
+# ' already present; will not overwrite with sparse update.
+# After fixing the above paths, you may want to run `git sparse-checkout
+# reapply`.
+
 test_expect_failure 'move sparse file to existing destination with --force and --sparse' '
 	git sparse-checkout disable &&
 	git reset --hard &&
-- 
2.35.1




[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux