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

[PATCH 15/16] ls: strip common directory prefix from output

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Feb 9, 2011, 12:24 UTC
Message-ID
<1297254284-3729-16-git-send-email-pclouds@gmail.com>
In-Reply-To
<1297254284-3729-1-git-send-email-pclouds@gmail.com>

In GNU ls, files are printed relative to their parent directory. We don't have such thing, so stay as close as we can.

The result is quite good. If the given pathspec is a directory prefix, it will be stripped, strictly following GNU ls behavior. If the pathspec has wildcards, then the command part is stripped. Usually this is the prefix part in the pathspec.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/ls-files.c |   37 +++++++++++++++++++++++++++++++++++++
 1 files changed, 37 insertions(+), 0 deletions(-)
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 22e0c87..bc438b2 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -710,6 +710,41 @@ static int one_match_pathspec(const char *pathspec)
 	return 0;
 }
 
+static void remove_common_prefix()
+{
+	int i, len = -1;
+	const char *s1, *s2;
+
+	if (output.nr <= 1)
+		return;
+
+	/*
+	 * Eliminate common prefix. This is caused by a prefix
+	 * pathspec like "ls builtin" or even "ls 't/t*.sh'"
+	 */
+
+	s1 = output.items[output.nr-1].string;
+	len = strlen(s1);
+	for (i = 1; i < output.nr; i++) {
+		int j = 0;
+		s1 = output.items[i-1].string;
+		s2 = output.items[i].string;
+		while (j < len && s1[j] == s2[j])
+			j++;
+		len = j;
+	}
+	while (len && s1[len] != '/')
+		len--;
+	if (len && s1[len] == '/')
+		len++;
+	if (len) {
+		for (i = 0; i < output.nr; i++) {
+			char *s = output.items[i].string;
+			memcpy(s, s+len, strlen(s) - len + 1);
+		}
+	}
+}
+
 int cmd_ls(int argc, const char **argv, const char *cmd_prefix)
 {
 	int show_pathspec;
@@ -801,6 +836,7 @@ int cmd_ls(int argc, const char **argv, const char *cmd_prefix)
 		one_matches[len] = NULL;
 		pathspec = one_matches;
 		show_files(&dir);
+		remove_common_prefix();
 		display_columns(&output, column_mode, term_columns(), 2, NULL);
 		string_list_clear(&output, 0);
 		if (dst)
@@ -821,6 +857,7 @@ int cmd_ls(int argc, const char **argv, const char *cmd_prefix)
 		if (output.nr && show_pathspec)
 			printf("%s:\n", pathspec[0]);
 
+		remove_common_prefix();
 		display_columns(&output, column_mode, term_columns(), 2, NULL);
 		string_list_clear(&output, 0);
 		if (show_pathspec && pathspecs[0])
-- 
1.7.2.2
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 16 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.