All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Teach rm to remove submodules when given with a trailing '/'
@ 2012-10-28 23:28 Jens Lehmann
  2012-10-29  7:11 ` Johannes Sixt
  0 siblings, 1 reply; 5+ messages in thread
From: Jens Lehmann @ 2012-10-28 23:28 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Jeff King

Doing a "git rm submod/" on a submodule results in an error:
	fatal: pathspec 'submod/' did not match any files
This is really inconvenient as e.g. using TAB completion in a shell on a
submodule automatically adds the trailing '/' when it completes the path
of the submodule directory. The user has then to remove the '/' herself to
make a "git rm" succeed. Doing a "git rm -r somedir/" is working fine, so
there is no reason why that shouldn't work for submodules too.

Teach git rm to not error out when a '/' is appended to the path of a
submodule. Achieve this by chopping off trailing slashes from the path
names given if they represent directories. Add tests to make sure that
logic only applies to directories and not to files.

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---


This patch applies on top of the jl/submodule-rm branch merged into
current next.


 builtin/rm.c  |  7 +++++++
 t/t3600-rm.sh | 17 +++++++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/builtin/rm.c b/builtin/rm.c
index 2aea3b5..5381d3f 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -234,6 +234,13 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 	if (read_cache() < 0)
 		die(_("index file corrupt"));

+	/* Remove trailing '/' from directories to find submodules in the index */
+	for (i = 0; i < argc; i++) {
+		size_t pathlen = strlen(argv[i]);
+		if (pathlen && is_directory(argv[i]) && (argv[i][pathlen - 1] == '/'))
+			argv[i] = xmemdupz(argv[i], pathlen - 1);
+	}
+
 	pathspec = get_pathspec(prefix, argv);
 	refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);

diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 97254e8..06f6384 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -302,6 +302,23 @@ test_expect_success 'rm removes work tree of unmodified submodules' '
 	test_cmp expect actual
 '

+test_expect_success 'rm removes a submodule with a trailing /' '
+	git reset --hard &&
+	git submodule update &&
+	git rm submod/ &&
+	test ! -d submod &&
+	git status -s -uno --ignore-submodules=none > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'rm fails when given a file with a trailing /' '
+	test_must_fail git rm empty/
+'
+
+test_expect_success 'rm succeeds when given a directory with a trailing /' '
+	git rm -r frotz/
+'
+
 test_expect_success 'rm of a populated submodule with different HEAD fails unless forced' '
 	git reset --hard &&
 	git submodule update &&
-- 
1.8.0.42.g3346551

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] Teach rm to remove submodules when given with a trailing '/'
  2012-10-28 23:28 [PATCH] Teach rm to remove submodules when given with a trailing '/' Jens Lehmann
@ 2012-10-29  7:11 ` Johannes Sixt
  2012-10-30 21:28   ` Jens Lehmann
  0 siblings, 1 reply; 5+ messages in thread
From: Johannes Sixt @ 2012-10-29  7:11 UTC (permalink / raw)
  To: Jens Lehmann; +Cc: Git Mailing List, Jeff King

Am 10/29/2012 0:28, schrieb Jens Lehmann:
> +	/* Remove trailing '/' from directories to find submodules in the index */
> +	for (i = 0; i < argc; i++) {
> +		size_t pathlen = strlen(argv[i]);
> +		if (pathlen && is_directory(argv[i]) && (argv[i][pathlen - 1] == '/'))
> +			argv[i] = xmemdupz(argv[i], pathlen - 1);
> +	}
> +
>  	pathspec = get_pathspec(prefix, argv);
>  	refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);

That's wrong: Either move the check below get_pathspec() (which normalizes
backslashes to forward-slashes on Windows) or use is_dir_sep().

But isn't it somewhat dangerous to check pathspec for existance in the
worktree without interpreting them? Think of magic pathspec syntax (that
we do not have yet, but which may materialize sometime in the future).

-- Hannes

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Teach rm to remove submodules when given with a trailing '/'
  2012-10-29  7:11 ` Johannes Sixt
@ 2012-10-30 21:28   ` Jens Lehmann
  2012-10-31  6:29     ` Johannes Sixt
  0 siblings, 1 reply; 5+ messages in thread
From: Jens Lehmann @ 2012-10-30 21:28 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Git Mailing List, Jeff King

Am 29.10.2012 08:11, schrieb Johannes Sixt:
> Am 10/29/2012 0:28, schrieb Jens Lehmann:
>> +	/* Remove trailing '/' from directories to find submodules in the index */
>> +	for (i = 0; i < argc; i++) {
>> +		size_t pathlen = strlen(argv[i]);
>> +		if (pathlen && is_directory(argv[i]) && (argv[i][pathlen - 1] == '/'))
>> +			argv[i] = xmemdupz(argv[i], pathlen - 1);
>> +	}
>> +
>>  	pathspec = get_pathspec(prefix, argv);
>>  	refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);
> 
> That's wrong: Either move the check below get_pathspec() (which normalizes
> backslashes to forward-slashes on Windows) or use is_dir_sep().

Thanks for bringing this up.

> But isn't it somewhat dangerous to check pathspec for existance in the
> worktree without interpreting them? Think of magic pathspec syntax (that
> we do not have yet, but which may materialize sometime in the future).

I have to admit I'm not aware of magic pathspec syntax. Do you happen to
have any pointers where I could look at code doing similar things right?

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Teach rm to remove submodules when given with a trailing '/'
  2012-10-30 21:28   ` Jens Lehmann
@ 2012-10-31  6:29     ` Johannes Sixt
  2012-11-22 22:32       ` [PATCH v2] " Jens Lehmann
  0 siblings, 1 reply; 5+ messages in thread
From: Johannes Sixt @ 2012-10-31  6:29 UTC (permalink / raw)
  To: Jens Lehmann; +Cc: Git Mailing List, Jeff King

Am 10/30/2012 22:28, schrieb Jens Lehmann:
> Am 29.10.2012 08:11, schrieb Johannes Sixt:
>> Am 10/29/2012 0:28, schrieb Jens Lehmann:
>>> +	/* Remove trailing '/' from directories to find submodules in the index */
>>> +	for (i = 0; i < argc; i++) {
>>> +		size_t pathlen = strlen(argv[i]);
>>> +		if (pathlen && is_directory(argv[i]) && (argv[i][pathlen - 1] == '/'))
>>> +			argv[i] = xmemdupz(argv[i], pathlen - 1);
>>> +	}
>>> +
>>>  	pathspec = get_pathspec(prefix, argv);
>>>  	refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);
>>
>> That's wrong: Either move the check below get_pathspec() (which normalizes
>> backslashes to forward-slashes on Windows) or use is_dir_sep().
> 
> Thanks for bringing this up.
> 
>> But isn't it somewhat dangerous to check pathspec for existance in the
>> worktree without interpreting them? Think of magic pathspec syntax (that
>> we do not have yet, but which may materialize sometime in the future).
> 
> I have to admit I'm not aware of magic pathspec syntax. Do you happen to
> have any pointers where I could look at code doing similar things right?

cmd_mv() in builtin/mv.c looks like a good candidate. It has to check
whether the destination (the last argument) is a directory.

-- Hannes

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v2] Teach rm to remove submodules when given with a trailing '/'
  2012-10-31  6:29     ` Johannes Sixt
@ 2012-11-22 22:32       ` Jens Lehmann
  0 siblings, 0 replies; 5+ messages in thread
From: Jens Lehmann @ 2012-11-22 22:32 UTC (permalink / raw)
  To: Git Mailing List; +Cc: Johannes Sixt, Junio C Hamano, Jeff King

Doing a "git rm submod/" on a submodule results in an error:
	fatal: pathspec 'submod/' did not match any files
This is really inconvenient as e.g. using TAB completion in a shell on a
submodule automatically adds the trailing '/' when it completes the path
of the submodule directory. The user has then to remove the '/' herself to
make a "git rm" succeed. Doing a "git rm -r somedir/" is working fine, so
there is no reason why that shouldn't work for submodules too.

Teach git rm to not error out when a '/' is appended to the path of a
submodule. Achieve this by chopping off trailing slashes from the path
names given if they represent directories. Add tests to make sure that
logic only applies to directories and not to files.

Signed-off-by: Jens Lehmann <Jens.Lehmann@web.de>
---

Am 31.10.2012 07:29, schrieb Johannes Sixt:
> Am 10/30/2012 22:28, schrieb Jens Lehmann:
>> Am 29.10.2012 08:11, schrieb Johannes Sixt:
>>> Am 10/29/2012 0:28, schrieb Jens Lehmann:
>>>> +	/* Remove trailing '/' from directories to find submodules in the index */
>>>> +	for (i = 0; i < argc; i++) {
>>>> +		size_t pathlen = strlen(argv[i]);
>>>> +		if (pathlen && is_directory(argv[i]) && (argv[i][pathlen - 1] == '/'))
>>>> +			argv[i] = xmemdupz(argv[i], pathlen - 1);
>>>> +	}
>>>> +
>>>>  	pathspec = get_pathspec(prefix, argv);
>>>>  	refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);
>>>
>>> That's wrong: Either move the check below get_pathspec() (which normalizes
>>> backslashes to forward-slashes on Windows) or use is_dir_sep().
>>
>> Thanks for bringing this up.

And sorry for taking so long to follow up on this, but I'm currently
pretty occupied with real life issues and am rather short on git time.

>>> But isn't it somewhat dangerous to check pathspec for existance in the
>>> worktree without interpreting them? Think of magic pathspec syntax (that
>>> we do not have yet, but which may materialize sometime in the future).
>>
>> I have to admit I'm not aware of magic pathspec syntax. Do you happen to
>> have any pointers where I could look at code doing similar things right?
> 
> cmd_mv() in builtin/mv.c looks like a good candidate. It has to check
> whether the destination (the last argument) is a directory.

Thanks, that was a good pointer (and judging from the comment just before
prefix_pathspec() in setup.c I currently can't do /that/ much about the
magic pathspec syntax as it has not materialized yet ;-).

I was thinking about reusing the copy_pathspec() function from mv.c but
came to the conclusion not to do so because it a) doesn't care if a '/'
is following a file (where I believe it should not be dropped but mv
should error out, but it currently doesn't) and b) it also has the
base_name argument I don't need (and which seems to be rather special to
the needs of mv.c). So I coded that loop myself using is_dir_sep()
(taking care that is_directory() will only be called on paths which have
a trailing directory separator).


 builtin/rm.c  | 15 +++++++++++++++
 t/t3600-rm.sh | 17 +++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/builtin/rm.c b/builtin/rm.c
index 2aea3b5..dabfcf6 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -234,6 +234,21 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 	if (read_cache() < 0)
 		die(_("index file corrupt"));

+	/*
+	 * Drop trailing directory separators from directories so we'll find
+	 * submodules in the index.
+	 */
+	for (i = 0; i < argc; i++) {
+		size_t pathlen = strlen(argv[i]);
+		if (pathlen && is_dir_sep(argv[i][pathlen - 1]) &&
+		    is_directory(argv[i])) {
+			do {
+				pathlen--;
+			} while (pathlen && is_dir_sep(argv[i][pathlen - 1]));
+			argv[i] = xmemdupz(argv[i], pathlen);
+		}
+	}
+
 	pathspec = get_pathspec(prefix, argv);
 	refresh_index(&the_index, REFRESH_QUIET, pathspec, NULL, NULL);

diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh
index 97254e8..06f6384 100755
--- a/t/t3600-rm.sh
+++ b/t/t3600-rm.sh
@@ -302,6 +302,23 @@ test_expect_success 'rm removes work tree of unmodified submodules' '
 	test_cmp expect actual
 '

+test_expect_success 'rm removes a submodule with a trailing /' '
+	git reset --hard &&
+	git submodule update &&
+	git rm submod/ &&
+	test ! -d submod &&
+	git status -s -uno --ignore-submodules=none > actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'rm fails when given a file with a trailing /' '
+	test_must_fail git rm empty/
+'
+
+test_expect_success 'rm succeeds when given a directory with a trailing /' '
+	git rm -r frotz/
+'
+
 test_expect_success 'rm of a populated submodule with different HEAD fails unless forced' '
 	git reset --hard &&
 	git submodule update &&
-- 
1.8.0.91.gf07e555

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-11-22 22:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-28 23:28 [PATCH] Teach rm to remove submodules when given with a trailing '/' Jens Lehmann
2012-10-29  7:11 ` Johannes Sixt
2012-10-30 21:28   ` Jens Lehmann
2012-10-31  6:29     ` Johannes Sixt
2012-11-22 22:32       ` [PATCH v2] " Jens Lehmann

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.