From: Junio C Hamano Date: Wed, 4 Jul 2007 05:56:59 +0000 (-0700) Subject: Merge branch 'maint' X-Git-Tag: v1.5.3-rc1~95 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/e2b1accc59ab5d682d71fd801ebe959c3e871488?ds=inline;hp=-c Merge branch 'maint' * maint: Document - for git-format-patch glossary: add 'reflog' diff --no-index: fix --name-status with added files Don't smash stack when $GIT_ALTERNATE_OBJECT_DIRECTORIES is too long --- e2b1accc59ab5d682d71fd801ebe959c3e871488 diff --combined Documentation/git-format-patch.txt index e5638102ec,0ca58a7eb3..6cbcf937bc --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@@ -11,8 -11,7 +11,8 @@@ SYNOPSI [verse] 'git-format-patch' [-n | -k] [-o | --stdout] [--thread] [--attach[=] | --inline[=]] - [-s | --signoff] [] [--start-number ] + [-s | --signoff] [] + [--start-number ] [--numbered-files] [--in-reply-to=Message-Id] [--suffix=.] [--ignore-if-in-upstream] [--subject-prefix=Subject-Prefix] @@@ -31,11 -30,9 +31,11 @@@ gitlink:git-rev-parse[1] The output of this command is convenient for e-mail submission or for use with gitlink:git-am[1]. -Each output file is numbered sequentially from 1, and uses the +By default, each output file is numbered sequentially from 1, and uses the first line of the commit message (massaged for pathname safety) as -the filename. The names of the output files are printed to standard +the filename. With the --numbered-files option, the output file names +will only be numbers, without the first line of the commit appended. +The names of the output files are printed to standard output, unless the --stdout option is specified. If -o is specified, output files are created in . Otherwise @@@ -53,6 -50,9 +53,9 @@@ OPTION ------- include::diff-options.txt[] + -:: + Limits the number of patches to prepare. + -o|--output-directory :: Use to store the resulting files, instead of the current working directory. @@@ -63,11 -63,6 +66,11 @@@ --start-number :: Start numbering the patches at instead of 1. +--numbered-files:: + Output file names will be a simple number sequence + without the default first line of the commit appended. + Mutually exclusive with the --stdout option. + -k|--keep-subject:: Do not strip/add '[PATCH]' from the first line of the commit log message. @@@ -126,13 -121,12 +129,13 @@@ not add any suffix CONFIGURATION ------------- You can specify extra mail header lines to be added to each -message in the repository configuration. Also you can specify -the default suffix different from the built-in one: +message in the repository configuration. You can also specify +new defaults for the subject prefix and file suffix. ------------ [format] headers = "Organization: git-foo\n" + subjectprefix = CHANGE suffix = .txt ------------ @@@ -179,3 -173,4 +182,3 @@@ Documentation by Junio C Hamano and th GIT --- Part of the gitlink:git[7] suite - diff --combined diff.c index b6eb72be02,da992dd485..19589707c4 --- a/diff.c +++ b/diff.c @@@ -1460,7 -1460,7 +1460,7 @@@ int diff_populate_filespec(struct diff_ if (size_only && 0 < s->size) return 0; - if (S_ISDIRLNK(s->mode)) + if (S_ISGITLINK(s->mode)) return diff_populate_gitlink(s, size_only); if (!s->sha1_valid || @@@ -1813,11 -1813,6 +1813,11 @@@ static void diff_fill_sha1_info(struct hashclr(one->sha1); } +static int similarity_index(struct diff_filepair *p) +{ + return p->score * 100 / MAX_SCORE; +} + static void run_diff(struct diff_filepair *p, struct diff_options *o) { const char *pgm = external_diff(); @@@ -1852,20 -1847,23 +1852,20 @@@ "similarity index %d%%\n" "copy from %s\n" "copy to %s\n", - (int)(0.5 + p->score * 100.0/MAX_SCORE), - name_munged, other_munged); + similarity_index(p), name_munged, other_munged); break; case DIFF_STATUS_RENAMED: len += snprintf(msg + len, sizeof(msg) - len, "similarity index %d%%\n" "rename from %s\n" "rename to %s\n", - (int)(0.5 + p->score * 100.0/MAX_SCORE), - name_munged, other_munged); + similarity_index(p), name_munged, other_munged); break; case DIFF_STATUS_MODIFIED: if (p->score) { len += snprintf(msg + len, sizeof(msg) - len, "dissimilarity index %d%%\n", - (int)(0.5 + p->score * - 100.0/MAX_SCORE)); + similarity_index(p)); complete_rewrite = 1; break; } @@@ -2105,8 -2103,6 +2105,8 @@@ static int opt_arg(const char *arg, in return 1; } +static int diff_scoreopt_parse(const char *opt); + int diff_opt_parse(struct diff_options *options, const char **av, int ac) { const char *arg = av[0]; @@@ -2203,8 -2199,6 +2203,8 @@@ options->detect_rename = DIFF_DETECT_RENAME; } else if (!prefixcmp(arg, "-C")) { + if (options->detect_rename == DIFF_DETECT_COPY) + options->find_copies_harder = 1; if ((options->rename_score = diff_scoreopt_parse(arg)) == -1) return -1; @@@ -2212,8 -2206,6 +2212,8 @@@ } else if (!strcmp(arg, "--find-copies-harder")) options->find_copies_harder = 1; + else if (!strcmp(arg, "--follow")) + options->follow_renames = 1; else if (!strcmp(arg, "--abbrev")) options->abbrev = DEFAULT_ABBREV; else if (!prefixcmp(arg, "--abbrev=")) { @@@ -2241,10 -2233,6 +2241,10 @@@ options->exit_with_status = 1; else if (!strcmp(arg, "--quiet")) options->quiet = 1; + else if (!strcmp(arg, "--ext-diff")) + options->allow_external = 1; + else if (!strcmp(arg, "--no-ext-diff")) + options->allow_external = 0; else return 0; return 1; @@@ -2286,7 -2274,7 +2286,7 @@@ static int parse_num(const char **cp_p return (int)((num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale)); } -int diff_scoreopt_parse(const char *opt) +static int diff_scoreopt_parse(const char *opt) { int opt1, opt2, cmd; @@@ -2393,7 -2381,8 +2393,7 @@@ static void diff_flush_raw(struct diff_ } if (p->score) - sprintf(status, "%c%03d", p->status, - (int)(0.5 + p->score * 100.0/MAX_SCORE)); + sprintf(status, "%c%03d", p->status, similarity_index(p)); else { status[0] = p->status; status[1] = 0; @@@ -2418,7 -2407,8 +2418,8 @@@ printf("%s ", diff_unique_abbrev(p->two->sha1, abbrev)); } - printf("%s%c%s", status, inter_name_termination, path_one); + printf("%s%c%s", status, inter_name_termination, + two_paths || p->one->mode ? path_one : path_two); if (two_paths) printf("%c%s", inter_name_termination, path_two); putchar(line_termination); @@@ -2675,7 -2665,8 +2676,7 @@@ static void show_rename_copy(const cha { char *names = pprint_rename(p->one->path, p->two->path); - printf(" %s %s (%d%%)\n", renamecopy, names, - (int)(0.5 + p->score * 100.0/MAX_SCORE)); + printf(" %s %s (%d%%)\n", renamecopy, names, similarity_index(p)); free(names); show_mode_change(p, 0); } @@@ -2699,7 -2690,7 +2700,7 @@@ static void diff_summary(struct diff_fi if (p->score) { char *name = quote_one(p->two->path); printf(" rewrite %s (%d%%)\n", name, - (int)(0.5 + p->score * 100.0/MAX_SCORE)); + similarity_index(p)); free(name); show_mode_change(p, 0); } else show_mode_change(p, 1); @@@ -3009,22 -3000,6 +3010,22 @@@ void diffcore_std(struct diff_options * { if (options->quiet) return; + + /* + * break/rename count similarity differently depending on + * the binary-ness. + */ + if ((options->break_opt != -1) || (options->detect_rename)) { + struct diff_queue_struct *q = &diff_queued_diff; + int i; + + for (i = 0; i < q->nr; i++) { + struct diff_filepair *p = q->queue[i]; + p->one->is_binary = file_is_binary(p->one); + p->two->is_binary = file_is_binary(p->two); + } + } + if (options->break_opt != -1) diffcore_break(options->break_opt); if (options->detect_rename) @@@ -3057,7 -3032,7 +3058,7 @@@ void diff_addremove(struct diff_option * entries to the diff-core. They will be prefixed * with something like '=' or '*' (I haven't decided * which but should not make any difference). - * Feeding the same new and old to diff_change() + * Feeding the same new and old to diff_change() * also has the same effect. * Before the final output happens, they are pruned after * merged into rename/copy pairs as appropriate. @@@ -3084,7 -3059,7 +3085,7 @@@ void diff_change(struct diff_options *o unsigned old_mode, unsigned new_mode, const unsigned char *old_sha1, const unsigned char *new_sha1, - const char *base, const char *path) + const char *base, const char *path) { char concatpath[PATH_MAX]; struct diff_filespec *one, *two; diff --combined sha1_file.c index f2b1ae0325,1d328c8d61..1efd9ae19a --- a/sha1_file.c +++ b/sha1_file.c @@@ -193,7 -193,7 +193,7 @@@ char *sha1_pack_name(const unsigned cha *buf++ = hex[val >> 4]; *buf++ = hex[val & 0xf]; } - + return base; } @@@ -218,7 -218,7 +218,7 @@@ char *sha1_pack_index_name(const unsign *buf++ = hex[val >> 4]; *buf++ = hex[val & 0xf]; } - + return base; } @@@ -352,10 -352,14 +352,14 @@@ static void read_info_alternates(const char *map; size_t mapsz; struct stat st; - char path[PATH_MAX]; + const char alt_file_name[] = "info/alternates"; + /* Given that relative_base is no longer than PATH_MAX, + ensure that "path" has enough space to append "/", the + file name, "info/alternates", and a trailing NUL. */ + char path[PATH_MAX + 1 + sizeof alt_file_name]; int fd; - sprintf(path, "%s/info/alternates", relative_base); + sprintf(path, "%s/%s", relative_base, alt_file_name); fd = open(path, O_RDONLY); if (fd < 0) return; @@@ -376,12 -380,11 +380,12 @@@ void prepare_alt_odb(void { const char *alt; + if (alt_odb_tail) + return; + alt = getenv(ALTERNATE_DB_ENVIRONMENT); if (!alt) alt = ""; - if (alt_odb_tail) - return; alt_odb_tail = &alt_odb_list; link_alt_odb_entries(alt, alt + strlen(alt), ':', NULL, 0); @@@ -413,7 -416,7 +417,7 @@@ static size_t peak_pack_mapped static size_t pack_mapped; struct packed_git *packed_git; -void pack_report() +void pack_report(void) { fprintf(stderr, "pack_report: getpagesize() = %10" SZ_FMT "\n" @@@ -534,21 -537,6 +538,21 @@@ static int check_packed_git_idx(const c return 0; } +int open_pack_index(struct packed_git *p) +{ + char *idx_name; + int ret; + + if (p->index_data) + return 0; + + idx_name = xstrdup(p->pack_name); + strcpy(idx_name + strlen(idx_name) - strlen(".pack"), ".idx"); + ret = check_packed_git_idx(idx_name, p); + free(idx_name); + return ret; +} + static void scan_windows(struct packed_git *p, struct packed_git **lru_p, struct pack_window **lru_w, @@@ -624,9 -612,6 +628,9 @@@ static int open_packed_git_1(struct pac unsigned char *idx_sha1; long fd_flag; + if (!p->index_data && open_pack_index(p)) + return error("packfile %s index unavailable", p->pack_name); + p->pack_fd = open(p->pack_name, O_RDONLY); if (p->pack_fd < 0 || fstat(p->pack_fd, &st)) return -1; @@@ -779,7 -764,8 +783,7 @@@ struct packed_git *add_packed_git(cons return NULL; memcpy(p->pack_name, path, path_len); strcpy(p->pack_name + path_len, ".pack"); - if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode) || - check_packed_git_idx(path, p)) { + if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) { free(p); return NULL; } @@@ -787,10 -773,6 +791,10 @@@ /* ok, it looks sane as far as we can check without * actually mapping the pack file. */ + p->index_version = 0; + p->index_data = NULL; + p->index_size = 0; + p->num_objects = 0; p->pack_size = st.st_size; p->next = NULL; p->windows = NULL; @@@ -836,7 -818,10 +840,10 @@@ void install_packed_git(struct packed_g static void prepare_packed_git_one(char *objdir, int local) { - char path[PATH_MAX]; + /* Ensure that this buffer is large enough so that we can + append "/pack/" without clobbering the stack even if + strlen(objdir) were PATH_MAX. */ + char path[PATH_MAX + 1 + 4 + 1 + 1]; int len; DIR *dir; struct dirent *de; @@@ -858,6 -843,9 +865,9 @@@ if (!has_extension(de->d_name, ".idx")) continue; + if (len + namelen + 1 > sizeof(path)) + continue; + /* Don't reopen a pack we already have. */ strcpy(path + len, de->d_name); for (p = packed_git; p; p = p->next) { @@@ -962,7 -950,7 +972,7 @@@ int check_sha1_signature(const unsigne return hashcmp(sha1, real_sha1) ? -1 : 0; } -void *map_sha1_file(const unsigned char *sha1, unsigned long *size) +static void *map_sha1_file(const unsigned char *sha1, unsigned long *size) { struct stat st; void *map; @@@ -997,7 -985,7 +1007,7 @@@ return map; } -int legacy_loose_object(unsigned char *map) +static int legacy_loose_object(unsigned char *map) { unsigned int word; @@@ -1059,14 -1047,6 +1069,14 @@@ static int unpack_sha1_header(z_stream return inflate(stream, 0); } + + /* + * There used to be a second loose object header format which + * was meant to mimic the in-pack format, allowing for direct + * copy of the object data. This format turned up not to be + * really worth it and we don't write it any longer. But we + * can still read it. + */ used = unpack_object_header_gently(map, mapsize, &type, &size); if (!used || !valid_loose_object_type[type]) return -1; @@@ -1142,7 -1122,7 +1152,7 @@@ static int parse_sha1_header(const cha unsigned long size; /* - * The type can be at most ten bytes (including the + * The type can be at most ten bytes (including the * terminating '\0' that we add), and is followed by * a space. */ @@@ -1597,15 -1577,10 +1607,15 @@@ void *unpack_entry(struct packed_git *p return data; } -const unsigned char *nth_packed_object_sha1(const struct packed_git *p, +const unsigned char *nth_packed_object_sha1(struct packed_git *p, uint32_t n) { const unsigned char *index = p->index_data; + if (!index) { + if (open_pack_index(p)) + return NULL; + index = p->index_data; + } if (n >= p->num_objects) return NULL; index += 4 * 256; @@@ -1642,12 -1617,6 +1652,12 @@@ off_t find_pack_entry_one(const unsigne const unsigned char *index = p->index_data; unsigned hi, lo; + if (!index) { + if (open_pack_index(p)) + return 0; + level1_ofs = p->index_data; + index = p->index_data; + } if (p->index_version > 1) { level1_ofs += 2; index += 8; @@@ -1690,25 -1659,20 +1700,25 @@@ static int matches_pack_name(struct pac static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed) { + static struct packed_git *last_found = (void *)1; struct packed_git *p; off_t offset; prepare_packed_git(); + if (!packed_git) + return 0; + p = (last_found == (void *)1) ? packed_git : last_found; - for (p = packed_git; p; p = p->next) { + do { if (ignore_packed) { const char **ig; for (ig = ignore_packed; *ig; ig++) if (!matches_pack_name(p, *ig)) break; if (*ig) - continue; + goto next; } + offset = find_pack_entry_one(sha1, p); if (offset) { /* @@@ -1721,27 -1685,18 +1731,27 @@@ */ if (p->pack_fd == -1 && open_packed_git(p)) { error("packfile %s cannot be accessed", p->pack_name); - continue; + goto next; } e->offset = offset; e->p = p; hashcpy(e->sha1, sha1); + last_found = p; return 1; } - } + + next: + if (p == last_found) + p = packed_git; + else + p = p->next; + if (p == last_found) + p = p->next; + } while (p); return 0; } -struct packed_git *find_sha1_pack(const unsigned char *sha1, +struct packed_git *find_sha1_pack(const unsigned char *sha1, struct packed_git *packs) { struct packed_git *p; @@@ -2020,6 -1975,40 +2030,6 @@@ static int write_buffer(int fd, const v return 0; } -static int write_binary_header(unsigned char *hdr, enum object_type type, unsigned long len) -{ - int hdr_len; - unsigned char c; - - c = (type << 4) | (len & 15); - len >>= 4; - hdr_len = 1; - while (len) { - *hdr++ = c | 0x80; - hdr_len++; - c = (len & 0x7f); - len >>= 7; - } - *hdr = c; - return hdr_len; -} - -static void setup_object_header(z_stream *stream, const char *type, unsigned long len) -{ - int obj_type, hdrlen; - - if (use_legacy_headers) { - while (deflate(stream, 0) == Z_OK) - /* nothing */; - return; - } - obj_type = type_from_string(type); - hdrlen = write_binary_header(stream->next_out, obj_type, len); - stream->total_out = hdrlen; - stream->next_out += hdrlen; - stream->avail_out -= hdrlen; -} - int hash_sha1_file(const void *buf, unsigned long len, const char *type, unsigned char *sha1) { @@@ -2086,8 -2075,7 +2096,8 @@@ int write_sha1_file(void *buf, unsigne /* First header.. */ stream.next_in = (unsigned char *)hdr; stream.avail_in = hdrlen; - setup_object_header(&stream, type, len); + while (deflate(&stream, 0) == Z_OK) + /* nothing */; /* Then the data itself.. */ stream.next_in = buf; diff --combined t/t4013-diff-various.sh index b453b42af7,4e7d68dda2..9eec754221 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@@ -17,6 -17,7 +17,7 @@@ test_expect_success setup export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && mkdir dir && + mkdir dir2 && for i in 1 2 3; do echo $i; done >file0 && for i in A B; do echo $i; done >dir/sub && cat file0 >file2 && @@@ -242,8 -243,6 +243,8 @@@ format-patch --inline --stdout initial. format-patch --inline --stdout initial..master^ format-patch --inline --stdout initial..master format-patch --inline --stdout --subject-prefix=TESTCASE initial..master +config format.subjectprefix DIFFERENT_PREFIX +format-patch --inline --stdout initial..master^^ diff --abbrev initial..side diff -r initial..side @@@ -254,6 -253,7 +255,7 @@@ diff --patch-with-stat initial..sid diff --patch-with-raw initial..side diff --patch-with-stat -r initial..side diff --patch-with-raw -r initial..side + diff --name-status dir2 dir EOF test_done