All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3] ls-files: Add eol diagnostics
@ 2015-11-21  7:36 Torsten Bögershausen
  2015-11-22  8:20 ` Sebastian Schuberth
  2015-11-23 17:27 ` Eric Sunshine
  0 siblings, 2 replies; 7+ messages in thread
From: Torsten Bögershausen @ 2015-11-21  7:36 UTC (permalink / raw
  To: git; +Cc: tboegi

When working in a cross-platform environment, a user wants to
check if text files are stored normalized in the repository and if
.gitattributes are set appropriately.

Make it possible to let Git show the line endings in the index and
in the working tree and the effective text/eol attributes

The end of line ("eolinfo") are shown like this:
"binary"       binary file
"text-no-eol"  text file without any EOL
"text-lf"      text file with LF
"text-crlf"    text file with CRLF
"text-crlf-lf" text file with mixed line endings.

The effective text/eol attribute is one of these:
"", "-text", "text", "text=auto", "eol=lf", "eol=crlf"

git ls-files --eol gives an output like this:

i/text-no-eol   w/text-no-eol   attr/text=auto t/t5100/empty
i/binary        w/binary        attr/-text     t/test-binary-2.png
i/text-lf       w/text-lf       attr/eol=lf    t/t5100/rfc2047-info-0007
i/text-lf       w/text-crlf     attr/eol=crlf  doit.bat
i/text-crlf-lf  w/text-crlf-lf  attr/          locale/XX.po

Note that the output is meant to be human-readable and may change.

Signed-off-by: Torsten Bögershausen <tboegi@web.de>
---
Changes since v2:
- Major rework
- New prefix, more common to what we use in Git (i/, w/ attr/)
- Only one option: git ls-files --eol (may be combined with -s or -o or -d
- Simplify the diagnostics: either the file is binary or text
  As empty files are not binary, they are text-no-eol
- Test cases in t0027
- The documentation is improved, but may need more improving

 Documentation/git-ls-files.txt |  22 +++++++++
 builtin/check-attr.c           |  34 ++++++++++++--
 builtin/ls-files.c             |  19 ++++++++
 convert.c                      |  86 ++++++++++++++++++++++++++++++++++
 convert.h                      |   3 ++
 t/t0027-auto-crlf.sh           | 104 ++++++++++++++++++++++++++++++++++++-----
 6 files changed, 252 insertions(+), 16 deletions(-)

diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index e26f01f..7c87a8d 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -12,6 +12,7 @@ SYNOPSIS
 'git ls-files' [-z] [-t] [-v]
 		(--[cached|deleted|others|ignored|stage|unmerged|killed|modified])*
 		(-[c|d|o|i|s|u|k|m])*
+		[--eol]
 		[-x <pattern>|--exclude=<pattern>]
 		[-X <file>|--exclude-from=<file>]
 		[--exclude-per-directory=<file>]
@@ -147,6 +148,18 @@ a space) at the start of each line:
 	possible for manual inspection; the exact format may change at
 	any time.
 
+--eol::
+	Show line endings ("eolinfo") and the text/eol attributes ("texteolattr") of files.
+	"eolinfo" is the file content identification used by Git when
+	the "text" attribute is "auto", or core.autocrlf != false.
+
+	"eolinfo" is either "" (when the the info is not avaiable"), or one of "binary",
+	"text-no-eol", "text-lf", "text-crlf" or "text-crlf-lf".
+	The "texteolattr" can be "", "-text", "text", "text=auto", "eol=lf", "eol=crlf".
+
+	Both the content in the index ("i/") and the content in the working tree ("w/")
+	are shown for regular files, followed by the "exteolattr ("attr/").
+
 \--::
 	Do not interpret any more arguments as options.
 
@@ -161,6 +174,15 @@ which case it outputs:
 
         [<tag> ]<mode> <object> <stage> <file>
 
+'git ls-files --eol' will show
+	i/<eolinfo> w/<eolinfo> attr/<eolattr> <file>
+
+'git ls-files --eol -o' will show
+	i/          w/<eolinfo> attr/<eolattr> <file>
+
+'git ls-files --eol -s' will show
+[<tag> ]<mode> <object> <stage> i/<eolinfo> w/<eolinfo> attr/<eolattr> <file>
+
 'git ls-files --unmerged' and 'git ls-files --stage' can be used to examine
 detailed information on unmerged paths.
 
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 265c9ba..7734715 100644
--- a/builtin/check-attr.c
+++ b/builtin/check-attr.c
@@ -5,6 +5,7 @@
 #include "parse-options.h"
 
 static int all_attrs;
+static int eol_attrs;
 static int cached_attrs;
 static int stdin_paths;
 static const char * const check_attr_usage[] = {
@@ -17,6 +18,7 @@ static int nul_term_line;
 
 static const struct option check_attr_options[] = {
 	OPT_BOOL('a', "all", &all_attrs, N_("report all attributes set on file")),
+	OPT_BOOL('e', "eol", &eol_attrs, N_("report effective eol attributes set on file")),
 	OPT_BOOL(0,  "cached", &cached_attrs, N_("use .gitattributes only from the index")),
 	OPT_BOOL(0 , "stdin", &stdin_paths, N_("read file names from stdin")),
 	OPT_BOOL('z', NULL, &nul_term_line,
@@ -51,6 +53,23 @@ static void output_attr(int cnt, struct git_attr_check *check,
 	}
 }
 
+static void output_eol_attr(const char *file)
+{
+	struct stat st;
+	if (lstat(file, &st) || (!S_ISREG(st.st_mode)))
+		return;
+	if (nul_term_line) {
+		printf("%s:", file);
+		if (!lstat(file, &st) && (S_ISREG(st.st_mode)))
+			printf(": %-13s ", get_convert_attr_ascii(file));
+		printf("%c", 0);
+	} else {
+		quote_c_style(file, NULL, stdout, 0);
+		printf(": %-13s ", get_convert_attr_ascii(file));
+		printf("\n");
+	}
+}
+
 static void check_attr(const char *prefix, int cnt,
 	struct git_attr_check *check, const char *file)
 {
@@ -61,7 +80,9 @@ static void check_attr(const char *prefix, int cnt,
 			die("git_check_attr died");
 		output_attr(cnt, check, file);
 	} else {
-		if (git_all_attrs(full_path, &cnt, &check))
+		if (eol_attrs)
+			output_eol_attr(full_path);
+		else if (git_all_attrs(full_path, &cnt, &check))
 			die("git_all_attrs died");
 		output_attr(cnt, check, file);
 		free(check);
@@ -123,8 +144,13 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
 			doubledash = i;
 	}
 
-	/* Process --all and/or attribute arguments: */
-	if (all_attrs) {
+	if (eol_attrs) {
+		if (doubledash >= 1)
+			error_with_usage("Attributes and --eol both specified");
+		cnt = 0;
+		filei = doubledash + 1;
+	} else if (all_attrs) {
+		/* Process --all and/or attribute arguments: */
 		if (doubledash >= 1)
 			error_with_usage("Attributes and --all both specified");
 
@@ -159,7 +185,7 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
 			error_with_usage("No file specified");
 	}
 
-	if (all_attrs) {
+	if (all_attrs || eol_attrs) {
 		check = NULL;
 	} else {
 		check = xcalloc(cnt, sizeof(*check));
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index b6a7cb0..ef892bc 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 show_eol;
 
 static const char *prefix;
 static int max_prefix_len;
@@ -47,6 +48,21 @@ static const char *tag_modified = "";
 static const char *tag_skip_worktree = "";
 static const char *tag_resolve_undo = "";
 
+static void write_eolinfo(const struct cache_entry *ce, const char *path)
+{
+	struct stat st;
+	const char *i_txt = "";
+	const char *w_txt = "";
+	if (!show_eol)
+		return;
+	if (ce && S_ISREG(ce->ce_mode))
+		i_txt = get_cached_convert_stats_ascii(ce->name);
+	if (!lstat(path, &st) && (S_ISREG(st.st_mode)))
+		w_txt = get_wt_convert_stats_ascii(path);
+	printf("i/%-13s w/%-13s attr/%-9s ", i_txt, w_txt,
+				 get_convert_attr_ascii(path));
+}
+
 static void write_name(const char *name)
 {
 	/*
@@ -68,6 +84,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent)
 		return;
 
 	fputs(tag, stdout);
+	write_eolinfo(NULL, ent->name);
 	write_name(ent->name);
 }
 
@@ -170,6 +187,7 @@ static void show_ce_entry(const char *tag, const struct cache_entry *ce)
 		       find_unique_abbrev(ce->sha1,abbrev),
 		       ce_stage(ce));
 	}
+	write_eolinfo(ce, ce->name);
 	write_name(ce->name);
 	if (debug_mode) {
 		const struct stat_data *sd = &ce->ce_stat_data;
@@ -433,6 +451,7 @@ 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", &show_eol, N_("show line endings of files")),
 		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..c99adcd 100644
--- a/convert.c
+++ b/convert.c
@@ -13,6 +13,11 @@
  * translation when the "text" attribute or "auto_crlf" option is set.
  */
 
+/* Stat bits: When BIN is set, the txt bits are unset */
+#define CONVERT_STAT_BITS_TXT_LF   (1)
+#define CONVERT_STAT_BITS_TXT_CRLF (2)
+#define CONVERT_STAT_BITS_BIN      (4)
+
 enum crlf_action {
 	CRLF_GUESS = -1,
 	CRLF_BINARY = 0,
@@ -95,6 +100,63 @@ static int is_binary(unsigned long size, struct text_stat *stats)
 	return 0;
 }
 
+static unsigned int gather_convert_stats(const char *data, unsigned long size)
+{
+	struct text_stat stats;
+	if (!data || !size)
+		return 0;
+	gather_stats(data, size, &stats);
+	if (is_binary(size, &stats) || stats.cr != stats.crlf)
+		return CONVERT_STAT_BITS_BIN;
+	else if (stats.crlf && (stats.crlf == stats.lf))
+		return CONVERT_STAT_BITS_TXT_CRLF;
+	else if (stats.crlf && stats.lf)
+		return CONVERT_STAT_BITS_TXT_CRLF | CONVERT_STAT_BITS_TXT_LF;
+	else if (stats.lf)
+		return CONVERT_STAT_BITS_TXT_LF;
+	else
+		return 0;
+}
+
+const char *gather_convert_stats_ascii(const char *data, unsigned long size)
+{
+	unsigned int convert_stats = gather_convert_stats(data, size);
+
+	if (convert_stats & CONVERT_STAT_BITS_BIN)
+		return "binary";
+	switch (convert_stats) {
+		case CONVERT_STAT_BITS_TXT_LF:
+			return("text-lf");
+		case CONVERT_STAT_BITS_TXT_CRLF:
+			return("text-crlf");
+		case CONVERT_STAT_BITS_TXT_LF | CONVERT_STAT_BITS_TXT_CRLF:
+			return("text-crlf-lf");
+		default:
+			return ("text-no-eol");
+	}
+}
+
+const char *get_cached_convert_stats_ascii(const char *path)
+{
+	const char *ret;
+	unsigned long sz;
+	void *data = read_blob_data_from_cache(path, &sz);
+	ret = gather_convert_stats_ascii(data, sz);
+	free(data);
+	return ret;
+}
+
+const char *get_wt_convert_stats_ascii(const char *path)
+{
+	const char *ret;
+	struct strbuf sb = STRBUF_INIT;
+	if (strbuf_read_file(&sb, path, 0) < 0)
+		return "";
+	ret = gather_convert_stats_ascii(sb.buf, sb.len);
+	strbuf_release(&sb);
+	return ret;
+}
+
 static enum eol output_eol(enum crlf_action crlf_action)
 {
 	switch (crlf_action) {
@@ -777,6 +839,30 @@ int would_convert_to_git_filter_fd(const char *path)
 	return apply_filter(path, NULL, 0, -1, NULL, ca.drv->clean);
 }
 
+const char *get_convert_attr_ascii(const char *path)
+{
+	struct conv_attrs ca;
+	enum crlf_action crlf_action;
+
+	convert_attrs(&ca, path);
+	crlf_action = input_crlf_action(ca.crlf_action, ca.eol_attr);
+	switch (crlf_action) {
+		case CRLF_GUESS:
+			return "";
+		case CRLF_BINARY:
+			return "-text";
+		case CRLF_TEXT:
+			return "text";
+		case CRLF_INPUT:
+			return "eol=lf";
+		case CRLF_CRLF:
+			return "eol=crlf";
+		case CRLF_AUTO:
+			return "text=auto";
+	}
+	return "";
+}
+
 int convert_to_git(const char *path, const char *src, size_t len,
                    struct strbuf *dst, enum safe_crlf checksafe)
 {
diff --git a/convert.h b/convert.h
index d9d853c..ccf436b 100644
--- a/convert.h
+++ b/convert.h
@@ -32,6 +32,9 @@ enum eol {
 };
 
 extern enum eol core_eol;
+extern const char *get_cached_convert_stats_ascii(const char *path);
+extern const char *get_wt_convert_stats_ascii(const char *path);
+extern const char *get_convert_attr_ascii(const char *path);
 
 /* returns 1 if *dst was used */
 extern int convert_to_git(const char *path, const char *src, size_t len,
diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
index b343651..7d51aed 100755
--- a/t/t0027-auto-crlf.sh
+++ b/t/t0027-auto-crlf.sh
@@ -56,21 +56,16 @@ create_gitattributes () {
 }
 
 create_NNO_files () {
-	lfname=$1
-	crlfname=$2
-	lfmixcrlf=$3
-	lfmixcr=$4
-	crlfnul=$5
 	for crlf in false true input
 	do
 		for attr in "" auto text -text lf crlf
 		do
 			pfx=NNO_${crlf}_attr_${attr} &&
-			cp $lfname    ${pfx}_LF.txt &&
-			cp $crlfname  ${pfx}_CRLF.txt &&
-			cp $lfmixcrlf ${pfx}_CRLF_mix_LF.txt &&
-			cp $lfmixcr   ${pfx}_LF_mix_CR.txt &&
-			cp $crlfnul   ${pfx}_CRLF_nul.txt
+			cp CRLF_mix_LF ${pfx}_LF.txt &&
+			cp CRLF_mix_LF ${pfx}_CRLF.txt &&
+			cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt &&
+			cp CRLF_mix_LF ${pfx}_LF_mix_CR.txt &&
+			cp CRLF_mix_LF ${pfx}_CRLF_nul.txt
 		done
 	done
 }
@@ -96,7 +91,7 @@ commit_check_warn () {
 	crlfnul=$7
 	pfx=crlf_${crlf}_attr_${attr}
 	create_gitattributes "$attr" &&
-	for f in LF CRLF repoMIX LF_mix_CR CRLF_mix_LF LF_nul CRLF_nul
+	for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul CRLF_nul
 	do
 		fname=${pfx}_$f.txt &&
 		cp $f $fname &&
@@ -149,6 +144,36 @@ commit_chk_wrnNNO () {
 	'
 }
 
+stats_ascii () {
+	case "$1" in
+		LF)
+		echo text-lf
+		;;
+		CRLF)
+		echo text-crlf
+		;;
+		CRLF_mix_LF)
+		echo text-crlf-lf
+		;;
+		LF_mix_CR)
+		echo binary
+		;;
+		CRLF_nul)
+		echo binary
+		;;
+		LF_nul)
+		echo binary
+		;;
+		CRLF_mix_CR)
+		echo binary
+		;;
+		*)
+		echo huh $1
+		;;
+	esac
+
+}
+
 check_files_in_repo () {
 	crlf=$1
 	attr=$2
@@ -213,7 +238,18 @@ checkout_files () {
 			git -c core.eol=$eol checkout $src$f.txt
 		fi
 	done
-
+	test_expect_success "ls-files --eol $lfname ${pfx}LF.txt" "
+		echo i/text-lf w/$(stats_ascii $lfname) ${src}LF.txt >e &&
+		echo i/text-crlf w/$(stats_ascii $crlfname) ${src}CRLF.txt >>e &&
+		echo i/text-crlf-lf w/$(stats_ascii $lfmixcrlf) ${src}CRLF_mix_LF.txt >>e &&
+		echo i/binary w/$(stats_ascii $lfmixcr) ${src}LF_mix_CR.txt >>e &&
+		echo i/binary w/$(stats_ascii $crlfnul) ${src}CRLF_nul.txt >>e &&
+		echo i/binary w/$(stats_ascii $crlfnul) ${src}LF_nul.txt >>e &&
+		sort <e >exp &&
+		git ls-files --eol $src* | sed -e 's!attr/[=a-z-]*!!g' -e 's/  */ /g' | sort >act &&
+		test_cmp exp act &&
+		rm e exp act
+	"
 	test_expect_success "checkout core.eol=$eol core.autocrlf=$crlf gitattributes=$attr file=LF" "
 		compare_ws_file $pfx $lfname    ${src}LF.txt
 	"
@@ -231,6 +267,35 @@ checkout_files () {
 	"
 }
 
+# Test control characters
+# NUL SOH CR EOF==^Z
+test_expect_success 'ls-files --eol -o Text/Binary' '
+	test_when_finished "rm e exp act TeBi_*" &&
+	STRT=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA &&
+	STR=$STRT$STRT$STRT$STRT &&
+	printf "${STR}BBB\001" >TeBi_127_S &&
+	printf "${STR}BBBB\001">TeBi_128_S &&
+	printf "${STR}BBB\032" >TeBi_127_E &&
+	printf "\032${STR}BBB" >TeBi_E_127 &&
+	printf "${STR}BBBB\000">TeBi_128_N &&
+	printf "${STR}BBB\012">TeBi_128_L &&
+	printf "${STR}BBB\015">TeBi_127_C &&
+	printf "${STR}BB\015\012" >TeBi_126_CL &&
+	printf "${STR}BB\015\012\015" >TeBi_126_CLC &&
+	echo i/ w/binary TeBi_127_S >e &&
+	echo i/ w/text-no-eol TeBi_128_S >>e &&
+	echo i/ w/text-no-eol TeBi_127_E >>e &&
+	echo i/ w/binary TeBi_E_127 >>e &&
+	echo i/ w/binary TeBi_128_N >>e &&
+	echo i/ w/text-lf TeBi_128_L >>e &&
+	echo i/ w/binary TeBi_127_C >>e &&
+	echo i/ w/text-crlf TeBi_126_CL >>e &&
+	echo i/ w/binary TeBi_126_CLC >>e &&
+	sort <e >exp &&
+	git ls-files --eol -o | egrep "TeBi_" | sed -e 's!attr/[=a-z-]*!!g' -e "s/  */ /g" | sort >act &&
+	test_cmp exp act
+'
+
 #######
 test_expect_success 'setup master' '
 	echo >.gitattributes &&
@@ -480,4 +545,19 @@ checkout_files    native  true  "lf"      LF    CRLF  CRLF_mix_LF  LF_mix_CR
 checkout_files    native  false "crlf"    CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
 checkout_files    native  true  "crlf"    CRLF  CRLF  CRLF         CRLF_mix_CR  CRLF_nul
 
+
+# Should be the last test case
+test_expect_success 'ls-files --eol -d' "
+	rm  crlf_false_attr__CRLF.txt crlf_false_attr__CRLF_mix_LF.txt crlf_false_attr__LF.txt .gitattributes &&
+	echo i/text-lf w/ .gitattributes >e &&
+	echo i/text-crlf w/ crlf_false_attr__CRLF.txt >>e &&
+	echo i/text-crlf-lf w/ crlf_false_attr__CRLF_mix_LF.txt >>e &&
+	echo i/text-lf w/ crlf_false_attr__LF.txt >>e &&
+	sort <e >exp &&
+	git ls-files --eol -d | sed -e 's!attr/[=a-z-]*!!g' -e 's/  */ /g' | sort >act &&
+	test_cmp exp act &&
+	rm e exp act
+"
+
+
 test_done
-- 
2.6.1.443.g36d7748

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v3] ls-files: Add eol diagnostics
  2015-11-21  7:36 [PATCH v3] ls-files: Add eol diagnostics Torsten Bögershausen
@ 2015-11-22  8:20 ` Sebastian Schuberth
  2015-11-23 17:05   ` Torsten Bögershausen
  2015-11-23 17:27 ` Eric Sunshine
  1 sibling, 1 reply; 7+ messages in thread
From: Sebastian Schuberth @ 2015-11-22  8:20 UTC (permalink / raw
  To: Torsten Bögershausen, git

On 21.11.2015 08:36, Torsten Bögershausen wrote:

> git ls-files --eol gives an output like this:
> 
> i/text-no-eol   w/text-no-eol   attr/text=auto t/t5100/empty

I'm sorry if this has been discussed before, but hav you considered to use a header line and omit the prefixed from the columns instead? Like

index         working tree     attributes    file

binary        binary           -text         t/test-binary-2.png
text-lf       text-lf          eol=lf        t/t5100/rfc2047-info-0007
text-lf       text-crlf        eol=crlf      doit.bat
text-crlf-lf  text-crlf-lf                   locale/XX.po

I believe this would be both easier to read for humans, and easier to parse for scripts that e.g. want to compare line endings in the index and working tree.

> +stats_ascii () {
> +	case "$1" in

[...]

> +		*)
> +		echo huh $1
> +		;;

Personally, I'm not a big fan of supposedly funny output like this. How about printing a proper message rather than "huh", even for cases that should not happen?

-- 
Sebastian Schuberth

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3] ls-files: Add eol diagnostics
  2015-11-22  8:20 ` Sebastian Schuberth
@ 2015-11-23 17:05   ` Torsten Bögershausen
  2015-11-23 19:45     ` Sebastian Schuberth
  2015-11-24 16:45     ` Ramsay Jones
  0 siblings, 2 replies; 7+ messages in thread
From: Torsten Bögershausen @ 2015-11-23 17:05 UTC (permalink / raw
  To: Sebastian Schuberth, Torsten Bögershausen, git

On 22.11.15 09:20, Sebastian Schuberth wrote:
> On 21.11.2015 08:36, Torsten Bögershausen wrote:
> 
>> git ls-files --eol gives an output like this:
>>
>> i/text-no-eol   w/text-no-eol   attr/text=auto t/t5100/empty
> 
> I'm sorry if this has been discussed before, but hav you considered to use a header line and omit the prefixed from the columns instead? Like
> 
> index         working tree     attributes    file
> 
> binary        binary           -text         t/test-binary-2.png
> text-lf       text-lf          eol=lf        t/t5100/rfc2047-info-0007
> text-lf       text-crlf        eol=crlf      doit.bat
> text-crlf-lf  text-crlf-lf                   locale/XX.po
> 
> I believe this would be both easier to read for humans, and easier to parse for scripts that e.g. want to compare line endings in the index and working tree.
> 
The problem I see is to make sure that there is always a separator, even when a field empty:

rm zlib.c; git ls-file --eol #will include a line like this:
i/text-lf       w/              attr/          zlib.c

or, as another example:
git ls-files -o --eol
i/              w/binary        attr/          zlib.o


And if there is no separator, it is harder to make it machine-parsable,
if we e.g. extend the attributes to support "*text=autocrlf", or "*.text=autoinput"
(But that is another story)

If we replace "/[-a-z]" with "\t", the line has always a separator,
but needs a somewhat wider screen:
        text-lf         text-lf                   zlib.c




>> +		echo huh $1
[] good catch, thanks

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3] ls-files: Add eol diagnostics
  2015-11-21  7:36 [PATCH v3] ls-files: Add eol diagnostics Torsten Bögershausen
  2015-11-22  8:20 ` Sebastian Schuberth
@ 2015-11-23 17:27 ` Eric Sunshine
  1 sibling, 0 replies; 7+ messages in thread
From: Eric Sunshine @ 2015-11-23 17:27 UTC (permalink / raw
  To: Torsten Bögershausen; +Cc: Git List

On Sat, Nov 21, 2015 at 2:36 AM, Torsten Bögershausen <tboegi@web.de> wrote:
> When working in a cross-platform environment, a user wants to
> check if text files are stored normalized in the repository and if
> .gitattributes are set appropriately.
>
> Make it possible to let Git show the line endings in the index and
> in the working tree and the effective text/eol attributes

s/$/./

> [...]
> Signed-off-by: Torsten Bögershausen <tboegi@web.de>
> ---
> diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
> @@ -147,6 +148,18 @@ a space) at the start of each line:
>         possible for manual inspection; the exact format may change at
>         any time.
>
> +--eol::
> +       Show line endings ("eolinfo") and the text/eol attributes ("texteolattr") of files.
> +       "eolinfo" is the file content identification used by Git when
> +       the "text" attribute is "auto", or core.autocrlf != false.
> +
> +       "eolinfo" is either "" (when the the info is not avaiable"), or one of "binary",

s/avaiable/available/

> +       "text-no-eol", "text-lf", "text-crlf" or "text-crlf-lf".
> +       The "texteolattr" can be "", "-text", "text", "text=auto", "eol=lf", "eol=crlf".
> +
> +       Both the content in the index ("i/") and the content in the working tree ("w/")
> +       are shown for regular files, followed by the "exteolattr ("attr/").

s/exteolattr/texteolattr/

Should the documentation mention that with --eol ls-files becomes a
much more expensive operation since it now has to read all blobs
referenced by trees? (genuine question)

> diff --git a/builtin/check-attr.c b/builtin/check-attr.c
> @@ -51,6 +53,23 @@ static void output_attr(int cnt, struct git_attr_check *check,
> +static void output_eol_attr(const char *file)
> +{
> +       struct stat st;
> +       if (lstat(file, &st) || (!S_ISREG(st.st_mode)))
> +               return;
> +       if (nul_term_line) {
> +               printf("%s:", file);
> +               if (!lstat(file, &st) && (S_ISREG(st.st_mode)))
> +                       printf(": %-13s ", get_convert_attr_ascii(file));

Why the trailing space in the format string?

> +               printf("%c", 0);

putc('\0') perhaps?

> +       } else {
> +               quote_c_style(file, NULL, stdout, 0);
> +               printf(": %-13s ", get_convert_attr_ascii(file));

Ditto regarding trailing space.

> +               printf("\n");

Is there a reason the "\n" isn't incorporated into the preceding
printf's format string?

> +       }
> +}
> diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh
> @@ -213,7 +238,18 @@ checkout_files () {
>                         git -c core.eol=$eol checkout $src$f.txt
>                 fi
>         done
> -
> +       test_expect_success "ls-files --eol $lfname ${pfx}LF.txt" "
> +               echo i/text-lf w/$(stats_ascii $lfname) ${src}LF.txt >e &&
> +               echo i/text-crlf w/$(stats_ascii $crlfname) ${src}CRLF.txt >>e &&
> +               echo i/text-crlf-lf w/$(stats_ascii $lfmixcrlf) ${src}CRLF_mix_LF.txt >>e &&
> +               echo i/binary w/$(stats_ascii $lfmixcr) ${src}LF_mix_CR.txt >>e &&
> +               echo i/binary w/$(stats_ascii $crlfnul) ${src}CRLF_nul.txt >>e &&
> +               echo i/binary w/$(stats_ascii $crlfnul) ${src}LF_nul.txt >>e &&

I wonder if a here-doc would make this a bit more readable and maintainable...

    echo >e <<-EOF &&
    i/text-lf w/$(stats_ascii $lfname) ${src}LF.txt
    i/text-crlf w/$(stats_ascii $crlfname) ${src}CRLF.txt
    i/text-crlf-lf w/$(stats_ascii $lfmixcrlf) ${src}CRLF_mix_LF.txt
    i/binary w/$(stats_ascii $lfmixcr) ${src}LF_mix_CR.txt
    i/binary w/$(stats_ascii $crlfnul) ${src}CRLF_nul.txt
    i/binary w/$(stats_ascii $crlfnul) ${src}LF_nul.txt
    EOF

> +               sort <e >exp &&
> +               git ls-files --eol $src* | sed -e 's!attr/[=a-z-]*!!g' -e 's/  */ /g' | sort >act &&
> +               test_cmp exp act &&
> +               rm e exp act
> +       "
> @@ -231,6 +267,35 @@ checkout_files () {
>         "
>  }
>
> +# Test control characters
> +# NUL SOH CR EOF==^Z
> +test_expect_success 'ls-files --eol -o Text/Binary' '
> +       test_when_finished "rm e exp act TeBi_*" &&
> +       STRT=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA &&
> +       STR=$STRT$STRT$STRT$STRT &&
> +       printf "${STR}BBB\001" >TeBi_127_S &&
> +       printf "${STR}BBBB\001">TeBi_128_S &&
> +       printf "${STR}BBB\032" >TeBi_127_E &&
> +       printf "\032${STR}BBB" >TeBi_E_127 &&
> +       printf "${STR}BBBB\000">TeBi_128_N &&
> +       printf "${STR}BBB\012">TeBi_128_L &&
> +       printf "${STR}BBB\015">TeBi_127_C &&
> +       printf "${STR}BB\015\012" >TeBi_126_CL &&
> +       printf "${STR}BB\015\012\015" >TeBi_126_CLC &&
> +       echo i/ w/binary TeBi_127_S >e &&
> +       echo i/ w/text-no-eol TeBi_128_S >>e &&
> +       echo i/ w/text-no-eol TeBi_127_E >>e &&
> +       echo i/ w/binary TeBi_E_127 >>e &&
> +       echo i/ w/binary TeBi_128_N >>e &&
> +       echo i/ w/text-lf TeBi_128_L >>e &&
> +       echo i/ w/binary TeBi_127_C >>e &&
> +       echo i/ w/text-crlf TeBi_126_CL >>e &&
> +       echo i/ w/binary TeBi_126_CLC >>e &&

here-doc equivalent:

    echo >e <<-\EOF &&
    i/ w/binary TeBi_127_S
    i/ w/text-no-eol TeBi_128_S
    i/ w/text-no-eol TeBi_127_E
    i/ w/binary TeBi_E_127
    i/ w/binary TeBi_128_N
    i/ w/text-lf TeBi_128_L
    i/ w/binary TeBi_127_C
    i/ w/text-crlf TeBi_126_CL
    i/ w/binary TeBi_126_CLC
    EOF

> +       sort <e >exp &&
> +       git ls-files --eol -o | egrep "TeBi_" | sed -e 's!attr/[=a-z-]*!!g' -e "s/  */ /g" | sort >act &&
> +       test_cmp exp act
> +'
> +
> @@ -480,4 +545,19 @@ checkout_files    native  true  "lf"      LF    CRLF  CRLF_mix_LF  LF_mix_CR
> +# Should be the last test case
> +test_expect_success 'ls-files --eol -d' "
> +       rm  crlf_false_attr__CRLF.txt crlf_false_attr__CRLF_mix_LF.txt crlf_false_attr__LF.txt .gitattributes &&
> +       echo i/text-lf w/ .gitattributes >e &&
> +       echo i/text-crlf w/ crlf_false_attr__CRLF.txt >>e &&
> +       echo i/text-crlf-lf w/ crlf_false_attr__CRLF_mix_LF.txt >>e &&
> +       echo i/text-lf w/ crlf_false_attr__LF.txt >>e &&

    echo >e <<-\EOF &&
    i/text-lf w/ .gitattributes
    i/text-crlf w/ crlf_false_attr__CRLF.txt
    i/text-crlf-lf w/ crlf_false_attr__CRLF_mix_LF.txt
    i/text-lf w/ crlf_false_attr__LF.txt
    EOF

> +       sort <e >exp &&
> +       git ls-files --eol -d | sed -e 's!attr/[=a-z-]*!!g' -e 's/  */ /g' | sort >act &&
> +       test_cmp exp act &&
> +       rm e exp act
> +"
> +
> +
>  test_done
> --
> 2.6.1.443.g36d7748

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3] ls-files: Add eol diagnostics
  2015-11-23 17:05   ` Torsten Bögershausen
@ 2015-11-23 19:45     ` Sebastian Schuberth
  2015-11-23 20:00       ` Eric Sunshine
  2015-11-24 16:45     ` Ramsay Jones
  1 sibling, 1 reply; 7+ messages in thread
From: Sebastian Schuberth @ 2015-11-23 19:45 UTC (permalink / raw
  To: Torsten Bögershausen; +Cc: Git Mailing List

On Mon, Nov 23, 2015 at 6:05 PM, Torsten Bögershausen <tboegi@web.de> wrote:

> or, as another example:
> git ls-files -o --eol
> i/              w/binary        attr/          zlib.o

I see, somewhat convincing I have to agree.

On another note, how about making the prefix either all just one
letter (i.e. "attr/" becomes "a/"), or all multi-letter abbreviations
(i.e. "i/" becomes "idx/" and "w/" becomes "wt/" or "wtree/" or
"tree/")?

-- 
Sebastian Schuberth

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3] ls-files: Add eol diagnostics
  2015-11-23 19:45     ` Sebastian Schuberth
@ 2015-11-23 20:00       ` Eric Sunshine
  0 siblings, 0 replies; 7+ messages in thread
From: Eric Sunshine @ 2015-11-23 20:00 UTC (permalink / raw
  To: Sebastian Schuberth; +Cc: Torsten Bögershausen, Git Mailing List

On Mon, Nov 23, 2015 at 2:45 PM, Sebastian Schuberth
<sschuberth@gmail.com> wrote:
> On Mon, Nov 23, 2015 at 6:05 PM, Torsten Bögershausen <tboegi@web.de> wrote:
>> git ls-files -o --eol
>> i/              w/binary        attr/          zlib.o
>
> I see, somewhat convincing I have to agree.
>
> On another note, how about making the prefix either all just one
> letter (i.e. "attr/" becomes "a/"), or all multi-letter abbreviations
> (i.e. "i/" becomes "idx/" and "w/" becomes "wt/" or "wtree/" or
> "tree/")?

The latter is answered by [1].

[1]: http://article.gmane.org/gmane.comp.version-control.git/280647

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v3] ls-files: Add eol diagnostics
  2015-11-23 17:05   ` Torsten Bögershausen
  2015-11-23 19:45     ` Sebastian Schuberth
@ 2015-11-24 16:45     ` Ramsay Jones
  1 sibling, 0 replies; 7+ messages in thread
From: Ramsay Jones @ 2015-11-24 16:45 UTC (permalink / raw
  To: Torsten Bögershausen, Sebastian Schuberth, git



On 23/11/15 17:05, Torsten Bögershausen wrote:
> On 22.11.15 09:20, Sebastian Schuberth wrote:
>> On 21.11.2015 08:36, Torsten Bögershausen wrote:
>>
>>> git ls-files --eol gives an output like this:
>>>
>>> i/text-no-eol   w/text-no-eol   attr/text=auto t/t5100/empty
>>
>> I'm sorry if this has been discussed before, but hav you considered to use a header line and omit the prefixed from the columns instead? Like
>>
>> index         working tree     attributes    file
>>
>> binary        binary           -text         t/test-binary-2.png
>> text-lf       text-lf          eol=lf        t/t5100/rfc2047-info-0007
>> text-lf       text-crlf        eol=crlf      doit.bat
>> text-crlf-lf  text-crlf-lf                   locale/XX.po
>>
>> I believe this would be both easier to read for humans, and easier to parse for scripts that e.g. want to compare line endings in the index and working tree.
>>
> The problem I see is to make sure that there is always a separator, even when a field empty:
> 
> rm zlib.c; git ls-file --eol #will include a line like this:
> i/text-lf       w/              attr/          zlib.c
> 
> or, as another example:
> git ls-files -o --eol
> i/              w/binary        attr/          zlib.o
> 

[I have been trying *not* to respond to this thread, since
the following comment is classic bikeshedding on the naming
of things and I am, in general, hopeless at naming things ... :-D ]

<bikeshedding>
I don't think you need to include 'text' in the name of the
line ending descriptors - if its not binary then its some
form of text. So, maybe something like:

    binary
    none
    lf
    crlf
    mixed

</bikeshedding>

HTH

ATB,
Ramsay Jones

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-11-24 16:45 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-21  7:36 [PATCH v3] ls-files: Add eol diagnostics Torsten Bögershausen
2015-11-22  8:20 ` Sebastian Schuberth
2015-11-23 17:05   ` Torsten Bögershausen
2015-11-23 19:45     ` Sebastian Schuberth
2015-11-23 20:00       ` Eric Sunshine
2015-11-24 16:45     ` Ramsay Jones
2015-11-23 17:27 ` Eric Sunshine

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.