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 <tbo...@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

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to