Skip to contentSkip to conversation

EOL conversion series, take 5

PATCH New Eyvind Bernhardsen 1 participant 5 messages Jun 15, 2016

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

v5 cover EOL conversion series, take 5

This is a resend of the latest crlf fix/rename series, including the final "add core.eol" config variable patch and some minor fixes to the tests. I didn't include Finn Arne's "safe autocrlf" patch this time, but it is still required.

Signature · 24 lines
Eyvind


Eyvind Bernhardsen (4):
  Add tests for per-repository eol normalization
  Add per-repository eol normalization
  Rename the "crlf" attribute "text"
  Add "core.eol" config variable

 Documentation/config.txt        |   28 +++++--
 Documentation/git-cvsserver.txt |   13 +--
 Documentation/gitattributes.txt |  167 +++++++++++++++++++++++++++++++--------
 Makefile                        |    3 +
 attr.c                          |    2 +-
 cache.h                         |   22 +++++-
 config.c                        |   18 ++++-
 convert.c                       |  148 ++++++++++++++++++++++++++---------
 environment.c                   |    3 +-
 git-cvsserver.perl              |   13 ++-
 t/t0025-crlf-auto.sh            |  155 ++++++++++++++++++++++++++++++++++++
 t/t0026-eol-config.sh           |   83 +++++++++++++++++++
 12 files changed, 562 insertions(+), 93 deletions(-)
 create mode 100755 t/t0025-crlf-auto.sh
 create mode 100755 t/t0026-eol-config.sh
#1 lore raw

PATCH v5 1/4 Add tests for per-repository eol normalization

---
 t/t0025-crlf-auto.sh |  142 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 142 insertions(+), 0 deletions(-)
 create mode 100755 t/t0025-crlf-auto.sh
t/t0025-crlf-auto.sh new file +142 -0
new file mode 100755
index 0000000..2c98338
@@ -0,0 +1,142 @@
+#!/bin/sh
+
+test_description='CRLF conversion'
+
+. ./test-lib.sh
+
+has_cr() {
+	tr '\015' Q <"$1" | grep Q >/dev/null
+}
+
+test_expect_success setup '
+
+	git config core.autocrlf false &&
+
+	for w in Hello world how are you; do echo $w; done >one &&
+	for w in I am very very fine thank you; do echo ${w}Q; done | q_to_cr >two &&
+	for w in Oh here is a QNUL byte how alarming; do echo ${w}; done | q_to_nul >three &&
+	git add . &&
+
+	git commit -m initial &&
+
+	one=`git rev-parse HEAD:one` &&
+	two=`git rev-parse HEAD:two` &&
+	three=`git rev-parse HEAD:three` &&
+
+	echo happy.
+'
+
+test_expect_success 'default settings cause no changes' '
+
+	rm -f .gitattributes tmp one two three &&
+	git read-tree --reset -u HEAD &&
+
+	! has_cr one &&
+	has_cr two &&
+	onediff=`git diff one` &&
+	twodiff=`git diff two` &&
+	threediff=`git diff three` &&
+	test -z "$onediff" -a -z "$twodiff" -a -z "$threediff"
+'
+
+test_expect_failure 'crlf=true causes a CRLF file to be normalized' '
+
+	rm -f .gitattributes tmp one two three &&
+	echo "two crlf" > .gitattributes &&
+	git read-tree --reset -u HEAD &&
+
+	# Note, "normalized" means that git will normalize it if added
+	has_cr two &&
+	twodiff=`git diff two` &&
+	test -n "$twodiff"
+'
+
+test_expect_failure 'eol=crlf gives a normalized file CRLFs with autocrlf=false' '
+
+	rm -f .gitattributes tmp one two three &&
+	git config core.autocrlf false &&
+	echo "one eol=crlf" > .gitattributes &&
+	git read-tree --reset -u HEAD &&
+
+	has_cr one &&
+	onediff=`git diff one` &&
+	test -z "$onediff"
+'
+
+test_expect_failure 'eol=crlf gives a normalized file CRLFs with autocrlf=input' '
+
+	rm -f .gitattributes tmp one two three &&
+	git config core.autocrlf input &&
+	echo "one eol=crlf" > .gitattributes &&
+	git read-tree --reset -u HEAD &&
+
+	has_cr one &&
+	onediff=`git diff one` &&
+	test -z "$onediff"
+'
+
+test_expect_failure 'eol=lf gives a normalized file LFs with autocrlf=true' '
+
+	rm -f .gitattributes tmp one two three &&
+	git config core.autocrlf true &&
+	echo "one eol=lf" > .gitattributes &&
+	git read-tree --reset -u HEAD &&
+
+	! has_cr one &&
+	onediff=`git diff one` &&
+	test -z "$onediff"
+'
+
+test_expect_success 'autocrlf=true does not normalize CRLF files' '
+
+	rm -f .gitattributes tmp one two three &&
+	git config core.autocrlf true &&
+	git read-tree --reset -u HEAD &&
+
+	has_cr one &&
+	has_cr two &&
+	onediff=`git diff one` &&
+	twodiff=`git diff two` &&
+	threediff=`git diff three` &&
+	test -z "$onediff" -a -z "$twodiff" -a -z "$threediff"
+'
+
+test_expect_failure 'crlf=auto, autocrlf=true _does_ normalize CRLF files' '
+
+	rm -f .gitattributes tmp one two three &&
+	git config core.autocrlf true &&
+	echo "* crlf=auto" > .gitattributes &&
+	git read-tree --reset -u HEAD &&
+
+	has_cr one &&
+	has_cr two &&
+	onediff=`git diff one` &&
+	twodiff=`git diff two` &&
+	threediff=`git diff three` &&
+	test -z "$onediff" -a -n "$twodiff" -a -z "$threediff"
+'
+
+test_expect_success 'crlf=auto, autocrlf=true does not normalize binary files' '
+
+	rm -f .gitattributes tmp one two three &&
+	git config core.autocrlf true &&
+	echo "* crlf=auto" > .gitattributes &&
+	git read-tree --reset -u HEAD &&
+
+	! has_cr three &&
+	threediff=`git diff three` &&
+	test -z "$threediff"
+'
+
+test_expect_failure 'eol=crlf _does_ normalize binary files' '
+
+	rm -f .gitattributes tmp one two three &&
+	echo "three eol=crlf" > .gitattributes &&
+	git read-tree --reset -u HEAD &&
+
+	has_cr three &&
+	threediff=`git diff three` &&
+	test -z "$threediff"
+'
+
+test_done
Signature · 1 line
1.7.1.5.gc3ee8
#2 lore raw

PATCH v5 2/4 Add per-repository eol normalization

In reply to Eyvind Bernhardsen

Change the semantics of the "crlf" attribute so that it enables end-of-line normalization when it is set, regardless of "core.autocrlf".

Add a new setting for "crlf": "auto", which enables end-of-line conversion but does not override the automatic text file detection.

Add a new attribute "eol" with possible values "crlf" and "lf". When set, this attribute enables normalization and forces git to use CRLF or LF line endings in the working directory, respectively.

The line ending style to be used for normalized text files in the working directory is set using "core.autocrlf". When it is set to "true", CRLFs are used in the working directory; when set to "input" or "false", LFs are used.

---
 Documentation/config.txt        |    4 +-
 Documentation/gitattributes.txt |  152 ++++++++++++++++++++++++++++++--------
 cache.h                         |    9 ++-
 config.c                        |    2 +-
 convert.c                       |  117 +++++++++++++++++++++---------
 environment.c                   |    2 +-
 t/t0025-crlf-auto.sh            |   12 ++--
 7 files changed, 222 insertions(+), 76 deletions(-)
Documentation/config.txt +2 -2
index 92f851e..4d3c472 100644
@@ -208,8 +208,8 @@ core.autocrlf::
 	based on the file's contents.  See linkgit:gitattributes[5].
 
 core.safecrlf::
-	If true, makes git check if converting `CRLF` as controlled by
-	`core.autocrlf` is reversible.  Git will verify if a command
+	If true, makes git check if converting `CRLF` is reversible when
+	end-of-line conversion is active.  Git will verify if a command
 	modifies a file in the work tree either directly or indirectly.
 	For example, committing a file followed by checking out the
 	same file should yield the original file in the work tree.  If
Documentation/gitattributes.txt +113 -25

163 lines not on this page · raw message

cache.h +8 -1
index 5eb0573..d1f669e 100644
@@ -547,7 +547,6 @@ extern int core_compression_seen;
 extern size_t packed_git_window_size;
 extern size_t packed_git_limit;
 extern size_t delta_base_cache_limit;
-extern int auto_crlf;
 extern int read_replace_refs;
 extern int fsync_object_files;
 extern int core_preload_index;
@@ -561,6 +560,14 @@ enum safe_crlf {
 
 extern enum safe_crlf safe_crlf;
 
+enum auto_crlf {
+	AUTO_CRLF_FALSE = 0,
+	AUTO_CRLF_TRUE = 1,
+	AUTO_CRLF_INPUT = -1,
+};
+
+extern enum auto_crlf auto_crlf;
+
 enum branch_track {
 	BRANCH_TRACK_UNSPECIFIED = -1,
 	BRANCH_TRACK_NEVER = 0,
config.c +1 -1
index 6963fbe..b60a1ff 100644
@@ -461,7 +461,7 @@ static int git_default_core_config(const char *var, const char *value)
 
 	if (!strcmp(var, "core.autocrlf")) {
 		if (value && !strcasecmp(value, "input")) {
-			auto_crlf = -1;
+			auto_crlf = AUTO_CRLF_INPUT;
 			return 0;
 		}
 		auto_crlf = git_config_bool(var, value);
convert.c +84 -33

254 lines not on this page · raw message

environment.c +1 -1
index 876c5e5..db4a5e9 100644
@@ -38,7 +38,7 @@ const char *pager_program;
 int pager_use_color = 1;
 const char *editor_program;
 const char *excludes_file;
-int auto_crlf = 0;	/* 1: both ways, -1: only when adding git objects */
+enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
 int read_replace_refs = 1;
 enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
 unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
t/t0025-crlf-auto.sh +6 -6
index 2c98338..2781f15 100755
@@ -39,7 +39,7 @@ test_expect_success 'default settings cause no changes' '
 	test -z "$onediff" -a -z "$twodiff" -a -z "$threediff"
 '
 
-test_expect_failure 'crlf=true causes a CRLF file to be normalized' '
+test_expect_success 'crlf=true causes a CRLF file to be normalized' '
 
 	rm -f .gitattributes tmp one two three &&
 	echo "two crlf" > .gitattributes &&
@@ -51,7 +51,7 @@ test_expect_failure 'crlf=true causes a CRLF file to be normalized' '
 	test -n "$twodiff"
 '
 
-test_expect_failure 'eol=crlf gives a normalized file CRLFs with autocrlf=false' '
+test_expect_success 'eol=crlf gives a normalized file CRLFs with autocrlf=false' '
 
 	rm -f .gitattributes tmp one two three &&
 	git config core.autocrlf false &&
@@ -63,7 +63,7 @@ test_expect_failure 'eol=crlf gives a normalized file CRLFs with autocrlf=false'
 	test -z "$onediff"
 '
 
-test_expect_failure 'eol=crlf gives a normalized file CRLFs with autocrlf=input' '
+test_expect_success 'eol=crlf gives a normalized file CRLFs with autocrlf=input' '
 
 	rm -f .gitattributes tmp one two three &&
 	git config core.autocrlf input &&
@@ -75,7 +75,7 @@ test_expect_failure 'eol=crlf gives a normalized file CRLFs with autocrlf=input'
 	test -z "$onediff"
 '
 
-test_expect_failure 'eol=lf gives a normalized file LFs with autocrlf=true' '
+test_expect_success 'eol=lf gives a normalized file LFs with autocrlf=true' '
 
 	rm -f .gitattributes tmp one two three &&
 	git config core.autocrlf true &&
@@ -101,7 +101,7 @@ test_expect_success 'autocrlf=true does not normalize CRLF files' '
 	test -z "$onediff" -a -z "$twodiff" -a -z "$threediff"
 '
 
-test_expect_failure 'crlf=auto, autocrlf=true _does_ normalize CRLF files' '
+test_expect_success 'crlf=auto, autocrlf=true _does_ normalize CRLF files' '
 
 	rm -f .gitattributes tmp one two three &&
 	git config core.autocrlf true &&
@@ -128,7 +128,7 @@ test_expect_success 'crlf=auto, autocrlf=true does not normalize binary files' '
 	test -z "$threediff"
 '
 
-test_expect_failure 'eol=crlf _does_ normalize binary files' '
+test_expect_success 'eol=crlf _does_ normalize binary files' '
 
 	rm -f .gitattributes tmp one two three &&
 	echo "three eol=crlf" > .gitattributes &&
Signature · 1 line
1.7.1.5.gc3ee8
#3 lore raw

PATCH v5 3/4 Rename the "crlf" attribute "text"

In reply to Eyvind Bernhardsen

As discussed on the list, "crlf" is not an optimal name. Linus suggested "text", which is much better.

---
 Documentation/config.txt        |   16 ++++++----
 Documentation/git-cvsserver.txt |   13 +++-----
 Documentation/gitattributes.txt |   59 +++++++++++++++++++++++----------------
 attr.c                          |    2 +-
 convert.c                       |   23 ++++++++++-----
 git-cvsserver.perl              |   13 ++++++--
 t/t0025-crlf-auto.sh            |   21 +++++++++++--
 7 files changed, 91 insertions(+), 56 deletions(-)
Documentation/config.txt +9 -7
index 4d3c472..207351b 100644
@@ -204,7 +204,7 @@ core.autocrlf::
 	reading from the work tree but files are written out to the work
 	tree with `LF` at the end of lines.  A file is considered
 	"text" (i.e. be subjected to the autocrlf mechanism) based on
-	the file's `crlf` attribute, or if `crlf` is unspecified,
+	the file's `text` attribute, or if `text` is unspecified,
 	based on the file's contents.  See linkgit:gitattributes[5].
 
 core.safecrlf::
@@ -975,13 +975,15 @@ gitcvs.logfile::
 	various stuff. See linkgit:git-cvsserver[1].
 
 gitcvs.usecrlfattr::
-	If true, the server will look up the `crlf` attribute for
-	files to determine the '-k' modes to use. If `crlf` is set,
-	the '-k' mode will be left blank, so cvs clients will
-	treat it as text. If `crlf` is explicitly unset, the file
+	If true, the server will look up the end-of-line conversion
+	attributes for files to determine the '-k' modes to use. If
+	the attributes force git to treat a file as text,
+	the '-k' mode will be left blank so cvs clients will
+	treat it as text. If they suppress text conversion, the file
 	will be set with '-kb' mode, which suppresses any newline munging
-	the client might otherwise do. If `crlf` is not specified,
-	then 'gitcvs.allbinary' is used. See linkgit:gitattributes[5].
+	the client might otherwise do. If the attributes do not allow
+	the file type to be determined, then 'gitcvs.allbinary' is
+	used. See linkgit:gitattributes[5].
 
 gitcvs.allbinary::
 	This is used if 'gitcvs.usecrlfattr' does not resolve
Documentation/git-cvsserver.txt +5 -8
index dbb053e..0864857 100644
@@ -340,16 +340,13 @@ By default the server leaves the '-k' mode blank for all files,
 which causes the cvs client to treat them as a text files, subject
 to crlf conversion on some platforms.
 
-You can make the server use `crlf` attributes to set the '-k' modes
-for files by setting the `gitcvs.usecrlfattr` config variable.
-In this case, if `crlf` is explicitly unset ('-crlf'), then the
-server will set '-kb' mode for binary files. If `crlf` is set,
-then the '-k' mode will explicitly be left blank.  See
-also linkgit:gitattributes[5] for more information about the `crlf`
-attribute.
+You can make the server use the end-of-line conversion attributes to
+set the '-k' modes for files by setting the `gitcvs.usecrlfattr`
+config variable.  See linkgit:gitattributes[5] for more information
+about end-of-line conversion.
 
 Alternatively, if `gitcvs.usecrlfattr` config is not enabled
-or if the `crlf` attribute is unspecified for a filename, then
+or the attributes do not allow automatic detection for a filename, then
 the server uses the `gitcvs.allbinary` config for the default setting.
 If `gitcvs.allbinary` is set, then file not otherwise
 specified will default to '-kb' mode. Otherwise the '-k' mode
Documentation/gitattributes.txt +35 -24

173 lines not on this page · raw message

attr.c +1 -1
index f5346ed..bf00469 100644
@@ -287,7 +287,7 @@ static void free_attr_elem(struct attr_stack *e)
 }
 
 static const char *builtin_attr[] = {
-	"[attr]binary -diff -crlf",
+	"[attr]binary -diff -text",
 	NULL,
 };
 
convert.c +15 -8
index 98bc029..a309e07 100644
@@ -440,12 +440,14 @@ static int read_convert_config(const char *var, const char *value, void *cb)
 
 static void setup_convert_check(struct git_attr_check *check)
 {
+	static struct git_attr *attr_text;
 	static struct git_attr *attr_crlf;
 	static struct git_attr *attr_eol;
 	static struct git_attr *attr_ident;
 	static struct git_attr *attr_filter;
 
-	if (!attr_crlf) {
+	if (!attr_text) {
+		attr_text = git_attr("text");
 		attr_crlf = git_attr("crlf");
 		attr_eol = git_attr("eol");
 		attr_ident = git_attr("ident");
@@ -457,6 +459,7 @@ static void setup_convert_check(struct git_attr_check *check)
 	check[1].attr = attr_ident;
 	check[2].attr = attr_filter;
 	check[3].attr = attr_eol;
+	check[4].attr = attr_text;
 }
 
 static int count_ident(const char *cp, unsigned long size)
@@ -652,20 +655,20 @@ static int git_path_check_ident(const char *path, struct git_attr_check *check)
 	return !!ATTR_TRUE(value);
 }
 
-enum action determine_action(enum action crlf_attr, enum eol eol_attr) {
-	if (crlf_attr == CRLF_BINARY)
+enum action determine_action(enum action text_attr, enum eol eol_attr) {
+	if (text_attr == CRLF_BINARY)
 		return CRLF_BINARY;
 	if (eol_attr == EOL_LF)
 		return CRLF_INPUT;
 	if (eol_attr == EOL_CRLF)
 		return CRLF_CRLF;
-	return crlf_attr;
+	return text_attr;
 }
 
 int convert_to_git(const char *path, const char *src, size_t len,
                    struct strbuf *dst, enum safe_crlf checksafe)
 {
-	struct git_attr_check check[4];
+	struct git_attr_check check[5];
 	enum action action = CRLF_GUESS;
 	enum eol eol = EOL_UNSET;
 	int ident = 0, ret = 0;
@@ -674,7 +677,9 @@ int convert_to_git(const char *path, const char *src, size_t len,
 	setup_convert_check(check);
 	if (!git_checkattr(path, ARRAY_SIZE(check), check)) {
 		struct convert_driver *drv;
-		action = git_path_check_crlf(path, check + 0);
+		action = git_path_check_crlf(path, check + 4);
+		if (action == CRLF_GUESS)
+			action = git_path_check_crlf(path, check + 0);
 		ident = git_path_check_ident(path, check + 1);
 		drv = git_path_check_convert(path, check + 2);
 		eol = git_path_check_eol(path, check + 3);
@@ -698,7 +703,7 @@ int convert_to_git(const char *path, const char *src, size_t len,
 
 int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst)
 {
-	struct git_attr_check check[4];
+	struct git_attr_check check[5];
 	enum action action = CRLF_GUESS;
 	enum eol eol = EOL_UNSET;
 	int ident = 0, ret = 0;
@@ -707,7 +712,9 @@ int convert_to_working_tree(const char *path, const char *src, size_t len, struc
 	setup_convert_check(check);
 	if (!git_checkattr(path, ARRAY_SIZE(check), check)) {
 		struct convert_driver *drv;
-		action = git_path_check_crlf(path, check + 0);
+		action = git_path_check_crlf(path, check + 4);
+		if (action == CRLF_GUESS)
+			action = git_path_check_crlf(path, check + 0);
 		ident = git_path_check_ident(path, check + 1);
 		drv = git_path_check_convert(path, check + 2);
 		eol = git_path_check_eol(path, check + 3);
git-cvsserver.perl +9 -4
index 13751db..4e55041 100755
@@ -2369,15 +2369,20 @@ sub kopts_from_path
     if ( defined ( $cfg->{gitcvs}{usecrlfattr} ) and
          $cfg->{gitcvs}{usecrlfattr} =~ /\s*(1|true|yes)\s*$/i )
     {
-        my ($val) = check_attr( "crlf", $path );
-        if ( $val eq "set" )
+        my ($val) = check_attr( "text", $path );
+        if ( $val eq "unspecified" )
         {
-            return "";
+            $val = check_attr( "crlf", $path );
         }
-        elsif ( $val eq "unset" )
+        if ( $val eq "unset" )
         {
             return "-kb"
         }
+        elsif ( check_attr( "eol", $path ) ne "unspecified" ||
+                $val eq "set" || $val eq "input" )
+        {
+            return "";
+        }
         else
         {
             $log->info("Unrecognized check_attr crlf $path : $val");
t/t0025-crlf-auto.sh +17 -4
index 2781f15..f5f67a6 100755
@@ -41,6 +41,7 @@ test_expect_success 'default settings cause no changes' '
 
 test_expect_success 'crlf=true causes a CRLF file to be normalized' '
 
+	# Backwards compatibility check
 	rm -f .gitattributes tmp one two three &&
 	echo "two crlf" > .gitattributes &&
 	git read-tree --reset -u HEAD &&
@@ -51,6 +52,18 @@ test_expect_success 'crlf=true causes a CRLF file to be normalized' '
 	test -n "$twodiff"
 '
 
+test_expect_success 'text=true causes a CRLF file to be normalized' '
+
+	rm -f .gitattributes tmp one two three &&
+	echo "two text" > .gitattributes &&
+	git read-tree --reset -u HEAD &&
+
+	# Note, "normalized" means that git will normalize it if added
+	has_cr two &&
+	twodiff=`git diff two` &&
+	test -n "$twodiff"
+'
+
 test_expect_success 'eol=crlf gives a normalized file CRLFs with autocrlf=false' '
 
 	rm -f .gitattributes tmp one two three &&
@@ -101,11 +114,11 @@ test_expect_success 'autocrlf=true does not normalize CRLF files' '
 	test -z "$onediff" -a -z "$twodiff" -a -z "$threediff"
 '
 
-test_expect_success 'crlf=auto, autocrlf=true _does_ normalize CRLF files' '
+test_expect_success 'text=auto, autocrlf=true _does_ normalize CRLF files' '
 
 	rm -f .gitattributes tmp one two three &&
 	git config core.autocrlf true &&
-	echo "* crlf=auto" > .gitattributes &&
+	echo "* text=auto" > .gitattributes &&
 	git read-tree --reset -u HEAD &&
 
 	has_cr one &&
@@ -116,11 +129,11 @@ test_expect_success 'crlf=auto, autocrlf=true _does_ normalize CRLF files' '
 	test -z "$onediff" -a -n "$twodiff" -a -z "$threediff"
 '
 
-test_expect_success 'crlf=auto, autocrlf=true does not normalize binary files' '
+test_expect_success 'text=auto, autocrlf=true does not normalize binary files' '
 
 	rm -f .gitattributes tmp one two three &&
 	git config core.autocrlf true &&
-	echo "* crlf=auto" > .gitattributes &&
+	echo "* text=auto" > .gitattributes &&
 	git read-tree --reset -u HEAD &&
 
 	! has_cr three &&
Signature · 1 line
1.7.1.5.gc3ee8
#4 lore raw

PATCH v5 4/4 Add "core.eol" config variable

In reply to Eyvind Bernhardsen

Introduce a new configuration variable, "core.eol", that allows the user to set which line endings to use for end-of-line-normalized files in the working directory. It defaults to "native", which means CRLF on Windows and LF everywhere else.

For backwards compatibility, "core.autocrlf" will override core.eol if core.eol is left unset. This means that

[core]
autocrlf = true

will give CRLFs in the working directory even on platforms with LF as their native line ending.

If core.eol is set explicitly (including setting it to "native"), it will override core.autocrlf so that

[core]
autocrlf = true
eol = lf

normalizes all files that look like text, but does not put CRLFs in the working directory.

---
 Documentation/config.txt        |    8 ++++
 Documentation/gitattributes.txt |    6 ++-
 Makefile                        |    3 +
 cache.h                         |   13 ++++++
 config.c                        |   16 +++++++
 convert.c                       |   56 +++++++++++++++++---------
 environment.c                   |    1 +
 t/t0026-eol-config.sh           |   83 +++++++++++++++++++++++++++++++++++++++
 8 files changed, 166 insertions(+), 20 deletions(-)
 create mode 100755 t/t0026-eol-config.sh
Documentation/config.txt +8 -0
index 207351b..7cc15a4 100644
@@ -207,6 +207,14 @@ core.autocrlf::
 	the file's `text` attribute, or if `text` is unspecified,
 	based on the file's contents.  See linkgit:gitattributes[5].
 
+core.eol::
+	Sets the line ending type to use in the working directory for
+	files that have the `text` property set.  Alternatives are
+	'lf', 'crlf' and 'native', which uses the platform's native
+	line ending.  The default value is `native`.  See
+	linkgit:gitattributes[5] for more information on end-of-line
+	conversion.
+
 core.safecrlf::
 	If true, makes git check if converting `CRLF` is reversible when
 	end-of-line conversion is active.  Git will verify if a command
Documentation/gitattributes.txt +5 -1
index f091f08..be1f160 100644
@@ -207,7 +207,11 @@ attribute to "auto" for _all_ files.
 ------------------------
 
 This ensures that all files that git considers to be text will have
-normalized (LF) line endings in the repository.
+normalized (LF) line endings in the repository.  The `core.eol`
+configuration variable controls which line endings git will use for
+normalized files in your working directory; the default is to use the
+native line ending for your platform, or CRLF if `core.autocrlf` is
+set.
 
 NOTE: When `text=auto` normalization is enabled in an existing
 repository, any text files containing CRLFs should be normalized.  If
Makefile +3 -0
index 910f471..419532e 100644
@@ -224,6 +224,8 @@ all::
 #
 # Define CHECK_HEADER_DEPENDENCIES to check for problems in the hard-coded
 # dependency rules.
+#
+# Define NATIVE_CRLF if your platform uses CRLF for line endings.
 
 GIT-VERSION-FILE: FORCE
 	@$(SHELL_PATH) ./GIT-VERSION-GEN
@@ -989,6 +991,7 @@ ifeq ($(uname_S),Windows)
 	NO_CURL = YesPlease
 	NO_PYTHON = YesPlease
 	BLK_SHA1 = YesPlease
+	NATIVE_CRLF = YesPlease
 
 	CC = compat/vcbuild/scripts/clink.pl
 	AR = compat/vcbuild/scripts/lib.pl
cache.h +13 -0
index d1f669e..ac6bfbd 100644
@@ -568,6 +568,19 @@ enum auto_crlf {
 
 extern enum auto_crlf auto_crlf;
 
+enum eol {
+	EOL_UNSET,
+	EOL_CRLF,
+	EOL_LF,
+#ifdef NATIVE_CRLF
+	EOL_NATIVE = EOL_CRLF
+#else
+	EOL_NATIVE = EOL_LF
+#endif
+};
+
+extern enum eol eol;
+
 enum branch_track {
 	BRANCH_TRACK_UNSPECIFIED = -1,
 	BRANCH_TRACK_NEVER = 0,
config.c +16 -0
index b60a1ff..1479ee6 100644
@@ -461,6 +461,8 @@ static int git_default_core_config(const char *var, const char *value)
 
 	if (!strcmp(var, "core.autocrlf")) {
 		if (value && !strcasecmp(value, "input")) {
+			if (eol == EOL_CRLF)
+				return error("core.autocrlf=input conflicts with core.eol=crlf");
 			auto_crlf = AUTO_CRLF_INPUT;
 			return 0;
 		}
@@ -477,6 +479,20 @@ static int git_default_core_config(const char *var, const char *value)
 		return 0;
 	}
 
+	if (!strcmp(var, "core.eol")) {
+		if (value && !strcasecmp(value, "lf"))
+			eol = EOL_LF;
+		else if (value && !strcasecmp(value, "crlf"))
+			eol = EOL_CRLF;
+		else if (value && !strcasecmp(value, "native"))
+			eol = EOL_NATIVE;
+		else
+			eol = EOL_UNSET;
+		if (eol == EOL_CRLF && auto_crlf == AUTO_CRLF_INPUT)
+			return error("core.autocrlf=input conflicts with core.eol=crlf");
+		return 0;
+	}
+
 	if (!strcmp(var, "core.notesref")) {
 		notes_ref_name = xstrdup(value);
 		return 0;
convert.c +37 -19

124 lines not on this page · raw message

environment.c +1 -0
index db4a5e9..83d38d3 100644
@@ -40,6 +40,7 @@ const char *editor_program;
 const char *excludes_file;
 enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
 int read_replace_refs = 1;
+enum eol eol = EOL_UNSET;
 enum safe_crlf safe_crlf = SAFE_CRLF_WARN;
 unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
 enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
t/t0026-eol-config.sh new file +83 -0

83 lines not on this page · raw message

Signature · 1 line
1.7.1.5.gc3ee8