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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxx>
---
 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
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux