summaryrefslogtreecommitdiff
path: root/convert.c
diff options
context:
space:
mode:
authorEyvind Bernhardsen <eyvind.bernhardsen@gmail.com>2010-06-04 19:29:08 (GMT)
committerJunio C Hamano <gitster@pobox.com>2010-06-07 04:20:04 (GMT)
commit942e7747678ecf5f118ea5b2d0c763166de21f3a (patch)
tree0e5f1e1e72682b183831d0ee76485b6b09e0df41 /convert.c
parent5ec3e67052289217c84e53d2cda90d939ac5725b (diff)
downloadgit-942e7747678ecf5f118ea5b2d0c763166de21f3a.zip
git-942e7747678ecf5f118ea5b2d0c763166de21f3a.tar.gz
git-942e7747678ecf5f118ea5b2d0c763166de21f3a.tar.bz2
Add "core.eol" config variable
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. Note that "core.autocrlf" overrides core.eol. This means that [core] autocrlf = true puts CRLFs in the working directory even if core.eol is set to "lf". Signed-off-by: Eyvind Bernhardsen <eyvind.bernhardsen@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'convert.c')
-rw-r--r--convert.c60
1 files changed, 36 insertions, 24 deletions
diff --git a/convert.c b/convert.c
index c61c02b..061fb23 100644
--- a/convert.c
+++ b/convert.c
@@ -8,7 +8,7 @@
* This should use the pathname to decide on whether it wants to do some
* more interesting conversions (automatic gzip/unzip, general format
* conversions etc etc), but by default it just does automatic CRLF<->LF
- * translation when the "crlf" attribute or "auto_crlf" option is set.
+ * translation when the "text" attribute or "auto_crlf" option is set.
*/
enum action {
@@ -20,12 +20,6 @@ enum action {
CRLF_AUTO,
};
-enum eol {
- EOL_UNSET,
- EOL_LF,
- EOL_CRLF,
-};
-
struct text_stat {
/* NUL, CR, LF and CRLF counts */
unsigned nul, cr, lf, crlf;
@@ -99,33 +93,55 @@ static int is_binary(unsigned long size, struct text_stat *stats)
return 0;
}
+static enum eol determine_output_conversion(enum action action) {
+ switch (action) {
+ case CRLF_BINARY:
+ return EOL_UNSET;
+ case CRLF_CRLF:
+ return EOL_CRLF;
+ case CRLF_INPUT:
+ return EOL_LF;
+ case CRLF_GUESS:
+ if (!auto_crlf)
+ return EOL_UNSET;
+ /* fall through */
+ case CRLF_TEXT:
+ case CRLF_AUTO:
+ if (auto_crlf == AUTO_CRLF_TRUE)
+ return EOL_CRLF;
+ else if (auto_crlf == AUTO_CRLF_INPUT)
+ return EOL_LF;
+ else if (eol == EOL_UNSET)
+ return EOL_NATIVE;
+ }
+ return eol;
+}
+
static void check_safe_crlf(const char *path, enum action action,
struct text_stat *stats, enum safe_crlf checksafe)
{
if (!checksafe)
return;
- if (action == CRLF_INPUT ||
- (action == CRLF_GUESS && auto_crlf == AUTO_CRLF_INPUT)) {
+ if (determine_output_conversion(action) == EOL_LF) {
/*
* CRLFs would not be restored by checkout:
* check if we'd remove CRLFs
*/
if (stats->crlf) {
if (checksafe == SAFE_CRLF_WARN)
- warning("CRLF will be replaced by LF in %s.", path);
+ warning("CRLF will be replaced by LF in %s.\nThe file will have its original line endings in your working directory.", path);
else /* i.e. SAFE_CRLF_FAIL */
die("CRLF would be replaced by LF in %s.", path);
}
- } else if (action == CRLF_CRLF ||
- (action == CRLF_GUESS && auto_crlf == AUTO_CRLF_TRUE)) {
+ } else if (determine_output_conversion(action) == EOL_CRLF) {
/*
* CRLFs would be added by checkout:
* check if we have "naked" LFs
*/
if (stats->lf != stats->crlf) {
if (checksafe == SAFE_CRLF_WARN)
- warning("LF will be replaced by CRLF in %s", path);
+ warning("LF will be replaced by CRLF in %s.\nThe file will have its original line endings in your working directory.", path);
else /* i.e. SAFE_CRLF_FAIL */
die("LF would be replaced by CRLF in %s", path);
}
@@ -244,11 +260,7 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len,
char *to_free = NULL;
struct text_stat stats;
- if ((action == CRLF_BINARY) || (action == CRLF_INPUT) ||
- (action != CRLF_CRLF && auto_crlf != AUTO_CRLF_TRUE))
- return 0;
-
- if (!len)
+ if (!len || determine_output_conversion(action) != EOL_CRLF)
return 0;
gather_stats(src, len, &stats);
@@ -669,7 +681,7 @@ int convert_to_git(const char *path, const char *src, size_t len,
{
struct git_attr_check check[5];
enum action action = CRLF_GUESS;
- enum eol eol = EOL_UNSET;
+ enum eol eol_attr = EOL_UNSET;
int ident = 0, ret = 0;
const char *filter = NULL;
@@ -681,7 +693,7 @@ int convert_to_git(const char *path, const char *src, size_t len,
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);
+ eol_attr = git_path_check_eol(path, check + 3);
if (drv && drv->clean)
filter = drv->clean;
}
@@ -691,7 +703,7 @@ int convert_to_git(const char *path, const char *src, size_t len,
src = dst->buf;
len = dst->len;
}
- action = determine_action(action, eol);
+ action = determine_action(action, eol_attr);
ret |= crlf_to_git(path, src, len, dst, action, checksafe);
if (ret) {
src = dst->buf;
@@ -704,7 +716,7 @@ int convert_to_working_tree(const char *path, const char *src, size_t len, struc
{
struct git_attr_check check[5];
enum action action = CRLF_GUESS;
- enum eol eol = EOL_UNSET;
+ enum eol eol_attr = EOL_UNSET;
int ident = 0, ret = 0;
const char *filter = NULL;
@@ -716,7 +728,7 @@ int convert_to_working_tree(const char *path, const char *src, size_t len, struc
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);
+ eol_attr = git_path_check_eol(path, check + 3);
if (drv && drv->smudge)
filter = drv->smudge;
}
@@ -726,7 +738,7 @@ int convert_to_working_tree(const char *path, const char *src, size_t len, struc
src = dst->buf;
len = dst->len;
}
- action = determine_action(action, eol);
+ action = determine_action(action, eol_attr);
ret |= crlf_to_worktree(path, src, len, dst, action);
if (ret) {
src = dst->buf;