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

[PATCH 2/2] rm: loosen safety valve for empty files

From
Jeff King <peff@peff.net>
Date
Oct 21, 2008, 00:37 UTC
Message-ID
<20081021003712.GB32569@coredump.intra.peff.net>

If a file is different between the working tree copy, the index, and the HEAD, then we do not allow it to be deleted without --force.

However, this is overly tight in the face of "git add --intent-to-add":

  $ git add --intent-to-add file
  $ : oops, I don't actually want to stage that yet
  $ git rm --cached file
  error: 'file' has staged content different from both the
  file and the HEAD (use -f to force removal)
  $ git rm -f --cached file

This patch loosens the safety valve to allow the deletion only if we are deleting the cached entry and the cached content is empty.

This covers the intent-to-add situation, and presumably there is little harm in not protecting users who have legitimately added an empty file. In many cases, the file will still be empty, in which case the safety valve does not trigger anyway (since the content remains untouched in the working tree). Otherwise, we do remove the fact that no content was staged, but given that the content is by definition empty, it is not terribly difficult for a user to recreate it.

Signed-off-by: Jeff King <peff@peff.net>
---
 builtin-rm.c  |    3 ++-
 cache.h       |    1 +
 read-cache.c  |    2 +-
 t/t3600-rm.sh |    7 +++++++
 4 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/builtin-rm.c b/builtin-rm.c
index e06640c..b7126e3 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -79,7 +79,8 @@ static int check_local_mod(unsigned char *head, int index_only)
 		     || hashcmp(ce->sha1, sha1))
 			staged_changes = 1;
 
-		if (local_changes && staged_changes)
+		if (local_changes && staged_changes &&
+		    !(index_only && is_empty_blob_sha1(ce->sha1)))
 			errs = error("'%s' has staged content different "
 				     "from both the file and the HEAD\n"
 				     "(use -f to force removal)", name);
diff --git a/cache.h b/cache.h
index ae6647e..7141705 100644
--- a/cache.h
+++ b/cache.h
@@ -517,6 +517,7 @@ static inline void hashclr(unsigned char *hash)
 {
 	memset(hash, 0, 20);
 }
+extern int is_empty_blob_sha1(const unsigned char *sha1);
 
 int git_mkstemp(char *path, size_t n, const char *template);
 
diff --git a/read-cache.c b/read-cache.c
index 780f2c7..d624cb3 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -160,7 +160,7 @@ static int ce_modified_check_fs(struct cache_entry *ce, struct stat *st)
 	return 0;
 }
 
-static int is_empty_blob_sha1(const unsigned char *sha1)
+int is_empty_blob_sha1(const unsigned char *sha1)
 {
 	static const unsigned char empty_blob_sha1[20] = {
 		0xe6,0x9d,0xe2,0x9b,0xb2,0xd1,0xd6,0x43,0x4b,0x8b,
diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 66aca99..88ae672 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -187,6 +187,13 @@ test_expect_success 'but with -f it should work.' '
 	test_must_fail git ls-files --error-unmatch baz
 '
 
+test_expect_success 'ok to remove cached empty file' '
+	touch empty &&
+	git add empty &&
+	echo content >empty &&
+	git rm --cached empty
+'
+
 test_expect_success 'Recursive test setup' '
 	mkdir -p frotz &&
 	echo qfwfq >frotz/nitfol &&
-- 
1.6.0.2.770.gb4241.dirty
Next: Junio C Hamano
Message 1 of 3 in “rm: loosen safety valve for empty files”
  1. 2/2 rm: loosen safety valve for empty filesJeff King, Oct 21, 2008
  2. Junio C HamanoOct 21, 2008
  3. Jeff KingOct 21, 2008

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.