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@xxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html