git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* [RFC/PATCH] ls-files: adding support for submodules
@ 2016-09-09 21:53 Brandon Williams
  2016-09-09 22:35 ` Jeff King
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Brandon Williams @ 2016-09-09 21:53 UTC (permalink / raw)
  To: git; +Cc: Brandon Williams

Allow ls-files to recognize submodules in order to retrieve a list of
files from a repository's submodules.  This is done by forking off a
process to recursively call ls-files on all submodules.

Signed-off-by: Brandon Williams <bmwill@google.com>
---
Hey git developers!

I'm new to the community and this is the first patch for an open source project
that I have worked on.

I'm looking forward to working on the project!
Brandon Williams

 Documentation/git-ls-files.txt         |   7 ++-
 builtin/ls-files.c                     |  58 +++++++++++++++++++
 t/t3007-ls-files-recurse-submodules.sh | 103 +++++++++++++++++++++++++++++++++
 3 files changed, 167 insertions(+), 1 deletion(-)
 create mode 100644 t/t3007-ls-files-recurse-submodules.sh

diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index 0d933ac..446209e 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -18,7 +18,8 @@ SYNOPSIS
 		[--exclude-per-directory=<file>]
 		[--exclude-standard]
 		[--error-unmatch] [--with-tree=<tree-ish>]
-		[--full-name] [--abbrev] [--] [<file>...]
+		[--full-name] [--recurse-submodules]
+		[--abbrev] [--] [<file>...]
 
 DESCRIPTION
 -----------
@@ -137,6 +138,10 @@ a space) at the start of each line:
 	option forces paths to be output relative to the project
 	top directory.
 
+--recurse-submodules::
+	Recursively calls ls-files on each submodule in the repository.
+	Currently there is only support for the --cached mode.
+
 --abbrev[=<n>]::
 	Instead of showing the full 40-byte hexadecimal object
 	lines, show only a partial prefix.
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 00ea91a..c428a51 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -14,6 +14,7 @@
 #include "resolve-undo.h"
 #include "string-list.h"
 #include "pathspec.h"
+#include "run-command.h"
 
 static int abbrev;
 static int show_deleted;
@@ -28,6 +29,7 @@ static int show_valid_bit;
 static int line_terminator = '\n';
 static int debug_mode;
 static int show_eol;
+static int recurse_submodules;
 
 static const char *prefix;
 static int max_prefix_len;
@@ -152,6 +154,45 @@ static void show_killed_files(struct dir_struct *dir)
 	}
 }
 
+/**
+ *  Recursively call ls-files on a submodule
+ */
+static void show_gitlink(const struct cache_entry *ce)
+{
+	struct child_process cp = CHILD_PROCESS_INIT;
+	struct strbuf buf = STRBUF_INIT;
+	struct strbuf name = STRBUF_INIT;
+	int submodule_name_len;
+	FILE *fp;
+
+	argv_array_push(&cp.args, "ls-files");
+	argv_array_push(&cp.args, "--recurse-submodules");
+	cp.git_cmd = 1;
+	cp.dir = ce->name;
+	cp.out = -1;
+	start_command(&cp);
+	fp = fdopen(cp.out, "r");
+
+	/*
+	 * The ls-files child process produces filenames relative to
+	 * the submodule. Prefix each line with the submodule path
+	 * to make it relative to the current repository.
+	 */
+	strbuf_addstr(&name, ce->name);
+	strbuf_addch(&name, '/');
+	submodule_name_len = name.len;
+	while (strbuf_getline(&buf, fp) != EOF) {
+		strbuf_addbuf(&name, &buf);
+		write_name(name.buf);
+		strbuf_setlen(&name, submodule_name_len);
+	}
+
+	finish_command(&cp);
+	strbuf_release(&buf);
+	strbuf_release(&name);
+	fclose(fp);
+}
+
 static void show_ce_entry(const char *tag, const struct cache_entry *ce)
 {
 	int len = max_prefix_len;
@@ -163,6 +204,10 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce)
 			    len, ps_matched,
 			    S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode)))
 		return;
+	if (recurse_submodules && S_ISGITLINK(ce->ce_mode)) {
+		show_gitlink(ce);
+		return;
+	}
 
 	if (tag && *tag && show_valid_bit &&
 	    (ce->ce_flags & CE_VALID)) {
@@ -468,6 +513,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 		{ OPTION_SET_INT, 0, "full-name", &prefix_len, NULL,
 			N_("make the output relative to the project top directory"),
 			PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL },
+		OPT_BOOL(0, "recurse-submodules", &recurse_submodules,
+			N_("recurse through submodules")),
 		OPT_BOOL(0, "error-unmatch", &error_unmatch,
 			N_("if any <file> is not in the index, treat this as an error")),
 		OPT_STRING(0, "with-tree", &with_tree, N_("tree-ish"),
@@ -519,6 +566,17 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 	if (require_work_tree && !is_inside_work_tree())
 		setup_work_tree();
 
+	if (recurse_submodules &&
+	    (show_stage || show_deleted || show_others || show_unmerged ||
+	     show_killed || show_modified || show_resolve_undo ||
+	     show_valid_bit || show_tag || show_eol))
+		die("ls-files --recurse-submodules can only be used in "
+		    "--cached mode");
+
+	if (recurse_submodules && argc)
+		die("ls-files --recurse-submodules does not support path "
+		    "arguments");
+
 	parse_pathspec(&pathspec, 0,
 		       PATHSPEC_PREFER_CWD |
 		       PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
diff --git a/t/t3007-ls-files-recurse-submodules.sh b/t/t3007-ls-files-recurse-submodules.sh
new file mode 100644
index 0000000..78deded
--- /dev/null
+++ b/t/t3007-ls-files-recurse-submodules.sh
@@ -0,0 +1,103 @@
+#!/bin/sh
+
+test_description='Test ls-files recurse-submodules feature
+
+This test verifies the recurse-submodules feature correctly lists files from
+submodules.
+'
+
+. ./test-lib.sh
+
+test_expect_success 'setup directory structure and submodules' '
+	echo a >a &&
+	mkdir b &&
+	echo b >b/b &&
+	git add a b &&
+	git commit -m "add a and b" &&
+	mkdir submodule &&
+	(
+		cd submodule &&
+		git init &&
+		echo c >c &&
+		git add c &&
+		git commit -m "add c"
+	) &&
+	git submodule add ./submodule &&
+	git commit -m "added submodule"
+'
+
+cat >expect <<EOF
+.gitmodules
+a
+b/b
+submodule/c
+EOF
+
+test_expect_success 'ls-files correctly outputs files in submodule' '
+	git ls-files --recurse-submodules >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'ls-files does not output files not added to a repo' '
+	echo a >not_added &&
+	echo b >b/not_added &&
+	(
+		cd submodule &&
+		echo c >not_added
+	) &&
+	git ls-files --recurse-submodules >actual &&
+	test_cmp expect actual
+'
+
+cat >expect <<EOF
+.gitmodules
+a
+b/b
+submodule/.gitmodules
+submodule/c
+submodule/subsub/d
+EOF
+
+test_expect_success 'ls-files recurses more than 1 level' '
+	(
+		cd submodule &&
+		mkdir subsub &&
+		(
+			cd subsub &&
+			git init &&
+			echo d >d &&
+			git add d &&
+			git commit -m "add d"
+		) &&
+		git submodule add ./subsub &&
+		git commit -m "added subsub"
+	) &&
+	git ls-files --recurse-submodules >actual &&
+	test_cmp expect actual
+'
+
+cat >expect_error <<EOF
+fatal: ls-files --recurse-submodules does not support path arguments
+EOF
+
+test_expect_success 'error when using path arguments' '
+	test_must_fail git ls-files --recurse-submodules b 2>actual &&
+	test_cmp expect_error actual
+'
+
+cat >expect_error <<EOF
+fatal: ls-files --recurse-submodules can only be used in --cached mode
+EOF
+
+test_expect_success 'error when using different modes' '
+	for opt in {v,t}; do
+		test_must_fail git ls-files --recurse-submodules -$opt 2>actual &&
+		test_cmp expect_error actual
+	done &&
+	for opt in {deleted,modified,others,ignored,stage,killed,unmerged,eol}; do
+		test_must_fail git ls-files --recurse-submodules --$opt 2>actual &&
+		test_cmp expect_error actual
+	done
+'
+
+test_done
-- 
2.8.0.rc3.226.g39d4020


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

* Re: [RFC/PATCH] ls-files: adding support for submodules
  2016-09-09 21:53 [RFC/PATCH] ls-files: adding support for submodules Brandon Williams
@ 2016-09-09 22:35 ` Jeff King
  2016-09-09 22:40   ` Junio C Hamano
  2016-09-09 23:01 ` Junio C Hamano
  2016-09-13  0:33 ` [PATCH v2] " Brandon Williams
  2 siblings, 1 reply; 22+ messages in thread
From: Jeff King @ 2016-09-09 22:35 UTC (permalink / raw)
  To: Brandon Williams; +Cc: git

On Fri, Sep 09, 2016 at 02:53:24PM -0700, Brandon Williams wrote:

> Allow ls-files to recognize submodules in order to retrieve a list of
> files from a repository's submodules.  This is done by forking off a
> process to recursively call ls-files on all submodules.
> 
> Signed-off-by: Brandon Williams <bmwill@google.com>
> ---
> Hey git developers!
> 
> I'm new to the community and this is the first patch for an open source project
> that I have worked on.
> 
> I'm looking forward to working on the project!

Welcome. :)

Submodules are not really my area of expertise, so I don't have any
commentary on the goal of the patch, except that it sounds reasonable to
my layman's ears.

The implementation looks fairly clean. A few comments:

> +static void show_gitlink(const struct cache_entry *ce)
> +{
> +	struct child_process cp = CHILD_PROCESS_INIT;
> +	struct strbuf buf = STRBUF_INIT;
> +	struct strbuf name = STRBUF_INIT;
> +	int submodule_name_len;
> +	FILE *fp;
> +
> +	argv_array_push(&cp.args, "ls-files");
> +	argv_array_push(&cp.args, "--recurse-submodules");
> +	cp.git_cmd = 1;
> +	cp.dir = ce->name;
> +	cp.out = -1;
> +	start_command(&cp);
> +	fp = fdopen(cp.out, "r");

You should error-check the result of start_command(). I guess the
reasonable outcome would be to die(), as it is a sign that we could not
fork, find git, etc.

Ditto for fdopen (you can use xfdopen for that).

> +	/*
> +	 * The ls-files child process produces filenames relative to
> +	 * the submodule. Prefix each line with the submodule path
> +	 * to make it relative to the current repository.
> +	 */
> +	strbuf_addstr(&name, ce->name);
> +	strbuf_addch(&name, '/');
> +	submodule_name_len = name.len;
> +	while (strbuf_getline(&buf, fp) != EOF) {
> +		strbuf_addbuf(&name, &buf);
> +		write_name(name.buf);
> +		strbuf_setlen(&name, submodule_name_len);
> +	}

What happens if the filename in the submodule needs quoting? You'll get
the quoted value in your buffer, and then re-quote it again in
write_name().

The simplest thing would probably be to use "ls-files -z" for the
recursive invocation, and then split on NUL bytes (we have
strbuf_getline_nul for that).

> +	finish_command(&cp);

What should happen if finish_command() tells us that the ls-files
sub-process reported an error? It may not be worth aborting the rest of
the listing, but we might want to propagate that in our own return code.

> +	strbuf_release(&buf);
> +	strbuf_release(&name);
> +	fclose(fp);
> +}

A minor style nit, but I would generally fclose(fp) before running
finish_command() (i.e., resource clean up in the reverse order of
allocation). It doesn't matter in this case because "fp" is output from
the process, and we know we've already read to EOF. For other cases, it
could cause a deadlock (e.g., we end up in wait() for the child process
to finish, but it is blocked in write() waiting for us to read). So I
think it's a good habit to get into.

> @@ -519,6 +566,17 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
>  	if (require_work_tree && !is_inside_work_tree())
>  		setup_work_tree();
>  
> +	if (recurse_submodules &&
> +	    (show_stage || show_deleted || show_others || show_unmerged ||
> +	     show_killed || show_modified || show_resolve_undo ||
> +	     show_valid_bit || show_tag || show_eol))
> +		die("ls-files --recurse-submodules can only be used in "
> +		    "--cached mode");

Woah, that list of variables is getting rather long. This is not a
problem introduced by your patch, so it's not a blocker. But I wonder if
some of them are mutually exclusive and could be collapsed to a single
variable.

I guess the reason for this "only with --cached" is that you do not
propagate the options down to the recursive process. If we were to do
that, then this big list of restrictions would go away. I'd be OK with
starting with more limited functionality like your patch, though. I
think doing the recursive thing correctly would also involve parsing the
output of each to append the filename prefix.

So I suppose another option would be to teach ls-files a "prefix" option
to add to each filename, and just pass in the submodule path. Then you
can let the sub-processes write directly to the common stdout, and I
think it would be safe to blindly pass the parent argv into the child
processes.

-Peff

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

* Re: [RFC/PATCH] ls-files: adding support for submodules
  2016-09-09 22:35 ` Jeff King
@ 2016-09-09 22:40   ` Junio C Hamano
  0 siblings, 0 replies; 22+ messages in thread
From: Junio C Hamano @ 2016-09-09 22:40 UTC (permalink / raw)
  To: Jeff King; +Cc: Brandon Williams, git

Jeff King <peff@peff.net> writes:

> So I suppose another option would be to teach ls-files a "prefix" option
> to add to each filename, and just pass in the submodule path. Then you
> can let the sub-processes write directly to the common stdout, and I
> think it would be safe to blindly pass the parent argv into the child
> processes.

I think that is a sensible way to do this, instead of reading from -z
and showing things depending on various output modes you were told
to use.

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

* Re: [RFC/PATCH] ls-files: adding support for submodules
  2016-09-09 21:53 [RFC/PATCH] ls-files: adding support for submodules Brandon Williams
  2016-09-09 22:35 ` Jeff King
@ 2016-09-09 23:01 ` Junio C Hamano
  2016-09-09 23:47   ` Stefan Beller
  2016-09-13  0:33 ` [PATCH v2] " Brandon Williams
  2 siblings, 1 reply; 22+ messages in thread
From: Junio C Hamano @ 2016-09-09 23:01 UTC (permalink / raw)
  To: Brandon Williams; +Cc: git

Brandon Williams <bmwill@google.com> writes:

> Allow ls-files to recognize submodules in order to retrieve a list of
> files from a repository's submodules.  This is done by forking off a
> process to recursively call ls-files on all submodules.

While I see why "ls-files --recurse-submodules" sounds nice ("hey, I
can get list of _all_ the files here"), and I am quite happy with
the quality of implementation (not just the code but its
documentation and test) especially from a first-time contributor, I
am not quite sure what the utility of this new feature would be,
especially given that the command is a plumbing, i.e. meant to be a
useful building block for scripts.

If I get

	$ git ls-files --recurse-submodules
	Makefile
        lib/Makefile
        lib/hello.py
	main.py
	goodbye.py

out of the command, what can I do with it without knowing where the
submodule boundaries are?  It's not like I can just do

	git ls-files --recurse-submodule |
        while read path
        do
        	git update-index --add "$path"
	done

when "lib/" is a submodule.  Instead, I'd need to go to "lib/" and
then add "Makefile" and "hello.py" from there.

> diff --git a/t/t3007-ls-files-recurse-submodules.sh b/t/t3007-ls-files-recurse-submodules.sh
> new file mode 100644
> index 0000000..78deded
> --- /dev/null
> +++ b/t/t3007-ls-files-recurse-submodules.sh
> @@ -0,0 +1,103 @@
> +...
> +test_expect_success 'setup directory structure and submodules' '
> +...
> +'
> +
> +cat >expect <<EOF
> +.gitmodules
> +a
> +b/b
> +submodule/c
> +EOF

We used to do that when we didn't know better.

Please don't do things outside test_expect_* block, especially in a
new script.

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

* Re: [RFC/PATCH] ls-files: adding support for submodules
  2016-09-09 23:01 ` Junio C Hamano
@ 2016-09-09 23:47   ` Stefan Beller
  2016-09-11 22:10     ` Junio C Hamano
  0 siblings, 1 reply; 22+ messages in thread
From: Stefan Beller @ 2016-09-09 23:47 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Brandon Williams, git@vger.kernel.org

On Fri, Sep 9, 2016 at 4:01 PM, Junio C Hamano <gitster@pobox.com> wrote:
> Brandon Williams <bmwill@google.com> writes:
>
>> Allow ls-files to recognize submodules in order to retrieve a list of
>> files from a repository's submodules.  This is done by forking off a
>> process to recursively call ls-files on all submodules.
>
> While I see why "ls-files --recurse-submodules" sounds nice ("hey, I
> can get list of _all_ the files here"), and I am quite happy with
> the quality of implementation (not just the code but its
> documentation and test)

The plan is to hook the ls-files machinery into
git-grep as the way of obtaining files to grep for a pattern.

As git-grep has a thread pool already, getting the list of files
single threaded  is more beneficial as e.g. calling git-grep recursively
for submodules, as then you may have a fork bomb.

>
>> diff --git a/t/t3007-ls-files-recurse-submodules.sh b/t/t3007-ls-files-recurse-submodules.sh

> We used to do that when we didn't know better.
>

Oops, a lot of stuff slipped through the first internal review.

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

* Re: [RFC/PATCH] ls-files: adding support for submodules
  2016-09-09 23:47   ` Stefan Beller
@ 2016-09-11 22:10     ` Junio C Hamano
  2016-09-12  0:51       ` Jeff King
  2016-09-12  1:47       ` Junio C Hamano
  0 siblings, 2 replies; 22+ messages in thread
From: Junio C Hamano @ 2016-09-11 22:10 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Brandon Williams, git@vger.kernel.org

Stefan Beller <sbeller@google.com> writes:

> The plan is to hook the ls-files machinery into
> git-grep as the way of obtaining files to grep for a pattern.

That does not make much sense to me for exactly the same reason why
the "grab the list of paths and run 'git add' on them" example in
the message you are responding to does not make sense.  The use of
the thread-pool would still need to honor the submodule boundary so
that one thread may be assigned files in the top-level superproject
while another may be assigned files in lib/ submodule repository,
and the latter would be doing a rough equivalent of "git -C lib
grep" perhaps with a new option "--output-path-prefix=lib/" that
makes any and all paths that are reported from the command prefixed
with the specified string, so the result of its grepping in Makefile
may be reported as findings in lib/Makefile.

For that, it is not sufficient for the enumeration of paths done in
the top-level to just list lib/Makefile and lib/hello.py along with
Makefile and main.py, is it?  You would somehow need to have a way
to tell that 'lib/' and everything in there is inside a separate
repository.  Without knowing that "lib/" is its own repository, you
would not even know which files under "lib/" hierarchy in the
filesystem are actually tracked files, which you would learn only by
reading lib/.git/index, or what textconv filtering needs to be done
on them, which you would learn only by reading lib/.gitattributes
and/or lib/.git/config.

So a "ls-files" that is done internally in the end-user facing "git
grep --recurse-submodules" needs to be run _without_ recursing
itself at least once to learn "lib/" is a submodule.  A flat "here
are everything we have" does not sound like a good building block.

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

* Re: [RFC/PATCH] ls-files: adding support for submodules
  2016-09-11 22:10     ` Junio C Hamano
@ 2016-09-12  0:51       ` Jeff King
  2016-09-12  0:52         ` Jeff King
  2016-09-12  1:47       ` Junio C Hamano
  1 sibling, 1 reply; 22+ messages in thread
From: Jeff King @ 2016-09-12  0:51 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Stefan Beller, Brandon Williams, git@vger.kernel.org

On Sun, Sep 11, 2016 at 03:10:13PM -0700, Junio C Hamano wrote:

> So a "ls-files" that is done internally in the end-user facing "git
> grep --recurse-submodules" needs to be run _without_ recursing
> itself at least once to learn "lib/" is a submodule.  A flat "here
> are everything we have" does not sound like a good building block.

I do not use submodules myself, but I could imagine that you may have
scripts outside of git that do not care about the submodule divisions at
all, and would be happy with the flat block. E.g., our "make tags"
target uses "git ls-files" so find all of the source files. I could
imagine projects with submodules that would want to do so recursively (I
could also imagine projects that do _not_ want to do so; it would depend
on your workflow and how tightly bound the submodules are). Another
plausible example would be something grep-like that has features
git-grep does not (I don't use "ack", but perhaps "git ls-files
--recurse-submodules -z | xargs --null ack ..." is something people
would want to do).

-Peff

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

* Re: [RFC/PATCH] ls-files: adding support for submodules
  2016-09-12  0:51       ` Jeff King
@ 2016-09-12  0:52         ` Jeff King
  2016-09-12 16:01           ` Junio C Hamano
  0 siblings, 1 reply; 22+ messages in thread
From: Jeff King @ 2016-09-12  0:52 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Stefan Beller, Brandon Williams, git@vger.kernel.org

On Sun, Sep 11, 2016 at 08:51:06PM -0400, Jeff King wrote:

> On Sun, Sep 11, 2016 at 03:10:13PM -0700, Junio C Hamano wrote:
> 
> > So a "ls-files" that is done internally in the end-user facing "git
> > grep --recurse-submodules" needs to be run _without_ recursing
> > itself at least once to learn "lib/" is a submodule.  A flat "here
> > are everything we have" does not sound like a good building block.
> 
> I do not use submodules myself, but I could imagine that you may have
> scripts outside of git that do not care about the submodule divisions at
> all, and would be happy with the flat block. E.g., our "make tags"
> target uses "git ls-files" so find all of the source files. I could
> imagine projects with submodules that would want to do so recursively (I
> could also imagine projects that do _not_ want to do so; it would depend
> on your workflow and how tightly bound the submodules are). Another
> plausible example would be something grep-like that has features
> git-grep does not (I don't use "ack", but perhaps "git ls-files
> --recurse-submodules -z | xargs --null ack ..." is something people
> would want to do).

None of that negates your point, btw, which is that this does not seem
like a great building block for "git grep --recurse-submodules". Just
that it seems plausible to me that people could find recursive
"ls-files" useful on its own.

-Peff

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

* Re: [RFC/PATCH] ls-files: adding support for submodules
  2016-09-11 22:10     ` Junio C Hamano
  2016-09-12  0:51       ` Jeff King
@ 2016-09-12  1:47       ` Junio C Hamano
  1 sibling, 0 replies; 22+ messages in thread
From: Junio C Hamano @ 2016-09-12  1:47 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Brandon Williams, git@vger.kernel.org

Junio C Hamano <gitster@pobox.com> writes:

> So a "ls-files" that is done internally in the end-user facing "git
> grep --recurse-submodules" needs to be run _without_ recursing
> itself at least once to learn "lib/" is a submodule.  A flat "here
> are everything we have" does not sound like a good building block.

... unless you are _only_ interested in grepping (or in general
working outside Git repository) in the files in the working tree,
i.e. "git grep" without <tree-ish> nor "--cached".

A lot of the time you are interested in the current state of files,
not even in "the state recorded in the tip of the history" but in
"the state as I have in my working tree, the state as my compiler
sees it".

I am a bit torn.  Clearly this is an important special case, but it
would make the codepath for object database case and working tree
case even further apart between "git grep [--cached | <tree-ish>]"
and the "find in the working tree" codepath, which does not sound
friendly to the codebase.


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

* Re: [RFC/PATCH] ls-files: adding support for submodules
  2016-09-12  0:52         ` Jeff King
@ 2016-09-12 16:01           ` Junio C Hamano
       [not found]             ` <CAKoko1oSEac_Nr1SkRB=dM_r3Jnew1Et2ZKj716iU3JLyHe2GQ@mail.gmail.com>
  0 siblings, 1 reply; 22+ messages in thread
From: Junio C Hamano @ 2016-09-12 16:01 UTC (permalink / raw)
  To: Jeff King; +Cc: Stefan Beller, Brandon Williams, git@vger.kernel.org

Jeff King <peff@peff.net> writes:

>> I do not use submodules myself, but I could imagine that you may have
>> scripts outside of git that do not care about the submodule divisions at
>> all, and would be happy with the flat block. ...
>> git-grep does not (I don't use "ack", but perhaps "git ls-files
>> --recurse-submodules -z | xargs --null ack ..." is something people
>> would want to do).
>
> None of that negates your point, btw, which is that this does not seem
> like a great building block for "git grep --recurse-submodules". Just
> that it seems plausible to me that people could find recursive
> "ls-files" useful on its own.

I do think it is a good argument why ls-files (with or without -z)
that recurses into submodules would help "git grep" that does not
look at the object store and does the search in the working tree
files that are tracked.  In normal Git world view, if you want a
list of files that are tracked, you are the one who is supposed to
go to the repository and look at the index there, but if you can
somehow magically get that list out-of-band, the "in the working
tree files" mode of "git grep" can work just like the "xargs -z ack"
pipeline in your example.

So I tend to agree that the enhancement in question is a useful
thing on its own, at least the part that gives a list of paths in
the index.

I do not know if all other operationg modes are useful, though.  For
eaxmple, the mode that lists untracked paths might be useful to do a
recursive "git clean".  On the other hand, "ls-files -s" with the
patch may produce the "correct" result (i.e. the object name given
for each path would be the same one that are found in the index of
the submodule the path was taken from), but the correctness may not
necessarily translate to usefulness, exactly because you need to
know which submodule's repository has the named object that is not
given by the flattened list.

Having to say that "this command produces correct result, but not
all correct things are necessarily useful" makes me wonder if that
is the direction in which we would want to go.  For example, what
would be our answer to an end-user question: I now know that the
recursive ls-files can give me all the untracked files in the
top-level and submodules.  How can I feed that to "git add" to
update their respective index files with them?

I am not convinced that we would always want to make "git add
lib/Makefile" to automagically run "git -C lib/ add Makefile" when
lib/ is a submodule (for that matter, even if we wanted to, I do not
know if that is something we can efficiently do with pathspecs that
have wildcards).

So...




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

* Re: [RFC/PATCH] ls-files: adding support for submodules
       [not found]             ` <CAKoko1oSEac_Nr1SkRB=dM_r3Jnew1Et2ZKj716iU3JLyHe2GQ@mail.gmail.com>
@ 2016-09-12 17:39               ` Brandon Williams
  0 siblings, 0 replies; 22+ messages in thread
From: Brandon Williams @ 2016-09-12 17:39 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Jeff King, Stefan Beller, git@vger.kernel.org

Thanks for all the comments.  What it sounds like is that using ls-files as
a means to power a recursive git-grep may not be like the best approach (I
assumed that would be the case but thought it a decent place to start).

I agree that not all operating modes would be useful for a recursive
ls-files, which is why I initially don't have support for them.  I guess
the question would be which modes would be worth supporting in a recursive
case?

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

* [PATCH v2] ls-files: adding support for submodules
  2016-09-09 21:53 [RFC/PATCH] ls-files: adding support for submodules Brandon Williams
  2016-09-09 22:35 ` Jeff King
  2016-09-09 23:01 ` Junio C Hamano
@ 2016-09-13  0:33 ` Brandon Williams
  2016-09-13  3:35   ` Brandon Williams
  2016-09-13 16:31   ` Junio C Hamano
  2 siblings, 2 replies; 22+ messages in thread
From: Brandon Williams @ 2016-09-13  0:33 UTC (permalink / raw)
  To: git; +Cc: Brandon Williams

Allow ls-files to recognize submodules in order to retrieve a list of
files from a repository's submodules.  This is done by forking off a
process to recursively call ls-files on all submodules. Also added an
output-path-prefix command in order to prepend paths to child processes.

Signed-off-by: Brandon Williams <bmwill@google.com>
---
 Documentation/git-ls-files.txt         | 11 +++-
 builtin/ls-files.c                     | 60 +++++++++++++++++++++
 t/t3007-ls-files-recurse-submodules.sh | 99 ++++++++++++++++++++++++++++++++++
 3 files changed, 169 insertions(+), 1 deletion(-)
 create mode 100755 t/t3007-ls-files-recurse-submodules.sh

diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index 0d933ac..a623ebf 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -18,7 +18,9 @@ SYNOPSIS
 		[--exclude-per-directory=<file>]
 		[--exclude-standard]
 		[--error-unmatch] [--with-tree=<tree-ish>]
-		[--full-name] [--abbrev] [--] [<file>...]
+		[--full-name] [--recurse-submodules]
+		[--output-path-prefix=<path>]
+		[--abbrev] [--] [<file>...]
 
 DESCRIPTION
 -----------
@@ -137,6 +139,13 @@ a space) at the start of each line:
 	option forces paths to be output relative to the project
 	top directory.
 
+--recurse-submodules::
+	Recursively calls ls-files on each submodule in the repository.
+	Currently there is only support for the --cached mode.
+
+--output-path-prefix=<path>::
+	Prepend the provided path to the output of each file
+
 --abbrev[=<n>]::
 	Instead of showing the full 40-byte hexadecimal object
 	lines, show only a partial prefix.
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 00ea91a..c0bce00 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -14,6 +14,7 @@
 #include "resolve-undo.h"
 #include "string-list.h"
 #include "pathspec.h"
+#include "run-command.h"
 
 static int abbrev;
 static int show_deleted;
@@ -28,6 +29,8 @@ static int show_valid_bit;
 static int line_terminator = '\n';
 static int debug_mode;
 static int show_eol;
+static const char *output_path_prefix = "";
+static int recurse_submodules;
 
 static const char *prefix;
 static int max_prefix_len;
@@ -68,6 +71,21 @@ static void write_eolinfo(const struct cache_entry *ce, const char *path)
 static void write_name(const char *name)
 {
 	/*
+	 * NEEDSWORK: To make this thread-safe, full_name would have to be owned
+	 * by the caller.
+	 *
+	 * full_name get reused across output lines to minimize the allocation
+	 * churn.
+	 */
+	static struct strbuf full_name = STRBUF_INIT;
+	if (output_path_prefix != '\0') {
+		strbuf_reset(&full_name);
+		strbuf_addstr(&full_name, output_path_prefix);
+		strbuf_addstr(&full_name, name);
+		name = full_name.buf;
+	}
+
+	/*
 	 * With "--full-name", prefix_len=0; this caller needs to pass
 	 * an empty string in that case (a NULL is good for "").
 	 */
@@ -152,6 +170,25 @@ static void show_killed_files(struct dir_struct *dir)
 	}
 }
 
+/**
+ * Recursively call ls-files on a submodule
+ */
+static void show_gitlink(const struct cache_entry *ce)
+{
+	struct child_process cp = CHILD_PROCESS_INIT;
+	int status;
+
+	argv_array_push(&cp.args, "ls-files");
+	argv_array_push(&cp.args, "--recurse-submodules");
+	argv_array_pushf(&cp.args, "--output-path-prefix=%s%s/",
+			 output_path_prefix, ce->name);
+	cp.git_cmd = 1;
+	cp.dir = ce->name;
+	status = run_command(&cp);
+	if (status)
+		exit(status);
+}
+
 static void show_ce_entry(const char *tag, const struct cache_entry *ce)
 {
 	int len = max_prefix_len;
@@ -163,6 +200,10 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce)
 			    len, ps_matched,
 			    S_ISDIR(ce->ce_mode) || S_ISGITLINK(ce->ce_mode)))
 		return;
+	if (recurse_submodules && S_ISGITLINK(ce->ce_mode)) {
+		show_gitlink(ce);
+		return;
+	}
 
 	if (tag && *tag && show_valid_bit &&
 	    (ce->ce_flags & CE_VALID)) {
@@ -468,6 +509,10 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 		{ OPTION_SET_INT, 0, "full-name", &prefix_len, NULL,
 			N_("make the output relative to the project top directory"),
 			PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL },
+		OPT_STRING(0, "output-path-prefix", &output_path_prefix,
+			N_("path"), N_("prepend <path> to each file")),
+		OPT_BOOL(0, "recurse-submodules", &recurse_submodules,
+			N_("recurse through submodules")),
 		OPT_BOOL(0, "error-unmatch", &error_unmatch,
 			N_("if any <file> is not in the index, treat this as an error")),
 		OPT_STRING(0, "with-tree", &with_tree, N_("tree-ish"),
@@ -519,6 +564,21 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 	if (require_work_tree && !is_inside_work_tree())
 		setup_work_tree();
 
+	if (recurse_submodules &&
+	    (show_stage || show_deleted || show_others || show_unmerged ||
+	     show_killed || show_modified || show_resolve_undo ||
+	     show_valid_bit || show_tag || show_eol))
+		die("ls-files --recurse-submodules can only be used in "
+		    "--cached mode");
+
+	if (recurse_submodules && error_unmatch)
+		die("ls-files --recurse-submodules does not support "
+		    "--error-unmatch");
+
+	if (recurse_submodules && argc)
+		die("ls-files --recurse-submodules does not support path "
+		    "arguments");
+
 	parse_pathspec(&pathspec, 0,
 		       PATHSPEC_PREFER_CWD |
 		       PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
diff --git a/t/t3007-ls-files-recurse-submodules.sh b/t/t3007-ls-files-recurse-submodules.sh
new file mode 100755
index 0000000..caf3815
--- /dev/null
+++ b/t/t3007-ls-files-recurse-submodules.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+
+test_description='Test ls-files recurse-submodules feature
+
+This test verifies the recurse-submodules feature correctly lists files from
+submodules.
+'
+
+. ./test-lib.sh
+
+test_expect_success 'setup directory structure and submodules' '
+	echo a >a &&
+	mkdir b &&
+	echo b >b/b &&
+	git add a b &&
+	git commit -m "add a and b" &&
+	git init submodule &&
+	echo c >submodule/c &&
+	git -C submodule add c &&
+	git -C submodule commit -m "add c" &&
+	git submodule add ./submodule &&
+	git commit -m "added submodule"
+'
+
+test_expect_success 'ls-files correctly outputs files in submodule' '
+	cat >expect <<-\EOF &&
+	.gitmodules
+	a
+	b/b
+	submodule/c
+	EOF
+
+	git ls-files --recurse-submodules >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'ls-files does not output files not added to a repo' '
+	cat >expect <<-\EOF &&
+	.gitmodules
+	a
+	b/b
+	submodule/c
+	EOF
+
+	echo a >not_added &&
+	echo b >b/not_added &&
+	echo c >submodule/not_added &&
+	git ls-files --recurse-submodules >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'ls-files recurses more than 1 level' '
+	cat >expect <<-\EOF &&
+	.gitmodules
+	a
+	b/b
+	submodule/.gitmodules
+	submodule/c
+	submodule/subsub/d
+	EOF
+
+	git init submodule/subsub &&
+	echo d >submodule/subsub/d &&
+	git -C submodule/subsub add d &&
+	git -C submodule/subsub commit -m "add d" &&
+	git -C submodule submodule add ./subsub &&
+	git -C submodule commit -m "added subsub" &&
+	git ls-files --recurse-submodules >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '--recurse-submodules does not support using path arguments' '
+	test_must_fail git ls-files --recurse-submodules b 2>actual &&
+	test_i18ngrep "does not support path arguments" actual
+'
+
+test_expect_success '--recurse-submodules does not support --error-unmatch' '
+	test_must_fail git ls-files --recurse-submodules --error-unmatch 2>actual &&
+	test_i18ngrep "does not support --error-unmatch" actual
+'
+
+test_incompatible_with_recurse_submodules () {
+	test_expect_success "--recurse-submodules and $1 are incompatible" "
+		test_must_fail git ls-files --recurse-submodules $1 2>actual &&
+		test_i18ngrep 'can only be used in --cached mode' actual
+	"
+}
+
+test_incompatible_with_recurse_submodules -v
+test_incompatible_with_recurse_submodules -t
+test_incompatible_with_recurse_submodules --deleted
+test_incompatible_with_recurse_submodules --modified
+test_incompatible_with_recurse_submodules --others
+test_incompatible_with_recurse_submodules --stage
+test_incompatible_with_recurse_submodules --killed
+test_incompatible_with_recurse_submodules --unmerged
+test_incompatible_with_recurse_submodules --eol
+
+test_done
-- 
2.8.0.rc3.226.g39d4020


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

* Re: [PATCH v2] ls-files: adding support for submodules
  2016-09-13  0:33 ` [PATCH v2] " Brandon Williams
@ 2016-09-13  3:35   ` Brandon Williams
  2016-09-13 16:31   ` Junio C Hamano
  1 sibling, 0 replies; 22+ messages in thread
From: Brandon Williams @ 2016-09-13  3:35 UTC (permalink / raw)
  To: git; +Cc: Brandon Williams

>  static void write_name(const char *name)
>  {
>         /*
> +        * NEEDSWORK: To make this thread-safe, full_name would have to be owned
> +        * by the caller.
> +        *
> +        * full_name get reused across output lines to minimize the allocation
> +        * churn.
> +        */
> +       static struct strbuf full_name = STRBUF_INIT;
> +       if (output_path_prefix != '\0') {

It was pointed out to me that this should be:
    if (*output_path_prefix != '\0') {


> +               strbuf_reset(&full_name);
> +               strbuf_addstr(&full_name, output_path_prefix);
> +               strbuf_addstr(&full_name, name);
> +               name = full_name.buf;
> +       }

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

* Re: [PATCH v2] ls-files: adding support for submodules
  2016-09-13  0:33 ` [PATCH v2] " Brandon Williams
  2016-09-13  3:35   ` Brandon Williams
@ 2016-09-13 16:31   ` Junio C Hamano
  2016-09-15 20:51     ` Junio C Hamano
                       ` (3 more replies)
  1 sibling, 4 replies; 22+ messages in thread
From: Junio C Hamano @ 2016-09-13 16:31 UTC (permalink / raw)
  To: Brandon Williams; +Cc: git

Brandon Williams <bmwill@google.com> writes:

> Allow ls-files to recognize submodules in order to retrieve a list of
> files from a repository's submodules.  This is done by forking off a
> process to recursively call ls-files on all submodules. Also added an
> output-path-prefix command in order to prepend paths to child processes.
>
> Signed-off-by: Brandon Williams <bmwill@google.com>

> @@ -68,6 +71,21 @@ static void write_eolinfo(const struct cache_entry *ce, const char *path)
>  static void write_name(const char *name)
>  {
>  	/*
> +	 * NEEDSWORK: To make this thread-safe, full_name would have to be owned
> +	 * by the caller.
> +	 *
> +	 * full_name get reused across output lines to minimize the allocation
> +	 * churn.
> +	 */
> +	static struct strbuf full_name = STRBUF_INIT;
> +	if (output_path_prefix != '\0') {
> +		strbuf_reset(&full_name);
> +		strbuf_addstr(&full_name, output_path_prefix);
> +		strbuf_addstr(&full_name, name);
> +		name = full_name.buf;
> +	}

At first glance it was surprising that no test caught this lack of
dereference; the reason is because you initialize output_path_prefix
to an empty string, not NULL, causing full_name.buf always used,
which does not have an impact on the output.

I think initializing it to NULL is a more typical way to say "this
option has not been given", and if you took that route, the
condition would become

	if (output_path_prefix && *output_path_prefix) {
        	...

In any case, the fact that only this much change was required to add
output-path-prefix shows two good things: (1) the original code was
already well structured, funneling any pathname we need to emit
through this single function so that we can do this kind of updates,
and (2) the author of the patch was competent to spot this single
point that needs to be updated.

Nice.

> +	status = run_command(&cp);
> +	if (status)
> +		exit(status);

run_command()'s return value comes from either start_command() or
finish_command().  These signal failure by returning a non-zero
value, and in practice they are negative small integers.  Feeding
negative value to exit() is not quite kosher.  Perhaps exit(128)
to mimick as if we called die() is better.

If your primary interest is to support the "find in the working tree
files that are tracked, recursively in submodules" grep, I think
this "when we hit a submodule, spawn a separate ls-files in there"
is sufficient and a solid base to build on it.

On the other hand, if you are more ambitious and "grep" is merely an
example of things that can be helped by having a list of paths
across module boundaries, we may want to "libify" ls-files in such a
way that a single process can instantiate one or more instances of
"ls-files machinery", that takes which repository to work in and
other arguments that specifies which paths to report, and instead of
always showing the result to the standard output, makes repeated
calls to a callback function to report the discovered path and other
attributes associated with the path that were asked for (the object
name, values of tag_*, etc.), without spawning a separate "ls-files"
process.

The latter would be a lot bigger task and I do not necessarily think
it is needed, but that is one possible future direction to keep in
mind.

Thanks, will queue with a minimum fix.

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

* Re: [PATCH v2] ls-files: adding support for submodules
  2016-09-13 16:31   ` Junio C Hamano
@ 2016-09-15 20:51     ` Junio C Hamano
  2016-09-15 20:51       ` [PATCH 1/2] SQUASH??? Junio C Hamano
  2016-09-15 20:51       ` [PATCH 2/2] SQUASH??? Undecided Junio C Hamano
  2016-09-15 20:57     ` [PATCH v2] ls-files: adding support for submodules Junio C Hamano
                       ` (2 subsequent siblings)
  3 siblings, 2 replies; 22+ messages in thread
From: Junio C Hamano @ 2016-09-15 20:51 UTC (permalink / raw)
  To: git

Junio C Hamano <gitster@pobox.com> writes:

> Thanks, will queue with a minimum fix.

So here are two squashable patches, one is the "minimum" one, the
other is a bit more invasive one to use "a pointer to an optional
setting is set to NULL" convention.  I am undecided, and I'll stay
to be without further comments from others, on the latter one.

I understand that many internal changes in your work environment
titles their changes like "DOing X", but our convention around here
is to label them "DO X", as if you are giving an order to somebody
else, either telling the codebase "to be like so", or telling the
patch-monkey maintainer "to make it so".  So I'd retitle it

	ls-files: optionally recurse into submodules

or something like that.  It is an added advantage of being a lot
more descriptive than "adding support", which does not say what kind
of support it is adding.

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

* [PATCH 1/2] SQUASH???
  2016-09-15 20:51     ` Junio C Hamano
@ 2016-09-15 20:51       ` Junio C Hamano
  2016-09-15 20:51       ` [PATCH 2/2] SQUASH??? Undecided Junio C Hamano
  1 sibling, 0 replies; 22+ messages in thread
From: Junio C Hamano @ 2016-09-15 20:51 UTC (permalink / raw)
  To: git

---
 builtin/ls-files.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index c0bce00..6e78c71 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -78,7 +78,7 @@ static void write_name(const char *name)
 	 * churn.
 	 */
 	static struct strbuf full_name = STRBUF_INIT;
-	if (output_path_prefix != '\0') {
+	if (*output_path_prefix) {
 		strbuf_reset(&full_name);
 		strbuf_addstr(&full_name, output_path_prefix);
 		strbuf_addstr(&full_name, name);
-- 
2.10.0-458-g97b4043


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

* [PATCH 2/2] SQUASH???  Undecided
  2016-09-15 20:51     ` Junio C Hamano
  2016-09-15 20:51       ` [PATCH 1/2] SQUASH??? Junio C Hamano
@ 2016-09-15 20:51       ` Junio C Hamano
  2016-09-15 21:12         ` Stefan Beller
  1 sibling, 1 reply; 22+ messages in thread
From: Junio C Hamano @ 2016-09-15 20:51 UTC (permalink / raw)
  To: git

If we were to follow the convention to leave an optional string
variable to NULL, we'd need to do this on top.  I am not sure if it
is a good change, though.
---
 builtin/ls-files.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 6e78c71..687e475 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -29,7 +29,7 @@ static int show_valid_bit;
 static int line_terminator = '\n';
 static int debug_mode;
 static int show_eol;
-static const char *output_path_prefix = "";
+static const char *output_path_prefix;
 static int recurse_submodules;
 
 static const char *prefix;
@@ -78,7 +78,7 @@ static void write_name(const char *name)
 	 * churn.
 	 */
 	static struct strbuf full_name = STRBUF_INIT;
-	if (*output_path_prefix) {
+	if (output_path_prefix && *output_path_prefix) {
 		strbuf_reset(&full_name);
 		strbuf_addstr(&full_name, output_path_prefix);
 		strbuf_addstr(&full_name, name);
@@ -181,7 +181,8 @@ static void show_gitlink(const struct cache_entry *ce)
 	argv_array_push(&cp.args, "ls-files");
 	argv_array_push(&cp.args, "--recurse-submodules");
 	argv_array_pushf(&cp.args, "--output-path-prefix=%s%s/",
-			 output_path_prefix, ce->name);
+			 output_path_prefix ? output_path_prefix : "",
+			 ce->name);
 	cp.git_cmd = 1;
 	cp.dir = ce->name;
 	status = run_command(&cp);
-- 
2.10.0-458-g97b4043


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

* Re: [PATCH v2] ls-files: adding support for submodules
  2016-09-13 16:31   ` Junio C Hamano
  2016-09-15 20:51     ` Junio C Hamano
@ 2016-09-15 20:57     ` Junio C Hamano
  2016-09-15 20:58     ` Junio C Hamano
  2016-09-15 20:58     ` Junio C Hamano
  3 siblings, 0 replies; 22+ messages in thread
From: Junio C Hamano @ 2016-09-15 20:57 UTC (permalink / raw)
  To: Brandon Williams; +Cc: git

Junio C Hamano <gitster@pobox.com> writes:

> Thanks, will queue with a minimum fix.

So here are two squashable patches, one is the "minimum" one, the
other is a bit more invasive one to use "a pointer to an optional
setting is set to NULL" convention.  I am undecided, and I'll stay
to be without further comments from others, on the latter one.

I understand that many internal changes in your work environment are
titled like "DOing X", but our convention around here is to label
them "DO X", as if you are giving an order to somebody else, either
telling the codebase "to be like so", or telling the patch-monkey
maintainer "to make it so".  So I'd retitle it

	ls-files: optionally recurse into submodules

or something like that.  It is an added advantage of being a lot
more descriptive than "adding support", which does not say what kind
of support it is adding.

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

* Re: [PATCH v2] ls-files: adding support for submodules
  2016-09-13 16:31   ` Junio C Hamano
  2016-09-15 20:51     ` Junio C Hamano
  2016-09-15 20:57     ` [PATCH v2] ls-files: adding support for submodules Junio C Hamano
@ 2016-09-15 20:58     ` Junio C Hamano
  2016-09-15 20:58     ` Junio C Hamano
  3 siblings, 0 replies; 22+ messages in thread
From: Junio C Hamano @ 2016-09-15 20:58 UTC (permalink / raw)
  To: Brandon Williams; +Cc: git

Here is an absolute mininum fix ;-)

 builtin/ls-files.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index c0bce00..6e78c71 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -78,7 +78,7 @@ static void write_name(const char *name)
 	 * churn.
 	 */
 	static struct strbuf full_name = STRBUF_INIT;
-	if (output_path_prefix != '\0') {
+	if (*output_path_prefix) {
 		strbuf_reset(&full_name);
 		strbuf_addstr(&full_name, output_path_prefix);
 		strbuf_addstr(&full_name, name);
-- 
2.10.0-458-g97b4043


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

* Re: [PATCH v2] ls-files: adding support for submodules
  2016-09-13 16:31   ` Junio C Hamano
                       ` (2 preceding siblings ...)
  2016-09-15 20:58     ` Junio C Hamano
@ 2016-09-15 20:58     ` Junio C Hamano
  3 siblings, 0 replies; 22+ messages in thread
From: Junio C Hamano @ 2016-09-15 20:58 UTC (permalink / raw)
  To: Brandon Williams; +Cc: git

If we were to follow the convention to leave an optional string
variable to NULL, we'd need to do this on top.  I am not sure if it
is a good change, though.
---
 builtin/ls-files.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 6e78c71..687e475 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -29,7 +29,7 @@ static int show_valid_bit;
 static int line_terminator = '\n';
 static int debug_mode;
 static int show_eol;
-static const char *output_path_prefix = "";
+static const char *output_path_prefix;
 static int recurse_submodules;
 
 static const char *prefix;
@@ -78,7 +78,7 @@ static void write_name(const char *name)
 	 * churn.
 	 */
 	static struct strbuf full_name = STRBUF_INIT;
-	if (*output_path_prefix) {
+	if (output_path_prefix && *output_path_prefix) {
 		strbuf_reset(&full_name);
 		strbuf_addstr(&full_name, output_path_prefix);
 		strbuf_addstr(&full_name, name);
@@ -181,7 +181,8 @@ static void show_gitlink(const struct cache_entry *ce)
 	argv_array_push(&cp.args, "ls-files");
 	argv_array_push(&cp.args, "--recurse-submodules");
 	argv_array_pushf(&cp.args, "--output-path-prefix=%s%s/",
-			 output_path_prefix, ce->name);
+			 output_path_prefix ? output_path_prefix : "",
+			 ce->name);
 	cp.git_cmd = 1;
 	cp.dir = ce->name;
 	status = run_command(&cp);
-- 
2.10.0-458-g97b4043


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

* Re: [PATCH 2/2] SQUASH??? Undecided
  2016-09-15 20:51       ` [PATCH 2/2] SQUASH??? Undecided Junio C Hamano
@ 2016-09-15 21:12         ` Stefan Beller
  2016-09-15 21:37           ` Brandon Williams
  0 siblings, 1 reply; 22+ messages in thread
From: Stefan Beller @ 2016-09-15 21:12 UTC (permalink / raw)
  To: Junio C Hamano, Brandon Williams; +Cc: git@vger.kernel.org

+ cc Brandon

On Thu, Sep 15, 2016 at 1:51 PM, Junio C Hamano <gitster@pobox.com> wrote:
> If we were to follow the convention to leave an optional string
> variable to NULL, we'd need to do this on top.  I am not sure if it
> is a good change, though.

I think it is a good change.

Thanks,
Stefan

> ---
>  builtin/ls-files.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/builtin/ls-files.c b/builtin/ls-files.c
> index 6e78c71..687e475 100644
> --- a/builtin/ls-files.c
> +++ b/builtin/ls-files.c
> @@ -29,7 +29,7 @@ static int show_valid_bit;
>  static int line_terminator = '\n';
>  static int debug_mode;
>  static int show_eol;
> -static const char *output_path_prefix = "";
> +static const char *output_path_prefix;
>  static int recurse_submodules;
>
>  static const char *prefix;
> @@ -78,7 +78,7 @@ static void write_name(const char *name)
>          * churn.
>          */
>         static struct strbuf full_name = STRBUF_INIT;
> -       if (*output_path_prefix) {
> +       if (output_path_prefix && *output_path_prefix) {
>                 strbuf_reset(&full_name);
>                 strbuf_addstr(&full_name, output_path_prefix);
>                 strbuf_addstr(&full_name, name);
> @@ -181,7 +181,8 @@ static void show_gitlink(const struct cache_entry *ce)
>         argv_array_push(&cp.args, "ls-files");
>         argv_array_push(&cp.args, "--recurse-submodules");
>         argv_array_pushf(&cp.args, "--output-path-prefix=%s%s/",
> -                        output_path_prefix, ce->name);
> +                        output_path_prefix ? output_path_prefix : "",
> +                        ce->name);
>         cp.git_cmd = 1;
>         cp.dir = ce->name;
>         status = run_command(&cp);
> --
> 2.10.0-458-g97b4043
>

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

* Re: [PATCH 2/2] SQUASH??? Undecided
  2016-09-15 21:12         ` Stefan Beller
@ 2016-09-15 21:37           ` Brandon Williams
  0 siblings, 0 replies; 22+ messages in thread
From: Brandon Williams @ 2016-09-15 21:37 UTC (permalink / raw)
  To: Stefan Beller; +Cc: Junio C Hamano, git@vger.kernel.org

Yeah if that is the convention then I have no problem with the change.

-Brandon

On Thu, Sep 15, 2016 at 2:12 PM, Stefan Beller <sbeller@google.com> wrote:
> + cc Brandon
>
> On Thu, Sep 15, 2016 at 1:51 PM, Junio C Hamano <gitster@pobox.com> wrote:
>> If we were to follow the convention to leave an optional string
>> variable to NULL, we'd need to do this on top.  I am not sure if it
>> is a good change, though.
>
> I think it is a good change.
>
> Thanks,
> Stefan
>
>> ---
>>  builtin/ls-files.c | 7 ++++---
>>  1 file changed, 4 insertions(+), 3 deletions(-)
>>
>> diff --git a/builtin/ls-files.c b/builtin/ls-files.c
>> index 6e78c71..687e475 100644
>> --- a/builtin/ls-files.c
>> +++ b/builtin/ls-files.c
>> @@ -29,7 +29,7 @@ static int show_valid_bit;
>>  static int line_terminator = '\n';
>>  static int debug_mode;
>>  static int show_eol;
>> -static const char *output_path_prefix = "";
>> +static const char *output_path_prefix;
>>  static int recurse_submodules;
>>
>>  static const char *prefix;
>> @@ -78,7 +78,7 @@ static void write_name(const char *name)
>>          * churn.
>>          */
>>         static struct strbuf full_name = STRBUF_INIT;
>> -       if (*output_path_prefix) {
>> +       if (output_path_prefix && *output_path_prefix) {
>>                 strbuf_reset(&full_name);
>>                 strbuf_addstr(&full_name, output_path_prefix);
>>                 strbuf_addstr(&full_name, name);
>> @@ -181,7 +181,8 @@ static void show_gitlink(const struct cache_entry *ce)
>>         argv_array_push(&cp.args, "ls-files");
>>         argv_array_push(&cp.args, "--recurse-submodules");
>>         argv_array_pushf(&cp.args, "--output-path-prefix=%s%s/",
>> -                        output_path_prefix, ce->name);
>> +                        output_path_prefix ? output_path_prefix : "",
>> +                        ce->name);
>>         cp.git_cmd = 1;
>>         cp.dir = ce->name;
>>         status = run_command(&cp);
>> --
>> 2.10.0-458-g97b4043
>>

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

end of thread, other threads:[~2016-09-15 21:37 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-09 21:53 [RFC/PATCH] ls-files: adding support for submodules Brandon Williams
2016-09-09 22:35 ` Jeff King
2016-09-09 22:40   ` Junio C Hamano
2016-09-09 23:01 ` Junio C Hamano
2016-09-09 23:47   ` Stefan Beller
2016-09-11 22:10     ` Junio C Hamano
2016-09-12  0:51       ` Jeff King
2016-09-12  0:52         ` Jeff King
2016-09-12 16:01           ` Junio C Hamano
     [not found]             ` <CAKoko1oSEac_Nr1SkRB=dM_r3Jnew1Et2ZKj716iU3JLyHe2GQ@mail.gmail.com>
2016-09-12 17:39               ` Brandon Williams
2016-09-12  1:47       ` Junio C Hamano
2016-09-13  0:33 ` [PATCH v2] " Brandon Williams
2016-09-13  3:35   ` Brandon Williams
2016-09-13 16:31   ` Junio C Hamano
2016-09-15 20:51     ` Junio C Hamano
2016-09-15 20:51       ` [PATCH 1/2] SQUASH??? Junio C Hamano
2016-09-15 20:51       ` [PATCH 2/2] SQUASH??? Undecided Junio C Hamano
2016-09-15 21:12         ` Stefan Beller
2016-09-15 21:37           ` Brandon Williams
2016-09-15 20:57     ` [PATCH v2] ls-files: adding support for submodules Junio C Hamano
2016-09-15 20:58     ` Junio C Hamano
2016-09-15 20:58     ` Junio C Hamano

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).