From: Victoria Dye <vdye@github.com>
To: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com>, git@vger.kernel.org
Cc: derrickstolee@github.com
Subject: Re: [PATCH v2 6/9] mv: from in-cone to out-of-cone
Date: Mon, 8 Aug 2022 17:53:25 -0700 [thread overview]
Message-ID: <9718ab8a-5a1a-d93c-ae8f-aa06f6822577@github.com> (raw)
In-Reply-To: <20220805030528.1535376-7-shaoxuan.yuan02@gmail.com>
Shaoxuan Yuan wrote:
> Originally, moving an in-cone <source> to an out-of-cone <destination>
> was not possible, mainly because such <destination> is a directory that
> is not present in the working tree.
>
> Change the behavior so that we can move an in-cone <source> to
> out-of-cone <destination> when --sparse is supplied.
>
> Such <source> can be either clean or dirty, and moving it results in
> different behaviors:
>
> A clean move should move the <source> to the <destination>, both in the
> working tree and the index, then remove the resulted path from the
> working tree, and turn on its CE_SKIP_WORKTREE bit.
It looks like this description is the same as what you wrote in patch 1 [1].
That's fine with me but, as noted in [2], I wanted to double-check whether
the "move <src> to <dst> in worktree, then remove <dst> from worktree" is an
accurate description of what's happening.
[1] https://lore.kernel.org/git/20220805030528.1535376-2-shaoxuan.yuan02@gmail.com/
[2] https://lore.kernel.org/git/bd80881d-b2a3-c220-8f2d-a07a46e14207@github.com/
>
> A dirty move should move the <source> to the <destination>, both in the
> working tree and the index, but should *not* remove the resulted path
> from the working tree and should *not* turn on its CE_SKIP_WORKTREE bit.>
> Helped-by: Derrick Stolee <derrickstolee@github.com>
> Helped-by: Victoria Dye <vdye@github.com>
> Signed-off-by: Shaoxuan Yuan <shaoxuan.yuan02@gmail.com>
> ---
> builtin/mv.c | 55 +++++++++++++++++++++++++++++------
> t/t7002-mv-sparse-checkout.sh | 8 ++---
> 2 files changed, 50 insertions(+), 13 deletions(-)
>
> diff --git a/builtin/mv.c b/builtin/mv.c
> index 1dc55153ed..e4a14aea2d 100644
> --- a/builtin/mv.c
> +++ b/builtin/mv.c
> @@ -171,12 +171,13 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
> };
> const char **source, **destination, **dest_path, **submodule_gitfile;
> const char *dst_w_slash;
> - enum update_mode *modes;
> + enum update_mode *modes, dst_mode = 0;
> struct stat st;
> struct string_list src_for_dst = STRING_LIST_INIT_NODUP;
> struct lock_file lock_file = LOCK_INIT;
> struct cache_entry *ce;
> struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP;
> + struct string_list dirty_paths = STRING_LIST_INIT_NODUP;
>
> git_config(git_default_config, NULL);
>
> @@ -214,6 +215,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
> if (!path_in_sparse_checkout(dst_w_slash, &the_index) &&
> empty_dir_has_sparse_contents(dst_w_slash)) {
> destination = internal_prefix_pathspec(dst_w_slash, argv, argc, DUP_BASENAME);
> + dst_mode = SKIP_WORKTREE_DIR;
> } else if (argc != 1) {
> die(_("destination '%s' is not a directory"), dest_path[0]);
> } else {
> @@ -408,6 +410,7 @@ 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;
> + int sparse_and_dirty = 0;
> struct checkout state = CHECKOUT_INIT;
> state.istate = &the_index;
>
> @@ -418,6 +421,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
> if (show_only)
> continue;
> if (!(mode & (INDEX | SPARSE | SKIP_WORKTREE_DIR)) &&
> + !(dst_mode & SKIP_WORKTREE_DIR) &&
> rename(src, dst) < 0) {
> if (ignore_errors)
> continue;
> @@ -437,17 +441,49 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
>
> pos = cache_name_pos(src, strlen(src));
> assert(pos >= 0);
> + if (!(mode & SPARSE) && !lstat(src, &st))
> + sparse_and_dirty = ce_modified(active_cache[pos], &st, 0);
> rename_cache_entry_at(pos, dst);
>
> - if ((mode & SPARSE) &&
> - (path_in_sparse_checkout(dst, &the_index))) {
> - int dst_pos;
> + if (ignore_sparse &&
> + core_apply_sparse_checkout &&
> + core_sparse_checkout_cone) {
> + if ((mode & SPARSE) &&
> + path_in_sparse_checkout(dst, &the_index)) {
> + /* from out-of-cone to in-cone */
> + int dst_pos = cache_name_pos(dst, strlen(dst));
> + struct cache_entry *dst_ce = active_cache[dst_pos];
> +
> + dst_ce->ce_flags &= ~CE_SKIP_WORKTREE;
> +
> + if (checkout_entry(dst_ce, &state, NULL, NULL))
> + die(_("cannot checkout %s"), dst_ce->name);
> + } else if ((dst_mode & SKIP_WORKTREE_DIR) &&
> + !(mode & SPARSE) &&
> + !path_in_sparse_checkout(dst, &the_index)) {
> + /* from in-cone to out-of-cone */
> + int dst_pos = cache_name_pos(dst, strlen(dst));
> + struct cache_entry *dst_ce = active_cache[dst_pos];
It looks like the above conditions assume "out-of-cone <src>" and
"out-of-cone <dst>" are mutually exclusive. Have you checked what happens
when you try a move like that?
If the behavior is sensible, it would be nice to add a test (in 't7002'?)
establishing that. Otherwise, changing that behavior is reasonably outside
the scope of this series, so it's fine with me if you add a either
"test_expect_failure" test, an "unsupported" warning message earlier in
'mv', or even just a "NEEDSWORK" comment somewhere around this code.
>
> - 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 src is clean, it will suffice to remove it
> + */
> + if (!sparse_and_dirty) {
> + dst_ce->ce_flags |= CE_SKIP_WORKTREE;
> + unlink_or_warn(src);
> + } else {
> + /*
> + * if src is dirty, move it to the
> + * destination and create leading
> + * dirs if necessary
> + */
> + char *dst_dup = xstrdup(dst);
> + string_list_append(&dirty_paths, dst);
> + safe_create_leading_directories(dst_dup);
> + FREE_AND_NULL(dst_dup);
> + rename(src, dst);
> + }
> + }
The rest of this is clearly organized and (as far as I can tell) matches the
behavior you established with the tests in patch 1. Nice work!
> }
> }
>
> @@ -459,6 +495,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
> die(_("Unable to write new index file"));
>
> string_list_clear(&src_for_dst, 0);
> + string_list_clear(&dirty_paths, 0);
> UNLEAK(source);
> UNLEAK(dest_path);
> free(submodule_gitfile);
> diff --git a/t/t7002-mv-sparse-checkout.sh b/t/t7002-mv-sparse-checkout.sh
> index 9b3a9ab4c3..fc9577b2a6 100755
> --- a/t/t7002-mv-sparse-checkout.sh
> +++ b/t/t7002-mv-sparse-checkout.sh
> @@ -290,7 +290,7 @@ test_expect_success 'move sparse file to existing destination with --force and -
> test_cmp expect sub/file1
> '
>
> -test_expect_failure 'move clean path from in-cone to out-of-cone' '
> +test_expect_success 'move clean path from in-cone to out-of-cone' '
> test_when_finished "cleanup_sparse_checkout" &&
> setup_sparse_checkout &&
>
> @@ -343,7 +343,7 @@ test_expect_failure 'move clean path from in-cone to out-of-cone overwrite' '
> test_cmp expect actual
> '
>
> -test_expect_failure 'move dirty path from in-cone to out-of-cone' '
> +test_expect_success 'move dirty path from in-cone to out-of-cone' '
> test_when_finished "cleanup_sparse_checkout" &&
> setup_sparse_checkout &&
> echo "modified" >>sub/d &&
> @@ -363,7 +363,7 @@ test_expect_failure 'move dirty path from in-cone to out-of-cone' '
> grep "H folder1/d" actual
> '
>
> -test_expect_failure 'move dir from in-cone to out-of-cone' '
> +test_expect_success 'move dir from in-cone to out-of-cone' '
> test_when_finished "cleanup_sparse_checkout" &&
> setup_sparse_checkout &&
>
> @@ -382,7 +382,7 @@ test_expect_failure 'move dir from in-cone to out-of-cone' '
> grep "S folder1/dir/e" actual
> '
>
> -test_expect_failure 'move partially-dirty dir from in-cone to out-of-cone' '
> +test_expect_success 'move partially-dirty dir from in-cone to out-of-cone' '
> test_when_finished "cleanup_sparse_checkout" &&
> setup_sparse_checkout &&
> touch sub/dir/e2 sub/dir/e3 &&
next prev parent reply other threads:[~2022-08-09 0:53 UTC|newest]
Thread overview: 61+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-19 13:28 [PATCH v1 0/7] mv: from in-cone to out-of-cone Shaoxuan Yuan
2022-07-19 13:28 ` [PATCH v1 1/7] t7002: add tests for moving " Shaoxuan Yuan
2022-07-19 14:52 ` Ævar Arnfjörð Bjarmason
2022-07-19 17:36 ` Derrick Stolee
2022-07-19 18:30 ` Junio C Hamano
2022-07-19 13:28 ` [PATCH v1 2/7] mv: add documentation for check_dir_in_index() Shaoxuan Yuan
2022-07-19 17:43 ` Derrick Stolee
2022-07-21 13:58 ` Shaoxuan Yuan
2022-07-19 18:01 ` Victoria Dye
2022-07-19 18:10 ` Victoria Dye
2022-07-21 14:20 ` Shaoxuan Yuan
2022-07-19 13:28 ` [PATCH v1 3/7] mv: free the *with_slash in check_dir_in_index() Shaoxuan Yuan
2022-07-19 17:46 ` Derrick Stolee
2022-07-19 13:28 ` [PATCH v1 4/7] mv: check if <destination> is a SKIP_WORKTREE_DIR Shaoxuan Yuan
2022-07-19 17:59 ` Derrick Stolee
2022-07-21 14:13 ` Shaoxuan Yuan
2022-07-22 12:48 ` Derrick Stolee
2022-07-22 18:40 ` Junio C Hamano
2022-07-19 13:28 ` [PATCH v1 5/7] mv: remove BOTH from enum update_mode Shaoxuan Yuan
2022-07-19 18:00 ` Derrick Stolee
2022-07-19 13:28 ` [PATCH v1 6/7] mv: from in-cone to out-of-cone Shaoxuan Yuan
2022-07-19 18:14 ` Derrick Stolee
2022-08-03 11:50 ` Shaoxuan Yuan
2022-08-03 14:30 ` Derrick Stolee
2022-08-04 8:40 ` Shaoxuan Yuan
2022-07-19 13:28 ` [PATCH v1 7/7] mv: check overwrite for in-to-out move Shaoxuan Yuan
2022-07-19 18:15 ` Derrick Stolee
2022-07-19 18:16 ` [PATCH v1 0/7] mv: from in-cone to out-of-cone Derrick Stolee
2022-08-05 3:05 ` [PATCH v2 0/9] " Shaoxuan Yuan
2022-08-05 3:05 ` [PATCH v2 1/9] t7002: add tests for moving " Shaoxuan Yuan
2022-08-09 0:51 ` Victoria Dye
2022-08-09 2:55 ` Shaoxuan Yuan
2022-08-09 11:24 ` Shaoxuan Yuan
2022-08-09 7:53 ` Shaoxuan Yuan
2022-08-05 3:05 ` [PATCH v2 2/9] mv: rename check_dir_in_index() to empty_dir_has_sparse_contents() Shaoxuan Yuan
2022-08-05 3:05 ` [PATCH v2 3/9] mv: free the *with_slash in check_dir_in_index() Shaoxuan Yuan
2022-08-08 23:41 ` Victoria Dye
2022-08-09 2:33 ` Shaoxuan Yuan
2022-08-05 3:05 ` [PATCH v2 4/9] mv: check if <destination> is a SKIP_WORKTREE_DIR Shaoxuan Yuan
2022-08-08 23:41 ` Victoria Dye
2022-08-09 0:23 ` Victoria Dye
2022-08-09 2:31 ` Shaoxuan Yuan
2022-08-05 3:05 ` [PATCH v2 5/9] mv: remove BOTH from enum update_mode Shaoxuan Yuan
2022-08-05 3:05 ` [PATCH v2 6/9] mv: from in-cone to out-of-cone Shaoxuan Yuan
2022-08-09 0:53 ` Victoria Dye [this message]
2022-08-09 3:16 ` Shaoxuan Yuan
2022-08-05 3:05 ` [PATCH v2 7/9] mv: cleanup empty WORKING_DIRECTORY Shaoxuan Yuan
2022-08-05 3:05 ` [PATCH v2 8/9] advice.h: add advise_on_moving_dirty_path() Shaoxuan Yuan
2022-08-05 3:05 ` [PATCH v2 9/9] mv: check overwrite for in-to-out move Shaoxuan Yuan
2022-08-08 23:53 ` Victoria Dye
2022-08-09 12:09 ` [PATCH v3 0/9] mv: from in-cone to out-of-cone Shaoxuan Yuan
2022-08-09 12:09 ` [PATCH v3 1/9] t7002: add tests for moving " Shaoxuan Yuan
2022-08-09 12:09 ` [PATCH v3 2/9] mv: rename check_dir_in_index() to empty_dir_has_sparse_contents() Shaoxuan Yuan
2022-08-09 12:09 ` [PATCH v3 3/9] mv: free the with_slash in check_dir_in_index() Shaoxuan Yuan
2022-08-09 12:09 ` [PATCH v3 4/9] mv: check if <destination> is a SKIP_WORKTREE_DIR Shaoxuan Yuan
2022-08-09 12:09 ` [PATCH v3 5/9] mv: remove BOTH from enum update_mode Shaoxuan Yuan
2022-08-09 12:09 ` [PATCH v3 6/9] mv: from in-cone to out-of-cone Shaoxuan Yuan
2022-08-09 12:09 ` [PATCH v3 7/9] mv: cleanup empty WORKING_DIRECTORY Shaoxuan Yuan
2022-08-09 12:09 ` [PATCH v3 8/9] advice.h: add advise_on_moving_dirty_path() Shaoxuan Yuan
2022-08-09 12:09 ` [PATCH v3 9/9] mv: check overwrite for in-to-out move Shaoxuan Yuan
2022-08-16 15:48 ` [PATCH v3 0/9] mv: from in-cone to out-of-cone Victoria Dye
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=9718ab8a-5a1a-d93c-ae8f-aa06f6822577@github.com \
--to=vdye@github.com \
--cc=derrickstolee@github.com \
--cc=git@vger.kernel.org \
--cc=shaoxuan.yuan02@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.