Thread (28 messages) 28 messages, 11 authors, 2016-06-15

[RFC/PATCH] reset: accept "git reset <removed file>"

flat view

From: Jonathan Nieder <hidden>
Date: 2016-06-15 22:49:48
Subsystem: the rest · Maintainer: Linus Torvalds

Suppose I try to use "git reset" to un-add an new, unwanted file:

	echo hello >foo.c
	git add foo.c
	rm foo.c; # bad file! bad!
	git reset foo.c

The file foo.c does not exist on disk, so "git reset" rejects the
request with

	fatal: ambiguous argument 'foo.c': unknown revision or path not in the working tree.
	Use '--' to separate paths from revisions

Git can do better: since foo.c is not a revision and has an entry in
the index, it is clear the request refers to a path and not a rev.

Signed-off-by: Jonathan Nieder <redacted>
---
Jonathan Nieder wrote:
Ah, this is a kind of obnoxious thing!  For a newly added file,

	git reset -- <path>

ought to un-add it, but it doesn't.
Err, yes it does.  Probably I was thinking of

	rm <path>
	git reset <path>

producing an "ambiguous argument" message.

 builtin/reset.c  |    8 +++++++-
 t/t7102-reset.sh |   34 ++++++++++++++++++++++++++++++++--
 2 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/builtin/reset.c b/builtin/reset.c
index 0037be4..7d23d75 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -295,7 +295,13 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
 			rev = argv[i++];
 		} else {
 			/* Otherwise we treat this as a filename */
-			verify_filename(prefix, argv[i]);
+			const char *name = argv[i];
+			if (prefix)
+				name = prefix_filename(prefix, strlen(prefix), name);
+			if (read_cache() < 0)
+				die("Could not read index");
+			if (cache_name_pos(name, strlen(name)) < 0)
+				verify_filename(prefix, argv[i]);
 		}
 	}
 
diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh
index b8cf260..69d125e 100755
--- a/t/t7102-reset.sh
+++ b/t/t7102-reset.sh
@@ -5,7 +5,7 @@
 
 test_description='git reset
 
-Documented tests for git reset'
+Miscellaneous tests for git reset'
 
 . ./test-lib.sh
 
@@ -441,6 +441,15 @@ test_expect_success 'disambiguation (1)' '
 
 '
 
+test_expect_success "disambiguation (1')" '
+
+	git reset --hard &&
+	git reset secondfile &&
+	git diff --exit-code &&
+	git diff --cached --exit-code
+
+'
+
 test_expect_success 'disambiguation (2)' '
 
 	git reset --hard &&
@@ -448,11 +457,18 @@ test_expect_success 'disambiguation (2)' '
 	git add secondfile &&
 	rm -f secondfile &&
 	test_must_fail git reset secondfile &&
-	test -n "$(git diff --cached --name-only -- secondfile)" &&
+	test -z "$(git diff --cached --name-only)" &&
 	test ! -f secondfile
 
 '
 
+test_expect_success "disambiguation (2')" '
+
+	git reset --hard &&
+	test_must_fail git reset doesnotexist
+
+'
+
 test_expect_success 'disambiguation (3)' '
 
 	git reset --hard &&
@@ -465,6 +481,13 @@ test_expect_success 'disambiguation (3)' '
 
 '
 
+test_expect_success "disambiguation (3')" '
+
+	git reset --hard &&
+	git reset HEAD doesnotexist
+
+'
+
 test_expect_success 'disambiguation (4)' '
 
 	git reset --hard &&
@@ -476,4 +499,11 @@ test_expect_success 'disambiguation (4)' '
 	test ! -f secondfile
 '
 
+test_expect_success "disambiguation (4')" '
+
+	git reset --hard &&
+	git reset -- doesnotexist
+
+'
+
 test_done
-- 
1.7.2.3
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help