git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v1 6/7] mv: from in-cone to out-of-cone

From
Derrick Stolee <derrickstolee@github.com>
Date
Jul 19, 2022, 18:14 UTC
Message-ID
<d30a358e-c9f0-55fa-8c8b-37f0cb0d7eb3@github.com>
In-Reply-To
<20220719132809.409247-7-shaoxuan.yuan02@gmail.com>
On 7/19/2022 9:28 AM, Shaoxuan Yuan wrote:
Show 19 quoted lines
> 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.
> 
> 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.
> Instead advise user to "git add" this path and run "git sparse-checkout
> reapply" to re-sparsify that path.

I feel like this patch should be two, instead: you can have one that makes the commands succeed or fail properly, and another that outputs the advice. As it is, it's a bit muddled as to what is necessary for the movement of the index entry versus representing the error message.

This might mean that you want to pull the advice messages out of the tests that are added in patch 1 and only apply those to the test as you implement the advice in that later patch. Such a split of the test implementation would allow this patch to still switch a bunch of test_expect_failure tests to test_expect_success.

Show 5 quoted lines
> @@ -424,6 +426,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) &&

Here is a use of dst_mode that might be helpful to put with the change in patch 4. Alternatively, you could delay declaring dst_mode until now.

> +		if (!(mode & SPARSE) && !lstat(src, &st))
> +			up_to_date = !ce_modified(active_cache[pos], &st, 0);

Here, you are only checking for a dirty file if (mode & SPARSE) and the file exists.

Perhaps it would be helpful to negate this and rename the variable?
	sparse_and_dirty = ce_modified(active_cache[pos], &st, 0);

This makes it clear that we can't use the variable except in this particular case.

Show 23 quoted lines
> -		if ((mode & SPARSE) &&
> -		    (path_in_sparse_checkout(dst, &the_index))) {
> -			int dst_pos;
> +		if (ignore_sparse &&
> +		    core_apply_sparse_checkout &&
> +		    core_sparse_checkout_cone) {
>  
> -			dst_pos = cache_name_pos(dst, strlen(dst));
> -			active_cache[dst_pos]->ce_flags &= ~CE_SKIP_WORKTREE;
> +			/* from out-of-cone to in-cone */
> +			if ((mode & SPARSE) &&
> +			    path_in_sparse_checkout(dst, &the_index)) {
> +				int dst_pos = cache_name_pos(dst, strlen(dst));
> +				struct cache_entry *dst_ce = active_cache[dst_pos];
>  
> -			if (checkout_entry(active_cache[dst_pos], &state, NULL, NULL))
> -				die(_("cannot checkout %s"), active_cache[dst_pos]->name);
> +				dst_ce->ce_flags &= ~CE_SKIP_WORKTREE;
> +
> +				if (checkout_entry(dst_ce, &state, NULL, NULL))
> +					die(_("cannot checkout %s"), dst_ce->name);
> +				continue;
> +			}

Here, it helps to ignore whitespace changes. This out to in was already handled by the existing implementation.

> +			/* from in-cone to out-of-cone */
> +			if ((dst_mode & SKIP_WORKTREE_DIR) &&

This is disjoint from the other case (because of !path_in_sparse_checkout()), so maybe we could short-circuit with an "else if" here? You could put your comments about the in-to-out or out-to-in inside the if blocks.

> +			    !(mode & SPARSE) &&
> +			    !path_in_sparse_checkout(dst, &the_index)) {
> +				int dst_pos = cache_name_pos(dst, strlen(dst));
> +				struct cache_entry *dst_ce = active_cache[dst_pos];

(It took me a while to realize that dst_ce is the right entry because we already called rename_cache_entry_at() earlier.)

> +				char *src_dir = dirname(xstrdup(src));
The xstrdup(src) return string is being lost here.
> +
> +				if (up_to_date) {
Based on my recommendation earlier, this would become
	if (!sparse_and_dirty) {
Show 6 quoted lines
> +					dst_ce->ce_flags |= CE_SKIP_WORKTREE;
> +					unlink_or_warn(src);
> +				} else {
> +					string_list_append(&dirty_paths, dst);
> +					safe_create_leading_directories(xstrdup(dst));
> +					rename(src, dst);
Ok, still doing the file rename, but leaving it unstaged.
> +				}

Please provide some whitespace between the close of an if/else chain before starting the next if.

> +				if ((mode & INDEX) && is_empty_dir(src_dir))
> +					rmdir_or_warn(src_dir);

This is an interesting cleanup of the first-level directory. Should it be recursive and clean up an entire chain of paths?

Thanks, -Stolee

Previous: Shaoxuan YuanNext: Shaoxuan Yuan
Message 22 of 61 in “mv: from in-cone to out-of-cone”
  1. 0/7 mv: from in-cone to out-of-coneShaoxuan Yuan, Jul 19, 2022
  2. 1/7 t7002: add tests for moving from in-cone to out-of-coneShaoxuan Yuan, Jul 19, 2022
  3. Ævar Arnfjörð BjarmasonJul 19, 2022
  4. Derrick StoleeJul 19, 2022
  5. Junio C HamanoJul 19, 2022
  6. 2/7 mv: add documentation for check_dir_in_index()Shaoxuan Yuan, Jul 19, 2022
  7. Derrick StoleeJul 19, 2022
  8. Shaoxuan YuanJul 21, 2022
  9. Victoria DyeJul 19, 2022
  10. Victoria DyeJul 19, 2022
  11. Shaoxuan YuanJul 21, 2022
  12. 3/7 mv: free the *with_slash in check_dir_in_index()Shaoxuan Yuan, Jul 19, 2022
  13. Derrick StoleeJul 19, 2022
  14. 5/7 mv: remove BOTH from enum update_modeShaoxuan Yuan, Jul 19, 2022
  15. Derrick StoleeJul 19, 2022
  16. 4/7 mv: check if <destination> is a SKIP_WORKTREE_DIRShaoxuan Yuan, Jul 19, 2022
  17. Derrick StoleeJul 19, 2022
  18. Shaoxuan YuanJul 21, 2022
  19. Derrick StoleeJul 22, 2022
  20. Junio C HamanoJul 22, 2022
  21. 6/7 mv: from in-cone to out-of-coneShaoxuan Yuan, Jul 19, 2022
  22. Derrick StoleeJul 19, 2022
  23. Shaoxuan YuanAug 3, 2022
  24. Derrick StoleeAug 3, 2022
  25. Shaoxuan YuanAug 4, 2022
  26. 7/7 mv: check overwrite for in-to-out moveShaoxuan Yuan, Jul 19, 2022
  27. Derrick StoleeJul 19, 2022
  28. Derrick StoleeJul 19, 2022
  29. 0/9 mv: from in-cone to out-of-coneShaoxuan Yuan, Aug 5, 2022
  30. 1/9 t7002: add tests for moving from in-cone to out-of-coneShaoxuan Yuan, Aug 5, 2022
  31. Victoria DyeAug 9, 2022
  32. Shaoxuan YuanAug 9, 2022
  33. Shaoxuan YuanAug 9, 2022
  34. Shaoxuan YuanAug 9, 2022
  35. 2/9 mv: rename check_dir_in_index() to empty_dir_has_sparse_contents()Shaoxuan Yuan, Aug 5, 2022
  36. 3/9 mv: free the *with_slash in check_dir_in_index()Shaoxuan Yuan, Aug 5, 2022
  37. Victoria DyeAug 8, 2022
  38. Shaoxuan YuanAug 9, 2022
  39. 4/9 mv: check if <destination> is a SKIP_WORKTREE_DIRShaoxuan Yuan, Aug 5, 2022
  40. Victoria DyeAug 8, 2022
  41. Victoria DyeAug 9, 2022
  42. Shaoxuan YuanAug 9, 2022
  43. 5/9 mv: remove BOTH from enum update_modeShaoxuan Yuan, Aug 5, 2022
  44. 6/9 mv: from in-cone to out-of-coneShaoxuan Yuan, Aug 5, 2022
  45. Victoria DyeAug 9, 2022
  46. Shaoxuan YuanAug 9, 2022
  47. 7/9 mv: cleanup empty WORKING_DIRECTORYShaoxuan Yuan, Aug 5, 2022
  48. 8/9 advice.h: add advise_on_moving_dirty_path()Shaoxuan Yuan, Aug 5, 2022
  49. 9/9 mv: check overwrite for in-to-out moveShaoxuan Yuan, Aug 5, 2022
  50. Victoria DyeAug 8, 2022
  51. 0/9 mv: from in-cone to out-of-coneShaoxuan Yuan, Aug 9, 2022
  52. 1/9 t7002: add tests for moving from in-cone to out-of-coneShaoxuan Yuan, Aug 9, 2022
  53. 2/9 mv: rename check_dir_in_index() to empty_dir_has_sparse_contents()Shaoxuan Yuan, Aug 9, 2022
  54. 3/9 mv: free the with_slash in check_dir_in_index()Shaoxuan Yuan, Aug 9, 2022
  55. 5/9 mv: remove BOTH from enum update_modeShaoxuan Yuan, Aug 9, 2022
  56. 6/9 mv: from in-cone to out-of-coneShaoxuan Yuan, Aug 9, 2022
  57. 7/9 mv: cleanup empty WORKING_DIRECTORYShaoxuan Yuan, Aug 9, 2022
  58. 8/9 advice.h: add advise_on_moving_dirty_path()Shaoxuan Yuan, Aug 9, 2022
  59. 9/9 mv: check overwrite for in-to-out moveShaoxuan Yuan, Aug 9, 2022
  60. 4/9 mv: check if <destination> is a SKIP_WORKTREE_DIRShaoxuan Yuan, Aug 9, 2022
  61. Victoria DyeAug 16, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.