All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
To: git@vger.kernel.org
Cc: "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>
Subject: [PATCH] rm: add --intent-to-add, to be used with --cached
Date: Sat, 22 Jun 2019 19:24:17 +0700	[thread overview]
Message-ID: <20190622122417.28178-1-pclouds@gmail.com> (raw)

An index entry serves two purposes: to keep the content to be committed,
and to mark that the same path on worktree is tracked. When

    git rm --cached foo

is called and there is "foo" in worktree, its status is changed from
tracked to untracked. Which I think is not intended, at least from the
user perspective because we almost always tell people "Git is about the
content" (*).

Add --intent-to-add, which will replace the current index entry with an
intent-to-add one. "git commit -m gone" will record "foo" gone, while
"git commit -am not-gone" will ignore the index as usual and keep "foo".
Before this, "commit -am" will also remove "foo".

While I think --intent-to-add (and also the one in git-reset) should be
the default behavior, changing it flip the test suite out because it
relies on the current behavior. Let's leave that for later. At least
having the ability to just remove the staged content is the right thing
to do.

(*) From the developer perspective, keeping the tool dumb actually
    sounds good. When you tell git to remove something from the index,
    it should go do just that, no trying to be clever. But that's more
    suitable for plumbing commands like update-index than rm, in my
    opinion.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 This occurred to me while adding intent-to-add support to git-restore.
 It's not related to nd/switch-and-restore though and I originally
 wanted to make it default, so I post it separately here.

 Documentation/git-rm.txt |  6 ++++++
 builtin/rm.c             | 10 ++++++++--
 t/t3600-rm.sh            |  9 +++++++++
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt
index b5c46223c4..aa0aa6063f 100644
--- a/Documentation/git-rm.txt
+++ b/Documentation/git-rm.txt
@@ -60,6 +60,12 @@ OPTIONS
 	Working tree files, whether modified or not, will be
 	left alone.
 
+--intent-to-add::
+--no-intent-to-add::
+	When `--cached` is used, if the given path also exist as a
+	working tree file, the index is updated to record the fact
+	that the path will be added later, similar to `git add -N`.
+
 --ignore-unmatch::
 	Exit with a zero status even if no files matched.
 
diff --git a/builtin/rm.c b/builtin/rm.c
index be8edc6d1e..135bc4b76e 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -235,12 +235,14 @@ static int check_local_mod(struct object_id *head, int index_only)
 }
 
 static int show_only = 0, force = 0, index_only = 0, recursive = 0, quiet = 0;
-static int ignore_unmatch = 0;
+static int ignore_unmatch = 0, intent_to_add = 0;
 
 static struct option builtin_rm_options[] = {
 	OPT__DRY_RUN(&show_only, N_("dry run")),
 	OPT__QUIET(&quiet, N_("do not list removed files")),
 	OPT_BOOL( 0 , "cached",         &index_only, N_("only remove from the index")),
+	OPT_BOOL( 0 , "intent-to-add",  &intent_to_add,
+		  N_("record that the path will be added later if needed")),
 	OPT__FORCE(&force, N_("override the up-to-date check"), PARSE_OPT_NOCOMPLETE),
 	OPT_BOOL('r', NULL,             &recursive,  N_("allow recursive removal")),
 	OPT_BOOL( 0 , "ignore-unmatch", &ignore_unmatch,
@@ -262,7 +264,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 	if (!argc)
 		usage_with_options(builtin_rm_usage, builtin_rm_options);
 
-	if (!index_only)
+	if (!index_only || intent_to_add)
 		setup_work_tree();
 
 	hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
@@ -344,6 +346,10 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 
 		if (remove_file_from_cache(path))
 			die(_("git rm: unable to remove %s"), path);
+
+		if (index_only && intent_to_add && file_exists(path) &&
+		    add_file_to_index(the_repository->index, path, ADD_CACHE_INTENT))
+			error(_("failed to mark '%s' as intent-to-add"), path);
 	}
 
 	if (show_only)
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 85ae7dc1e4..04233b7dc4 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -34,6 +34,15 @@ test_expect_success 'Test that git rm foo succeeds' '
 	git rm --cached foo
 '
 
+test_expect_success 'Test that git rm --cached --intent-to-add foo succeeds' '
+	echo content >foo &&
+	git add foo &&
+	git rm --cached --intent-to-add foo &&
+	git diff --summary -- foo >actual &&
+	echo " create mode 100644 foo" >expected &&
+	test_cmp expected actual
+'
+
 test_expect_success 'Test that git rm --cached foo succeeds if the index matches the file' '
 	echo content >foo &&
 	git add foo &&
-- 
2.22.0.rc0.322.g2b0371e29a


             reply	other threads:[~2019-06-22 12:24 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-22 12:24 Nguyễn Thái Ngọc Duy [this message]
2019-06-24 10:52 ` [PATCH] rm: add --intent-to-add, to be used with --cached Johannes Schindelin
2019-06-24 15:02   ` Duy Nguyen

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=20190622122417.28178-1-pclouds@gmail.com \
    --to=pclouds@gmail.com \
    --cc=git@vger.kernel.org \
    /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.