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

[PATCH] Add ls-files --eol-staged, --eol-worktree

From
Torsten Bögershausen <tboegi@web.de>
Date
Oct 17, 2015, 20:18 UTC
Message-ID
<D68CC6D0-3FD5-4423-A9E2-905DF18E893F@web.de>

Make it possible to show the line endings of files. Files which are staged and/or files in the working tree:

git ls-files --eol-staged git ls-files --eol-worktree

Both will show an output like this:

empty empty_file bin binary_file_or_with_cr_handled_as_binary txt-crlf text_file_with_crlf txt-mix text_file_with_crlf_and_lf txt-lf text_file_with_lf txt text_file_with_no_eol_at_all

Implementation details: Make struct text_stat, is_binary() and gather_stats() from convert.c public, add a new function get_convert_stats_ascii() and use it in and use them in ls-files. git ls-files --eol-staged will give a line like this:

Signed-off-by: Torsten Bögershausen <tboegi@web.de>
---
This needs to go on top of tb/t0027-crlf

builtin/ls-files.c | 21 +++++++++++++++++++++ convert.c | 51 +++++++++++++++++++++++++++++++++++++++++---------- convert.h | 14 ++++++++++++++ 3 files changed, 76 insertions(+), 10 deletions(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index b6a7cb0..c989e94 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -27,6 +27,8 @@ static int show_killed;
static int show_valid_bit;
static int line_terminator = '\n';
static int debug_mode;
+static int show_eol_staged;
+static int show_eol_wt;

static const char *prefix;
static int max_prefix_len;
@@ -68,6 +70,11 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)
		return;

	fputs(tag, stdout);
+	if (show_eol_wt) {
+		printf("%s ", get_convert_stats_ascii(ent->name,
+																					GET_CONVERT_STATS_ASCII_WT, 0));
+	}
+
	write_name(ent->name);
}

@@ -170,6 +177,14 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce)
		       find_unique_abbrev(ce->sha1,abbrev),
		       ce_stage(ce));
	}
+	if (show_eol_staged) {
+		printf("%s ",
+					 get_convert_stats_ascii(ce->name, GET_CONVERT_STATS_ASCII_BLOB, 0));
+	}
+	if (show_eol_wt) {
+		printf("%s ", get_convert_stats_ascii(ce->name,GET_CONVERT_STATS_ASCII_WT,
+																					ce->ce_stat_data.sd_size));
+	}
	write_name(ce->name);
	if (debug_mode) {
		const struct stat_data *sd = &ce->ce_stat_data;
@@ -206,6 +221,10 @@ static void show_ru_info(void)
			printf("%s%06o %s %d\t", tag_resolve_undo, ui->mode[i],
			       find_unique_abbrev(ui->sha1[i], abbrev),
			       i + 1);
+			if (show_eol_wt) {
+				printf("%s ",
+							 get_convert_stats_ascii(path, GET_CONVERT_STATS_ASCII_WT, 0));
+			}
			write_name(path);
		}
	}
@@ -433,6 +452,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
		OPT_BIT(0, "directory", &dir.flags,
			N_("show 'other' directories' names only"),
			DIR_SHOW_OTHER_DIRECTORIES),
+		OPT_BOOL(0, "eol-staged", &show_eol_staged, N_("show line endings of the staged file")),
+		OPT_BOOL(0, "eol-worktree", &show_eol_wt, N_("show line endings of the file in work tree")),
		OPT_NEGBIT(0, "empty-directory", &dir.flags,
			N_("don't show empty directories"),
			DIR_HIDE_EMPTY_DIRECTORIES),
diff --git a/convert.c b/convert.c
index 814e814..a1c24cd 100644
--- a/convert.c
+++ b/convert.c
@@ -22,15 +22,7 @@ enum crlf_action {
	CRLF_AUTO
};

-struct text_stat {
-	/* NUL, CR, LF and CRLF counts */
-	unsigned nul, cr, lf, crlf;
-
-	/* These are just approximations! */
-	unsigned printable, nonprintable;
-};
-
-static void gather_stats(const char *buf, unsigned long size, struct text_stat *stats)
+void gather_stats(const char *buf, unsigned long size, struct text_stat *stats)
{
	unsigned long i;

@@ -76,7 +68,7 @@ static void gather_stats(const char *buf, unsigned long size, struct text_stat *
/*
 * The same heuristics as diff.c::mmfile_is_binary()
 */
-static int is_binary(unsigned long size, struct text_stat *stats)
+int is_binary(unsigned long size, struct text_stat *stats)
{

	if (stats->nul)
@@ -95,6 +87,45 @@ static int is_binary(unsigned long size, struct text_stat *stats)
	return 0;
}

+
+const char *gather_stats_ascii(const char *data, unsigned long size)
+{
+	struct text_stat stats;
+	if (!data || !size)
+		return("empty   ");
+	gather_stats(data, size, &stats);
+	if (is_binary(size, &stats))
+		return("bin     ");
+	else if (stats.cr != stats.crlf)
+		return("bin     ");
+	else if (stats.crlf && (stats.crlf == stats.lf))
+		return("txt-crlf");
+	else if (stats.crlf && stats.lf)
+		return("txt-mix ");
+	else if (stats.lf)
+		return("txt-lf  ");
+	else
+		return("txt     ");
+}
+
+const char *get_convert_stats_ascii(const char *path, int flags, size_t hint)
+{
+	const char *ret = "";
+	if (flags & GET_CONVERT_STATS_ASCII_BLOB) {
+		unsigned long sz;
+		void *data = read_blob_data_from_cache(path, &sz);
+		ret = gather_stats_ascii(data, sz);
+		if (data)
+			free(data);
+	} else if (flags & GET_CONVERT_STATS_ASCII_WT){
+		struct strbuf sb = STRBUF_INIT;
+		strbuf_read_file(&sb, path, hint);
+		ret = gather_stats_ascii(sb.buf, sb.len);
+		strbuf_release(&sb);
+	}
+	return ret;
+}
+
static enum eol output_eol(enum crlf_action crlf_action)
{
	switch (crlf_action) {
diff --git a/convert.h b/convert.h
index d9d853c..566cf0e 100644
--- a/convert.h
+++ b/convert.h
@@ -31,6 +31,20 @@ enum eol {
#endif
};

+struct text_stat {
+	/* NUL, CR, LF and CRLF counts */
+	unsigned nul, cr, lf, crlf;
+
+	/* These are just approximations! */
+	unsigned printable, nonprintable;
+};
+void gather_stats(const char *buf, unsigned long size, struct text_stat *stats);
+int is_binary(unsigned long size, struct text_stat *stats);
+const char *gather_stats_ascii(const char *buf, unsigned long size);
+#define GET_CONVERT_STATS_ASCII_BLOB           (1<<0)
+#define GET_CONVERT_STATS_ASCII_WT             (1<<1)
+const char *get_convert_stats_ascii(const char *path, int isBlob, size_t hint);
+
extern enum eol core_eol;

/* returns 1 if *dst was used */
-- 
2.6.1.443.g36d7748
Next: Eric Sunshine
Message 1 of 8 in “Add ls-files --eol-staged, --eol-worktree”
  1. Add ls-files --eol-staged, --eol-worktreeTorsten Bögershausen, Oct 17, 2015
  2. Eric SunshineOct 18, 2015
  3. Philip OakleyOct 18, 2015
  4. Junio C HamanoOct 18, 2015
  5. Junio C HamanoOct 18, 2015
  6. Junio C HamanoOct 18, 2015
  7. Torsten BögershausenOct 19, 2015
  8. Junio C HamanoOct 19, 2015

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.