From d2543b8ee3abeb611c352f17a9177732bfde7e36 Mon Sep 17 00:00:00 2001 From: Timo Hirvonen Date: Sat, 24 Jun 2006 20:20:32 +0300 Subject: [PATCH 1/5] Clean up diff.c Signed-off-by: Timo Hirvonen Signed-off-by: Junio C Hamano --- diff.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/diff.c b/diff.c index f89224f75f..834b166064 100644 --- a/diff.c +++ b/diff.c @@ -203,7 +203,7 @@ static void emit_rewrite_diff(const char *name_a, static int fill_mmfile(mmfile_t *mf, struct diff_filespec *one) { if (!DIFF_FILE_VALID(one)) { - mf->ptr = ""; /* does not matter */ + mf->ptr = (char *)""; /* does not matter */ mf->size = 0; return 0; } @@ -395,7 +395,7 @@ static void show_stats(struct diffstat_t* data) } for (i = 0; i < data->nr; i++) { - char *prefix = ""; + const char *prefix = ""; char *name = data->files[i]->name; int added = data->files[i]->added; int deleted = data->files[i]->deleted; @@ -917,7 +917,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) err_empty: err = -1; empty: - s->data = ""; + s->data = (char *)""; s->size = 0; return err; } @@ -1408,7 +1408,7 @@ int diff_setup_done(struct diff_options *options) return 0; } -int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val) +static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val) { char c, *eq; int len; @@ -1720,16 +1720,12 @@ static void diff_flush_raw(struct diff_filepair *p, free((void*)path_two); } -static void diff_flush_name(struct diff_filepair *p, - int inter_name_termination, - int line_termination) +static void diff_flush_name(struct diff_filepair *p, int line_termination) { char *path = p->two->path; if (line_termination) path = quote_one(p->two->path); - else - path = p->two->path; printf("%s%c", path, line_termination); if (p->two->path != path) free(path); @@ -1950,9 +1946,7 @@ static void flush_one_pair(struct diff_filepair *p, options, diff_output_format); break; case DIFF_FORMAT_NAME: - diff_flush_name(p, - inter_name_termination, - line_termination); + diff_flush_name(p, line_termination); break; case DIFF_FORMAT_NO_OUTPUT: break; From 3eaa38da94c7e683163ebf78465b8681d3e8a211 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sat, 24 Jun 2006 22:10:11 +0200 Subject: [PATCH 2/5] apply: replace NO_ACCURATE_DIFF with --inaccurate-eof runtime flag. It does not make much sense to build git whose behaviour is different depending on the brokenness of diff implementation of the platform because the brokenness of the patch that is applied with the tool depends on brokenness of the diff the person who generates the patch uses. So we do not use NO_ACCURATE_DIFF anymore, but help people to apply patches that do not record incomplete lines correctly with a runtime flag. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- builtin-apply.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/builtin-apply.c b/builtin-apply.c index 6dd0472ae0..e9ead002d3 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -125,6 +125,7 @@ struct patch { unsigned long deflate_origlen; int lines_added, lines_deleted; int score; + int inaccurate_eof:1; struct fragment *fragments; char *result; unsigned long resultsize; @@ -1333,7 +1334,8 @@ static int apply_line(char *output, const char *patch, int plen) return plen; } -static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag) +static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, + int inaccurate_eof) { int match_beginning, match_end; char *buf = desc->buffer; @@ -1386,13 +1388,11 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag) size -= len; } -#ifdef NO_ACCURATE_DIFF - if (oldsize > 0 && old[oldsize - 1] == '\n' && + if (inaccurate_eof && oldsize > 0 && old[oldsize - 1] == '\n' && newsize > 0 && new[newsize - 1] == '\n') { oldsize--; newsize--; } -#endif oldlines = old; newlines = new; @@ -1614,7 +1614,7 @@ static int apply_fragments(struct buffer_desc *desc, struct patch *patch) return apply_binary(desc, patch); while (frag) { - if (apply_one_fragment(desc, frag) < 0) + if (apply_one_fragment(desc, frag, patch->inaccurate_eof) < 0) return error("patch failed: %s:%ld", name, frag->oldpos); frag = frag->next; @@ -2097,7 +2097,7 @@ static int use_patch(struct patch *p) return 1; } -static int apply_patch(int fd, const char *filename) +static int apply_patch(int fd, const char *filename, int inaccurate_eof) { unsigned long offset, size; char *buffer = read_patch_file(fd, &size); @@ -2113,6 +2113,7 @@ static int apply_patch(int fd, const char *filename) int nr; patch = xcalloc(1, sizeof(*patch)); + patch->inaccurate_eof = inaccurate_eof; nr = parse_chunk(buffer + offset, size, patch); if (nr < 0) break; @@ -2180,6 +2181,8 @@ int cmd_apply(int argc, const char **argv, char **envp) { int i; int read_stdin = 1; + int inaccurate_eof = 0; + const char *whitespace_option = NULL; for (i = 1; i < argc; i++) { @@ -2188,7 +2191,7 @@ int cmd_apply(int argc, const char **argv, char **envp) int fd; if (!strcmp(arg, "-")) { - apply_patch(0, ""); + apply_patch(0, "", inaccurate_eof); read_stdin = 0; continue; } @@ -2265,6 +2268,10 @@ int cmd_apply(int argc, const char **argv, char **envp) parse_whitespace_option(arg + 13); continue; } + if (!strcmp(arg, "--inaccurate-eof")) { + inaccurate_eof = 1; + continue; + } if (check_index && prefix_length < 0) { prefix = setup_git_directory(); @@ -2281,12 +2288,12 @@ int cmd_apply(int argc, const char **argv, char **envp) usage(apply_usage); read_stdin = 0; set_default_whitespace_mode(whitespace_option); - apply_patch(fd, arg); + apply_patch(fd, arg, inaccurate_eof); close(fd); } set_default_whitespace_mode(whitespace_option); if (read_stdin) - apply_patch(0, ""); + apply_patch(0, "", inaccurate_eof); if (whitespace_error) { if (squelch_whitespace_errors && squelch_whitespace_errors < whitespace_error) { From 817151e61a74241df5b5dd206d27086283f28b84 Mon Sep 17 00:00:00 2001 From: Peter Eriksen Date: Sat, 24 Jun 2006 16:01:25 +0200 Subject: [PATCH 3/5] Rename safe_strncpy() to strlcpy(). This cleans up the use of safe_strncpy() even more. Since it has the same semantics as strlcpy() use this name instead. Also move the definition from inside path.c to its own file compat/strlcpy.c, and use it conditionally at compile time, since some platforms already has strlcpy(). It's included in the same way as compat/setenv.c. Signed-off-by: Peter Eriksen Signed-off-by: Junio C Hamano --- Makefile | 14 ++++++++++++++ builtin-log.c | 2 +- builtin-tar-tree.c | 4 ++-- cache.h | 1 - compat/strlcpy.c | 13 +++++++++++++ config.c | 6 +++--- git-compat-util.h | 5 +++++ http-fetch.c | 6 +++--- http-push.c | 6 +++--- ident.c | 4 ++-- path.c | 15 +-------------- sha1_name.c | 2 +- 12 files changed, 48 insertions(+), 30 deletions(-) create mode 100644 compat/strlcpy.c diff --git a/Makefile b/Makefile index e29e3fa381..cde619c498 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,8 @@ all: # # Define NO_STRCASESTR if you don't have strcasestr. # +# Define NO_STRLCPY if you don't have strlcpy. +# # Define NO_SETENV if you don't have setenv in the C library. # # Define NO_SYMLINK_HEAD if you never want .git/HEAD to be a symbolic link. @@ -240,9 +242,13 @@ LIBS = $(GITLIBS) -lz # because maintaining the nesting to match is a pain. If # we had "elif" things would have been much nicer... +ifeq ($(uname_S),Linux) + NO_STRLCPY = YesPlease +endif ifeq ($(uname_S),Darwin) NEEDS_SSL_WITH_CRYPTO = YesPlease NEEDS_LIBICONV = YesPlease + NO_STRLCPY = YesPlease ## fink ifeq ($(shell test -d /sw/lib && echo y),y) ALL_CFLAGS += -I/sw/include @@ -259,6 +265,7 @@ ifeq ($(uname_S),SunOS) NEEDS_NSL = YesPlease SHELL_PATH = /bin/bash NO_STRCASESTR = YesPlease + NO_STRLCPY = YesPlease ifeq ($(uname_R),5.8) NEEDS_LIBICONV = YesPlease NO_UNSETENV = YesPlease @@ -276,6 +283,7 @@ ifeq ($(uname_O),Cygwin) NO_D_TYPE_IN_DIRENT = YesPlease NO_D_INO_IN_DIRENT = YesPlease NO_STRCASESTR = YesPlease + NO_STRLCPY = YesPlease NO_SYMLINK_HEAD = YesPlease NEEDS_LIBICONV = YesPlease # There are conflicting reports about this. @@ -305,12 +313,14 @@ ifeq ($(uname_S),NetBSD) endif ifeq ($(uname_S),AIX) NO_STRCASESTR=YesPlease + NO_STRLCPY = YesPlease NEEDS_LIBICONV=YesPlease endif ifeq ($(uname_S),IRIX64) NO_IPV6=YesPlease NO_SETENV=YesPlease NO_STRCASESTR=YesPlease + NO_STRLCPY = YesPlease NO_SOCKADDR_STORAGE=YesPlease SHELL_PATH=/usr/gnu/bin/bash ALL_CFLAGS += -DPATH_MAX=1024 @@ -403,6 +413,10 @@ ifdef NO_STRCASESTR COMPAT_CFLAGS += -DNO_STRCASESTR COMPAT_OBJS += compat/strcasestr.o endif +ifdef NO_STRLCPY + COMPAT_CFLAGS += -DNO_STRLCPY + COMPAT_OBJS += compat/strlcpy.o +endif ifdef NO_SETENV COMPAT_CFLAGS += -DNO_SETENV COMPAT_OBJS += compat/setenv.o diff --git a/builtin-log.c b/builtin-log.c index 5a8a50b81d..44d2d136f5 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -115,7 +115,7 @@ static void reopen_stdout(struct commit *commit, int nr, int keep_subject) int len = 0; if (output_directory) { - safe_strncpy(filename, output_directory, 1010); + strlcpy(filename, output_directory, 1010); len = strlen(filename); if (filename[len - 1] != '/') filename[len++] = '/'; diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c index 39a61b6293..f2e48aae2a 100644 --- a/builtin-tar-tree.c +++ b/builtin-tar-tree.c @@ -233,8 +233,8 @@ static void write_entry(const unsigned char *sha1, struct strbuf *path, /* XXX: should we provide more meaningful info here? */ sprintf(header.uid, "%07o", 0); sprintf(header.gid, "%07o", 0); - safe_strncpy(header.uname, "git", sizeof(header.uname)); - safe_strncpy(header.gname, "git", sizeof(header.gname)); + strlcpy(header.uname, "git", sizeof(header.uname)); + strlcpy(header.gname, "git", sizeof(header.gname)); sprintf(header.devmajor, "%07o", 0); sprintf(header.devminor, "%07o", 0); diff --git a/cache.h b/cache.h index efeafea70f..14358a872c 100644 --- a/cache.h +++ b/cache.h @@ -216,7 +216,6 @@ enum sharedrepo { int git_config_perm(const char *var, const char *value); int adjust_shared_perm(const char *path); int safe_create_leading_directories(char *path); -size_t safe_strncpy(char *, const char *, size_t); char *enter_repo(char *path, int strict); /* Read and unpack a sha1 file into memory, write memory to a sha1 file */ diff --git a/compat/strlcpy.c b/compat/strlcpy.c new file mode 100644 index 0000000000..b66856a3a5 --- /dev/null +++ b/compat/strlcpy.c @@ -0,0 +1,13 @@ +#include + +size_t gitstrlcpy(char *dest, const char *src, size_t size) +{ + size_t ret = strlen(src); + + if (size) { + size_t len = (ret >= size) ? size - 1 : ret; + memcpy(dest, src, len); + dest[len] = '\0'; + } + return ret; +} diff --git a/config.c b/config.c index 3e077d4c6c..ec44827da4 100644 --- a/config.c +++ b/config.c @@ -280,17 +280,17 @@ int git_default_config(const char *var, const char *value) } if (!strcmp(var, "user.name")) { - safe_strncpy(git_default_name, value, sizeof(git_default_name)); + strlcpy(git_default_name, value, sizeof(git_default_name)); return 0; } if (!strcmp(var, "user.email")) { - safe_strncpy(git_default_email, value, sizeof(git_default_email)); + strlcpy(git_default_email, value, sizeof(git_default_email)); return 0; } if (!strcmp(var, "i18n.commitencoding")) { - safe_strncpy(git_commit_encoding, value, sizeof(git_commit_encoding)); + strlcpy(git_commit_encoding, value, sizeof(git_commit_encoding)); return 0; } diff --git a/git-compat-util.h b/git-compat-util.h index b3d4cf532e..93f558056d 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -79,6 +79,11 @@ extern void gitunsetenv(const char *); extern char *gitstrcasestr(const char *haystack, const char *needle); #endif +#ifdef NO_STRLCPY +#define strlcpy gitstrlcpy +extern size_t gitstrlcpy(char *, const char *, size_t); +#endif + static inline void *xmalloc(size_t size) { void *ret = malloc(size); diff --git a/http-fetch.c b/http-fetch.c index 2b63d89501..44eba5fd0d 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -584,8 +584,8 @@ static void process_alternates_response(void *callback_data) // skip 'objects' at end if (okay) { target = xmalloc(serverlen + posn - i - 6); - safe_strncpy(target, base, serverlen); - safe_strncpy(target + serverlen, data + i, posn - i - 6); + strlcpy(target, base, serverlen); + strlcpy(target + serverlen, data + i, posn - i - 6); if (get_verbosely) fprintf(stderr, "Also look at %s\n", target); @@ -727,7 +727,7 @@ xml_cdata(void *userData, const XML_Char *s, int len) if (ctx->cdata) free(ctx->cdata); ctx->cdata = xmalloc(len + 1); - safe_strncpy(ctx->cdata, s, len + 1); + strlcpy(ctx->cdata, s, len + 1); } static int remote_ls(struct alt_base *repo, const char *path, int flags, diff --git a/http-push.c b/http-push.c index 8d472f0202..3c89a17496 100644 --- a/http-push.c +++ b/http-push.c @@ -1271,7 +1271,7 @@ xml_cdata(void *userData, const XML_Char *s, int len) if (ctx->cdata) free(ctx->cdata); ctx->cdata = xmalloc(len + 1); - safe_strncpy(ctx->cdata, s, len + 1); + strlcpy(ctx->cdata, s, len + 1); } static struct remote_lock *lock_remote(char *path, long timeout) @@ -1473,7 +1473,7 @@ static void process_ls_object(struct remote_ls_ctx *ls) return; path += 8; obj_hex = xmalloc(strlen(path)); - safe_strncpy(obj_hex, path, 3); + strlcpy(obj_hex, path, 3); strcpy(obj_hex + 2, path + 3); one_remote_object(obj_hex); free(obj_hex); @@ -2172,7 +2172,7 @@ static void fetch_symref(char *path, char **symref, unsigned char *sha1) /* If it's a symref, set the refname; otherwise try for a sha1 */ if (!strncmp((char *)buffer.buffer, "ref: ", 5)) { *symref = xmalloc(buffer.posn - 5); - safe_strncpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 5); + strlcpy(*symref, (char *)buffer.buffer + 5, buffer.posn - 5); } else { get_sha1_hex(buffer.buffer, sha1); } diff --git a/ident.c b/ident.c index 7b44cbd2cc..efec97ffd0 100644 --- a/ident.c +++ b/ident.c @@ -71,9 +71,9 @@ int setup_ident(void) len = strlen(git_default_email); git_default_email[len++] = '.'; if (he && (domainname = strchr(he->h_name, '.'))) - safe_strncpy(git_default_email + len, domainname + 1, sizeof(git_default_email) - len); + strlcpy(git_default_email + len, domainname + 1, sizeof(git_default_email) - len); else - safe_strncpy(git_default_email + len, "(none)", sizeof(git_default_email) - len); + strlcpy(git_default_email + len, "(none)", sizeof(git_default_email) - len); } /* And set the default date */ datestamp(git_default_date, sizeof(git_default_date)); diff --git a/path.c b/path.c index 36972fd6df..db8905f3c3 100644 --- a/path.c +++ b/path.c @@ -77,25 +77,12 @@ int git_mkstemp(char *path, size_t len, const char *template) pch += n; } - safe_strncpy(pch, template, len); + strlcpy(pch, template, len); return mkstemp(path); } -size_t safe_strncpy(char *dest, const char *src, size_t size) -{ - size_t ret = strlen(src); - - if (size) { - size_t len = (ret >= size) ? size - 1 : ret; - memcpy(dest, src, len); - dest[len] = '\0'; - } - return ret; -} - - int validate_symref(const char *path) { struct stat st; diff --git a/sha1_name.c b/sha1_name.c index cd85d1fa0f..f2cbafa496 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -262,7 +262,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1) if (str[am] == '@' && str[am+1] == '{' && str[len-1] == '}') { int date_len = len - am - 3; char *date_spec = xmalloc(date_len + 1); - safe_strncpy(date_spec, str + am + 2, date_len + 1); + strlcpy(date_spec, str + am + 2, date_len + 1); at_time = approxidate(date_spec); free(date_spec); len = am; From 29f4ad867cd15f4029c280c417f4a0866d5229a9 Mon Sep 17 00:00:00 2001 From: Yann Dirson Date: Sat, 24 Jun 2006 00:04:05 +0200 Subject: [PATCH 4/5] git-commit: filter out log message lines only when editor was run. The current behaviour strips out lines starting with a # even when fed through stdin or -m. This is particularly bad when importing history from another SCM (tailor 0.9.23 uses git-commit). In the best cases all lines are stripped and the commit fails with a confusing "empty log message" error, but in many cases the commit is done, with loss of information. Note that it is quite peculiar to just have "#" handled as a leading comment char here. One commonly meet CVS: or CG: or STG: as prefixes, and using GIT: would be more robust as well as consistent with other commit tools. However, that would break any tool relying on the # (if any). Signed-off-by: Yann Dirson Signed-off-by: Junio C Hamano --- git-commit.sh | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/git-commit.sh b/git-commit.sh index e74fe640b8..128db6c52a 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -693,13 +693,18 @@ t) fi esac -sed -e ' - /^diff --git a\/.*/{ - s/// - q - } - /^#/d -' "$GIT_DIR"/COMMIT_EDITMSG | +if test -z "$no_edit" +then + sed -e ' + /^diff --git a\/.*/{ + s/// + q + } + /^#/d + ' "$GIT_DIR"/COMMIT_EDITMSG +else + cat "$GIT_DIR"/COMMIT_EDITMSG +fi | git-stripspace >"$GIT_DIR"/COMMIT_MSG if cnt=`grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG | From 801235c5e6bff0ec1c4e41c9d46535ead3b693c1 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 24 Jun 2006 04:06:23 -0700 Subject: [PATCH 5/5] diff --color: use $GIT_DIR/config This lets you use something like this in your $GIT_DIR/config file. [diff] color = auto [diff.color] new = blue old = yellow frag = reverse When diff.color is set to "auto", colored diff is enabled when the standard output is the terminal. Other choices are "always", and "never". Usual boolean true/false can also be used. The colormap entries can specify colors for the following slots: plain - lines that appear in both old and new file (context) meta - diff --git header and extended git diff headers frag - @@ -n,m +l,k @@ lines (hunk header) old - lines deleted from old file new - lines added to new file The following color names can be used: normal, bold, dim, l, blink, reverse, reset, black, red, green, yellow, blue, magenta, cyan, white Signed-off-by: Junio C Hamano --- cache.h | 1 - diff.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 80 insertions(+), 15 deletions(-) diff --git a/cache.h b/cache.h index 14358a872c..87199396a0 100644 --- a/cache.h +++ b/cache.h @@ -181,7 +181,6 @@ extern int assume_unchanged; extern int prefer_symlink_refs; extern int log_all_ref_updates; extern int warn_ambiguous_refs; -extern int diff_rename_limit_default; extern int shared_repository; extern const char *apply_default_whitespace; diff --git a/diff.c b/diff.c index 834b166064..e73c0c3008 100644 --- a/diff.c +++ b/diff.c @@ -13,17 +13,8 @@ static int use_size_cache; -int diff_rename_limit_default = -1; - -int git_diff_config(const char *var, const char *value) -{ - if (!strcmp(var, "diff.renamelimit")) { - diff_rename_limit_default = git_config_int(var, value); - return 0; - } - - return git_default_config(var, value); -} +static int diff_rename_limit_default = -1; +static int diff_use_color_default = 0; enum color_diff { DIFF_RESET = 0, @@ -51,9 +42,6 @@ enum color_diff { #define COLOR_CYAN "\033[36m" #define COLOR_WHITE "\033[37m" -#define COLOR_CYANBG "\033[46m" -#define COLOR_GRAYBG "\033[47m" // Good for xterm - static const char *diff_colors[] = { [DIFF_RESET] = COLOR_RESET, [DIFF_PLAIN] = COLOR_NORMAL, @@ -63,6 +51,83 @@ static const char *diff_colors[] = { [DIFF_FILE_NEW] = COLOR_GREEN, }; +static int parse_diff_color_slot(const char *var, int ofs) +{ + if (!strcasecmp(var+ofs, "plain")) + return DIFF_PLAIN; + if (!strcasecmp(var+ofs, "meta")) + return DIFF_METAINFO; + if (!strcasecmp(var+ofs, "frag")) + return DIFF_FRAGINFO; + if (!strcasecmp(var+ofs, "old")) + return DIFF_FILE_OLD; + if (!strcasecmp(var+ofs, "new")) + return DIFF_FILE_NEW; + die("bad config variable '%s'", var); +} + +static const char *parse_diff_color_value(const char *value, const char *var) +{ + if (!strcasecmp(value, "normal")) + return COLOR_NORMAL; + if (!strcasecmp(value, "bold")) + return COLOR_BOLD; + if (!strcasecmp(value, "dim")) + return COLOR_DIM; + if (!strcasecmp(value, "ul")) + return COLOR_UL; + if (!strcasecmp(value, "blink")) + return COLOR_BLINK; + if (!strcasecmp(value, "reverse")) + return COLOR_REVERSE; + if (!strcasecmp(value, "reset")) + return COLOR_RESET; + if (!strcasecmp(value, "black")) + return COLOR_BLACK; + if (!strcasecmp(value, "red")) + return COLOR_RED; + if (!strcasecmp(value, "green")) + return COLOR_GREEN; + if (!strcasecmp(value, "yellow")) + return COLOR_YELLOW; + if (!strcasecmp(value, "blue")) + return COLOR_BLUE; + if (!strcasecmp(value, "magenta")) + return COLOR_MAGENTA; + if (!strcasecmp(value, "cyan")) + return COLOR_CYAN; + if (!strcasecmp(value, "white")) + return COLOR_WHITE; + die("bad config value '%s' for variable '%s'", value, var); +} + +int git_diff_config(const char *var, const char *value) +{ + if (!strcmp(var, "diff.renamelimit")) { + diff_rename_limit_default = git_config_int(var, value); + return 0; + } + if (!strcmp(var, "diff.color")) { + if (!value) + diff_use_color_default = 1; /* bool */ + else if (!strcasecmp(value, "auto")) + diff_use_color_default = isatty(1); + else if (!strcasecmp(value, "never")) + diff_use_color_default = 0; + else if (!strcasecmp(value, "always")) + diff_use_color_default = 1; + else + diff_use_color_default = git_config_bool(var, value); + return 0; + } + if (!strncmp(var, "diff.color.", 11)) { + int slot = parse_diff_color_slot(var, 11); + diff_colors[slot] = parse_diff_color_value(value, var); + return 0; + } + return git_default_config(var, value); +} + static char *quote_one(const char *str) { int needlen; @@ -1362,6 +1427,7 @@ void diff_setup(struct diff_options *options) options->change = diff_change; options->add_remove = diff_addremove; + options->color_diff = diff_use_color_default; } int diff_setup_done(struct diff_options *options)