git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 13/16] ls: add --recursive and turn default to non-recursive mode

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Feb 9, 2011, 12:24 UTC
Message-ID
<1297254284-3729-14-git-send-email-pclouds@gmail.com>
In-Reply-To
<1297254284-3729-1-git-send-email-pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 This patch should be after 14/16. Otherwise the requirement in path_too_deep()
 is just wrong. Too late to reorder the series for sending.
 builtin/ls-files.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 3195f75..87ee728 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -27,6 +27,7 @@ static int show_killed;
 static int show_valid_bit;
 static int line_terminator = '\n';
 static int debug_mode;
+static int depth_limit;
 
 static const char *prefix;
 static int max_prefix_len;
@@ -63,18 +64,54 @@ static void write_name(const char* name, size_t len)
 			line_terminator);
 }
 
+static const char *path_too_deep(const char *name)
+{
+	int common = 0;
+	if (!depth_limit)
+		return NULL;
+
+	/* When depth_limit is set, pathspec contains exactly 1 item */
+	while (name[common] &&
+	       name[common] == pathspec[0][common])
+		common++;
+	while (common && name[common] != '/')
+		common--;
+	if (name[common] == '/')
+		common++;
+	return strchr(name + common, '/');
+}
+
+static int already_shown(const char *name)
+{
+	const char *last_item;
+	int len;
+
+	if (!output.nr)
+		return 0;
+
+	last_item = output.items[output.nr-1].string;
+	len = strlen(last_item);
+	return !strncmp(last_item, name, len) && name[len] == '/';
+}
+
 static void show_dir_entry(const char *tag, struct dir_entry *ent)
 {
 	int len = max_prefix_len;
+	const char *too_deep;
 
 	if (len >= ent->len)
 		die("git ls-files: internal error - directory entry not superset of prefix");
 
+	if (already_shown(ent->name))
+		return;
+
+	too_deep = path_too_deep(ent->name);
 	if (!match_pathspec(pathspec, ent->name, ent->len, len, ps_matched))
 		return;
 
+	len = too_deep ? too_deep - ent->name : ent->len;
 	fputs(tag, stdout);
-	write_name(ent->name, ent->len);
+	write_name(ent->name, len);
 }
 
 static void show_other_files(struct dir_struct *dir)
@@ -141,12 +178,19 @@ static void show_killed_files(struct dir_struct *dir)
 static void show_ce_entry(const char *tag, struct cache_entry *ce)
 {
 	int len = max_prefix_len;
+	const char *too_deep;
+	int namelen;
 
 	if (len >= ce_namelen(ce))
 		die("git ls-files: internal error - cache entry not superset of prefix");
 
+	if (already_shown(ce->name))
+		return;
+
+	too_deep = path_too_deep(ce->name);
 	if (!match_pathspec(pathspec, ce->name, ce_namelen(ce), len, ps_matched))
 		return;
+	namelen = too_deep ? too_deep - ce->name : ce_namelen(ce);
 
 	if (tag && *tag && show_valid_bit &&
 	    (ce->ce_flags & CE_VALID)) {
@@ -174,7 +218,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce)
 		       find_unique_abbrev(ce->sha1,abbrev),
 		       ce_stage(ce));
 	}
-	write_name(ce->name, ce_namelen(ce));
+	write_name(ce->name, namelen);
 	if (debug_mode) {
 		printf("  ctime: %d:%d\n", ce->ce_ctime.sec, ce->ce_ctime.nsec);
 		printf("  mtime: %d:%d\n", ce->ce_mtime.sec, ce->ce_mtime.nsec);
@@ -635,6 +679,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 int cmd_ls(int argc, const char **argv, const char *cmd_prefix)
 {
 	struct dir_struct dir;
+	int recursive = 0;
 	struct option builtin_ls_files_options[] = {
 		OPT_BOOLEAN('c', "cached", &show_cached,
 			"show cached files in the output (default)"),
@@ -647,6 +692,8 @@ int cmd_ls(int argc, const char **argv, const char *cmd_prefix)
 		OPT_BIT('i', "ignored", &dir.flags,
 			"show ignored files in the output",
 			DIR_SHOW_IGNORED),
+		OPT_BOOLEAN('r', "recursive", &recursive,
+			    "list recursively"),
 		OPT_BOOLEAN('k', "killed", &show_killed,
 			"show files on the filesystem that need to be removed"),
 		OPT_COLUMN(0, "column", &column_mode, "show files in columns" ),
@@ -683,6 +730,9 @@ int cmd_ls(int argc, const char **argv, const char *cmd_prefix)
 	      show_killed | show_modified | show_resolve_undo))
 		show_cached = 1;
 
+	if (!recursive)
+		depth_limit = 1;
+
 	show_files(&dir);
 	display_columns(&output, column_mode, term_columns(), 2, NULL);
 	return 0;
-- 
1.7.2.2
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 14 of 17 in “column output (v2) and git-ls”
  1. 00/16 column output (v2) and git-lsNguyễn Thái Ngọc Duy, Feb 9, 2011
  2. 01/16 Move term_columns() to pager.c and save terminal width before pagerNguyễn Thái Ngọc Duy, Feb 9, 2011
  3. 02/16 Add display_columns() to display in column layoutNguyễn Thái Ngọc Duy, Feb 9, 2011
  4. 03/16 display_columns: add COL_MODE_{COLUMN,ROW} modeNguyễn Thái Ngọc Duy, Feb 9, 2011
  5. 04/16 display_columns: add COL_DENSE to do unequal column layoutNguyễn Thái Ngọc Duy, Feb 9, 2011
  6. 05/16 Add test-column for testing column layoutNguyễn Thái Ngọc Duy, Feb 9, 2011
  7. 06/16 Add core.columnNguyễn Thái Ngọc Duy, Feb 9, 2011
  8. 07/16 parseopt: OPT_COLUMN to set struct column_layout.modeNguyễn Thái Ngọc Duy, Feb 9, 2011
  9. 08/16 help: reuse display_columns() for help -aNguyễn Thái Ngọc Duy, Feb 9, 2011
  10. 09/16 tag: add --columnNguyễn Thái Ngọc Duy, Feb 9, 2011
  11. 10/16 branch: add --columnNguyễn Thái Ngọc Duy, Feb 9, 2011
  12. 11/16 Add ls commandNguyễn Thái Ngọc Duy, Feb 9, 2011
  13. 12/16 ls: add --columnNguyễn Thái Ngọc Duy, Feb 9, 2011
  14. 13/16 ls: add --recursive and turn default to non-recursive modeNguyễn Thái Ngọc Duy, Feb 9, 2011
  15. 14/16 ls: immitate UNIX ls output styleNguyễn Thái Ngọc Duy, Feb 9, 2011
  16. 15/16 ls: strip common directory prefix from outputNguyễn Thái Ngọc Duy, Feb 9, 2011
  17. 16/16 ls: color outputNguyễn Thái Ngọc Duy, Feb 9, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.