[PATCH 0/3] Bringing git-ls-files to porcelain level

STALE3735d

8 messages, 2 authors, 2016-06-15 · open the first message on its own page

[PATCH 0/3] Bringing git-ls-files to porcelain level

From: Nguyễn Thái Ngọc Duy <hidden>
Date: 2016-06-15 22:47:58

This is a hack, to scratch my itch. These patches add "git ls",
which is equivalent to "git ls-files --max-depth 1|column"

Anyone up for coloring? ;)

Nguyễn Thái Ngọc Duy (3):
  ls-files: support --max-depth
  ls-files: support -o --max-depth (more of a hack as fill_directory
    should support this)
  Add "ls", which is basically ls-files with user-friendly settings

 builtin-ls-files.c |   72 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 builtin.h          |    1 +
 git.c              |    1 +
 3 files changed, 74 insertions(+), 0 deletions(-)

[PATCH 1/3] ls-files: support --max-depth

From: Nguyễn Thái Ngọc Duy <hidden>
Date: 2016-06-15 22:47:58

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
 builtin-ls-files.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 7382157..2bb851a 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -30,6 +30,7 @@ static int error_unmatch;
 static char *ps_matched;
 static const char *with_tree;
 static int exc_given;
+static int max_depth = 0;
 
 static const char *tag_cached = "";
 static const char *tag_unmerged = "";
@@ -232,6 +233,30 @@ static void prune_cache(const char *prefix)
 	active_nr = last;
 }
 
+/*
+ * It is assumed that prune_cache() as been called before this
+ */
+static void prune_cache_by_depth(const char *prefix, int max_depth)
+{
+	int i = active_nr-1;
+
+	while (i >= 0) {
+		int slashes = 0;
+		const char *entry = active_cache[i]->name + prefix_len;
+		while ((entry = strchr(entry, '/')) != NULL) {
+			slashes++;
+			if (slashes >= max_depth) {
+				memmove(active_cache + i, active_cache + i + 1,
+					(active_nr - i - 1) * sizeof(struct cache_entry *));
+				active_nr--;
+				break;
+			}
+			entry++;
+		}
+		i--;
+	}
+}
+
 static const char *verify_pathspec(const char *prefix)
 {
 	const char **p, *n, *prev;
@@ -476,6 +501,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 			"if any <file> is not in the index, treat this as an error"),
 		OPT_STRING(0, "with-tree", &with_tree, "tree-ish",
 			"pretend that paths removed since <tree-ish> are still present"),
+		OPT_INTEGER(0, "max-depth", &max_depth, "max recursive depth"),
 		OPT__ABBREV(&abbrev),
 		OPT_END()
 	};
@@ -541,6 +567,10 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 
 	if (prefix)
 		prune_cache(prefix);
+
+	if (max_depth)
+		prune_cache_by_depth(prefix, max_depth);
+
 	if (with_tree) {
 		/*
 		 * Basic sanity check; show-stages and show-unmerged
-- 
1.6.6.315.g1a406

[PATCH 2/3] ls-files: support -o --max-depth (more of a hack as fill_directory should support this)

From: Nguyễn Thái Ngọc Duy <hidden>
Date: 2016-06-15 22:47:58

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
 builtin-ls-files.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index 2bb851a..e16638e 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -51,6 +51,17 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)
 	if (!match_pathspec(pathspec, ent->name, ent->len, len, ps_matched))
 		return;
 
+	if (max_depth) {
+		int slashes = 0;
+		const char *entry = ent->name + prefix_offset;
+		while ((entry = strchr(entry, '/')) != NULL) {
+			slashes++;
+			if (slashes >= max_depth)
+				return;
+			entry++;
+		}
+	}
+
 	fputs(tag, stdout);
 	write_name_quoted(ent->name + offset, stdout, line_terminator);
 }
-- 
1.6.6.315.g1a406

[PATCH 3/3] Add "ls", which is basically ls-files with user-friendly settings

From: Nguyễn Thái Ngọc Duy <hidden>
Date: 2016-06-15 22:47:58

Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
 builtin-ls-files.c |   31 +++++++++++++++++++++++++++++++
 builtin.h          |    1 +
 git.c              |    1 +
 3 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index e16638e..f63b039 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -11,6 +11,7 @@
 #include "builtin.h"
 #include "tree.h"
 #include "parse-options.h"
+#include "run-command.h"
 
 static int abbrev;
 static int show_deleted;
@@ -31,6 +32,7 @@ static char *ps_matched;
 static const char *with_tree;
 static int exc_given;
 static int max_depth = 0;
+static int show_colums = 0;
 
 static const char *tag_cached = "";
 static const char *tag_unmerged = "";
@@ -461,6 +463,7 @@ static int option_parse_exclude_standard(const struct option *opt,
 
 int cmd_ls_files(int argc, const char **argv, const char *prefix)
 {
+	struct child_process cp;
 	int require_work_tree = 0, show_tag = 0;
 	struct dir_struct dir;
 	struct option builtin_ls_files_options[] = {
@@ -513,6 +516,7 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 		OPT_STRING(0, "with-tree", &with_tree, "tree-ish",
 			"pretend that paths removed since <tree-ish> are still present"),
 		OPT_INTEGER(0, "max-depth", &max_depth, "max recursive depth"),
+		OPT_BOOLEAN(0, "columns", &show_colums, "show in columns"),
 		OPT__ABBREV(&abbrev),
 		OPT_END()
 	};
@@ -591,6 +595,20 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 			die("ls-files --with-tree is incompatible with -s or -u");
 		overlay_tree_on_cache(with_tree, prefix);
 	}
+
+	if (show_colums) {
+		const char *argv[] = { "column", NULL };
+
+		memset(&cp, 0, sizeof(cp));
+		cp.in = -1;
+		cp.out = dup(1);
+		cp.argv = argv;
+		start_command(&cp);
+		close(1);
+		dup2(cp.in, 1);
+		close(cp.in);
+	}
+
 	show_files(&dir, prefix);
 
 	if (ps_matched) {
@@ -602,5 +620,18 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
 		return bad ? 1 : 0;
 	}
 
+	if (show_colums) {
+		fflush(stdout);
+		close(1);
+		finish_command(&cp);
+	}
+
 	return 0;
 }
+
+int cmd_ls(int argc, const char **argv, const char *prefix)
+{
+	max_depth = 1;
+	show_colums = 1;
+	return cmd_ls_files(argc, argv, prefix);
+}
diff --git a/builtin.h b/builtin.h
index c3f83c0..d8980e5 100644
--- a/builtin.h
+++ b/builtin.h
@@ -61,6 +61,7 @@ extern int cmd_init_db(int argc, const char **argv, const char *prefix);
 extern int cmd_log(int argc, const char **argv, const char *prefix);
 extern int cmd_log_reflog(int argc, const char **argv, const char *prefix);
 extern int cmd_ls_files(int argc, const char **argv, const char *prefix);
+extern int cmd_ls(int argc, const char **argv, const char *prefix);
 extern int cmd_ls_tree(int argc, const char **argv, const char *prefix);
 extern int cmd_ls_remote(int argc, const char **argv, const char *prefix);
 extern int cmd_mailinfo(int argc, const char **argv, const char *prefix);
diff --git a/git.c b/git.c
index 11544cd..4aff5ec 100644
--- a/git.c
+++ b/git.c
@@ -323,6 +323,7 @@ static void handle_internal_command(int argc, const char **argv)
 		{ "init-db", cmd_init_db },
 		{ "log", cmd_log, RUN_SETUP | USE_PAGER },
 		{ "ls-files", cmd_ls_files, RUN_SETUP },
+		{ "ls", cmd_ls, RUN_SETUP },
 		{ "ls-tree", cmd_ls_tree, RUN_SETUP },
 		{ "ls-remote", cmd_ls_remote },
 		{ "mailinfo", cmd_mailinfo },
-- 
1.6.6.315.g1a406

Re: [PATCH 2/3] ls-files: support -o --max-depth (more of a hack as fill_directory should support this)

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:47:59

Nguyễn Thái Ngọc Duy  [off-list ref] writes:
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
Subject: Re: [PATCH 2/3] ls-files: support -o --max-depth (more of a hack
as fill_directory should support this)

Perhaps you would want to look at how builtin_grep()'s walker and the
walker in dir.c can be consolidated?  The former has support for
max_depth.

Re: [PATCH 3/3] Add "ls", which is basically ls-files with user-friendly settings

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:47:59

Nguyễn Thái Ngọc Duy  [off-list ref] writes:
+
+	if (show_colums) {
+		const char *argv[] = { "column", NULL };
+
+		memset(&cp, 0, sizeof(cp));
+		cp.in = -1;
+		cp.out = dup(1);
+		cp.argv = argv;
+		start_command(&cp);
+		close(1);
+		dup2(cp.in, 1);
+		close(cp.in);
+	}
I think the code for columnar output used in producing "git help -a"
output should be reusable (if not, should be made reusable and reused
here).

Re: [PATCH 3/3] Add "ls", which is basically ls-files with user-friendly settings

From: Nguyen Thai Ngoc Duy <hidden>
Date: 2016-06-15 22:47:59

On 1/8/10, Junio C Hamano [off-list ref] wrote:
Nguyễn Thái Ngọc Duy  [off-list ref] writes:

 > +
 > +     if (show_colums) {
 > +             const char *argv[] = { "column", NULL };
 > +
 > +             memset(&cp, 0, sizeof(cp));
 > +             cp.in = -1;
 > +             cp.out = dup(1);
 > +             cp.argv = argv;
 > +             start_command(&cp);
 > +             close(1);
 > +             dup2(cp.in, 1);
 > +             close(cp.in);
 > +     }


I think the code for columnar output used in producing "git help -a"
 output should be reusable (if not, should be made reusable and reused
 here).
I saw that and even exported term_columns() but was too lazy to make
pretty_print_string_list() something reusable. Will think of it again
when I see this command is worth pushing forward.
-- 
Duy

Re: [PATCH 3/3] Add "ls", which is basically ls-files with user-friendly settings

From: Nguyen Thai Ngoc Duy <hidden>
Date: 2016-06-15 22:47:59

On 1/8/10, Nguyen Thai Ngoc Duy [off-list ref] wrote:
On 1/8/10, Junio C Hamano [off-list ref] wrote:
 > I think the code for columnar output used in producing "git help -a"
 >  output should be reusable (if not, should be made reusable and reused
 >  here).


I saw that and even exported term_columns() but was too lazy to make
 pretty_print_string_list() something reusable. Will think of it again
 when I see this command is worth pushing forward.
I think again. There are a few places that may benefit from column
display: git tag -l, git grep -l, git branch (if you have lots of
branches) and probably untracked part of "git status". Moreover, I
have to implement it anyway because Solaris does not have command
"column". How about an external "git-column"? This way we don't have
to modify lots of code for columnized output. We may want to name it
"git-pager" if we want an internal pager someday ;)
-- 
Duy
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help