git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Junio C Hamano <gitster@pobox.com>
Cc: jpinheiro <7jpinheiro@gmail.com>, git@vger.kernel.org
Subject: [PATCH 1/3] rm: do not complain about d/f conflicts during deletion
Date: Thu, 4 Apr 2013 15:03:35 -0400	[thread overview]
Message-ID: <20130404190335.GA4063@sigill.intra.peff.net> (raw)
In-Reply-To: <20130404190211.GA15912@sigill.intra.peff.net>

If we used to have an index entry "d/f", but "d" has been
replaced by a non-directory entry, the user may still want
to run "git rm" to delete the stale index entry. They could
use "git rm --cached" to just touch the index, but "git rm"
should also work: we explicitly try to handle the case that
the file has already been removed from the working tree.

However, because unlinking "d/f" in this case will not yield
ENOENT, but rather ENOTDIR, we do not notice that the file
is already gone. Instead, we report it as an error.

The simple solution is to treat ENOTDIR in this case exactly
like ENOENT; all we want to know is whether the file is
already gone, and if a leading path is no longer a
directory, then by definition the sub-path is gone.

Reported-by: jpinheiro <7jpinheiro@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
---
 builtin/rm.c  |  2 +-
 dir.c         |  2 +-
 t/t3600-rm.sh | 25 +++++++++++++++++++++++++
 3 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/builtin/rm.c b/builtin/rm.c
index dabfcf6..7b91d52 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -110,7 +110,7 @@ static int check_local_mod(unsigned char *head, int index_only)
 		ce = active_cache[pos];
 
 		if (lstat(ce->name, &st) < 0) {
-			if (errno != ENOENT)
+			if (errno != ENOENT && errno != ENOTDIR)
 				warning("'%s': %s", ce->name, strerror(errno));
 			/* It already vanished from the working tree */
 			continue;
diff --git a/dir.c b/dir.c
index 57394e4..f9e7355 100644
--- a/dir.c
+++ b/dir.c
@@ -1603,7 +1603,7 @@ int remove_path(const char *name)
 {
 	char *slash;
 
-	if (unlink(name) && errno != ENOENT)
+	if (unlink(name) && errno != ENOENT && errno != ENOTDIR)
 		return -1;
 
 	slash = strrchr(name, '/');
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 37bf5f1..73772b2 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -622,4 +622,29 @@ test_expect_success 'rm of a populated nested submodule with a nested .git direc
 	rm -rf submod
 '
 
+test_expect_success 'rm of d/f when d has become a non-directory' '
+	rm -rf d &&
+	mkdir d &&
+	>d/f &&
+	git add d &&
+	rm -rf d &&
+	>d &&
+	git rm d/f &&
+	test_must_fail git rev-parse --verify :d/f &&
+	test_path_is_file d
+'
+
+test_expect_success SYMLINKS 'rm of d/f when d has become a dangling symlink' '
+	rm -rf d &&
+	mkdir d &&
+	>d/f &&
+	git add d &&
+	rm -rf d &&
+	ln -s nonexistent d &&
+	git rm d/f &&
+	test_must_fail git rev-parse --verify :d/f &&
+	test -h d &&
+	test_path_is_missing d
+'
+
 test_done
-- 
1.8.2.rc0.33.gd915649

  reply	other threads:[~2013-04-04 19:04 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-03 14:50 Behavior of git rm jpinheiro
2013-04-03 15:58 ` Jeff King
2013-04-03 17:35   ` Junio C Hamano
2013-04-03 20:36     ` Jeff King
2013-04-04 19:02     ` Jeff King
2013-04-04 19:03       ` Jeff King [this message]
2013-04-04 19:03       ` [PATCH 2/3] t3600: test behavior of reverse-d/f conflict Jeff King
2013-04-04 19:06       ` [PATCH 3/3] t3600: test rm of path with changed leading symlinks Jeff King
2013-04-04 19:42         ` Junio C Hamano
2013-04-04 19:55           ` Jeff King
2013-04-04 20:31             ` Junio C Hamano
2013-04-04 21:03               ` Jeff King
2013-04-04 23:12                 ` Junio C Hamano
2013-04-04 23:29                   ` Jeff King
2013-04-04 23:33                     ` Junio C Hamano
2013-04-05  0:00                       ` Jeff King
2013-04-05  4:59                         ` Junio C Hamano
2013-04-05  5:04                           ` Jeff King

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=20130404190335.GA4063@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=7jpinheiro@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).