X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=diff.c;h=890bdaa6b8a22dad667807cc3d835ccd9fb8056a;hb=687dd75c95f9212244b6cf4fe60b40db44de01ba;hp=2e0797bf3ee651a644be50aee10ee125fe96368f;hpb=5e80092f7e6db09a40a62e837ca3f74f0bc5ad73;p=git.git diff --git a/diff.c b/diff.c index 2e0797bf..890bdaa6 100644 --- a/diff.c +++ b/diff.c @@ -504,9 +504,9 @@ static void prepare_temp_file(const char *name, } if (S_ISLNK(st.st_mode)) { int ret; - char *buf, buf_[1024]; - buf = ((sizeof(buf_) < st.st_size) ? - xmalloc(st.st_size) : buf_); + char buf[PATH_MAX + 1]; /* ought to be SYMLINK_MAX */ + if (sizeof(buf) <= st.st_size) + die("symlink too long: %s", name); ret = readlink(name, buf, st.st_size); if (ret < 0) die("readlink(%s)", name); @@ -555,6 +555,8 @@ static void remove_tempfile(void) static void remove_tempfile_on_signal(int signo) { remove_tempfile(); + signal(SIGINT, SIG_DFL); + raise(signo); } /* An external diff command takes: @@ -650,7 +652,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one) if (DIFF_FILE_VALID(one)) { if (!one->sha1_valid) { struct stat st; - if (stat(one->path, &st) < 0) + if (lstat(one->path, &st) < 0) die("stat %s", one->path); if (index_path(one->sha1, one->path, &st, 0)) die("cannot hash %s\n", one->path); @@ -723,11 +725,13 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o) if (memcmp(one->sha1, two->sha1, 20)) { char one_sha1[41]; - const char *index_fmt = o->full_index ? "index %s..%s" : "index %.7s..%.7s"; + int abbrev = o->full_index ? 40 : DEFAULT_ABBREV; memcpy(one_sha1, sha1_to_hex(one->sha1), 41); len += snprintf(msg + len, sizeof(msg) - len, - index_fmt, one_sha1, sha1_to_hex(two->sha1)); + "index %.*s..%.*s", + abbrev, one_sha1, abbrev, + sha1_to_hex(two->sha1)); if (one->mode == two->mode) len += snprintf(msg + len, sizeof(msg) - len, " %06o", one->mode); @@ -785,12 +789,14 @@ int diff_setup_done(struct diff_options *options) * so it is safe for us to do this here. Also * it does not smudge active_cache or active_nr * when it fails, so we do not have to worry about - * cleaning it up oufselves either. + * cleaning it up ourselves either. */ read_cache(); } if (options->setup & DIFF_SETUP_USE_SIZE_CACHE) use_size_cache = 1; + if (options->abbrev <= 0 || 40 < options->abbrev) + options->abbrev = 40; /* full */ return 0; } @@ -841,6 +847,15 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) } else if (!strcmp(arg, "--find-copies-harder")) options->find_copies_harder = 1; + else if (!strcmp(arg, "--abbrev")) + options->abbrev = DEFAULT_ABBREV; + else if (!strncmp(arg, "--abbrev=", 9)) { + options->abbrev = strtoul(arg + 9, NULL, 10); + if (options->abbrev < MINIMUM_ABBREV) + options->abbrev = MINIMUM_ABBREV; + else if (40 < options->abbrev) + options->abbrev = 40; + } else return 0; return 1; @@ -947,14 +962,41 @@ void diff_free_filepair(struct diff_filepair *p) free(p); } +/* This is different from find_unique_abbrev() in that + * it stuffs the result with dots for alignment. + */ +const char *diff_unique_abbrev(const unsigned char *sha1, int len) +{ + int abblen; + const char *abbrev; + if (len == 40) + return sha1_to_hex(sha1); + + abbrev = find_unique_abbrev(sha1, len); + if (!abbrev) + return sha1_to_hex(sha1); + abblen = strlen(abbrev); + if (abblen < 37) { + static char hex[41]; + if (len < abblen && abblen <= len + 2) + sprintf(hex, "%s%.*s", abbrev, len+3-abblen, ".."); + else + sprintf(hex, "%s...", abbrev); + return hex; + } + return sha1_to_hex(sha1); +} + static void diff_flush_raw(struct diff_filepair *p, int line_termination, int inter_name_termination, - int output_format) + struct diff_options *options) { int two_paths; char status[10]; + int abbrev = options->abbrev; const char *path_one, *path_two; + int output_format = options->output_format; path_one = p->one->path; path_two = p->two->path; @@ -985,8 +1027,10 @@ static void diff_flush_raw(struct diff_filepair *p, } if (output_format != DIFF_FORMAT_NAME_STATUS) { printf(":%06o %06o %s ", - p->one->mode, p->two->mode, sha1_to_hex(p->one->sha1)); - printf("%s ", sha1_to_hex(p->two->sha1)); + p->one->mode, p->two->mode, + diff_unique_abbrev(p->one->sha1, abbrev)); + printf("%s ", + diff_unique_abbrev(p->two->sha1, abbrev)); } printf("%s%c%s", status, inter_name_termination, path_one); if (two_paths) @@ -1194,7 +1238,7 @@ void diff_flush(struct diff_options *options) case DIFF_FORMAT_NAME_STATUS: diff_flush_raw(p, line_termination, inter_name_termination, - diff_output_format); + options); break; case DIFF_FORMAT_NAME: diff_flush_name(p,