From: Junio C Hamano Date: Wed, 19 Sep 2007 00:42:15 +0000 (-0700) Subject: Merge branch 'master' into ph/strbuf X-Git-Tag: v1.5.4-rc0~295^2~8 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/39bd2eb56af89d43a08ba54699d9a1849ab57b39?ds=inline;hp=-c Merge branch 'master' into ph/strbuf * master: (94 commits) Fixed update-hook example allow-users format. Documentation/git-svn: updated design philosophy notes t/t4014: test "am -3" with mode-only change. git-commit.sh: Shell script cleanup preserve executable bits in zip archives Fix lapsus in builtin-apply.c git-push: documentation and tests for pushing only branches git-svnimport: Use separate arguments in the pipe for git-rev-parse contrib/fast-import: add perl version of simple example contrib/fast-import: add simple shell example rev-list --bisect: Bisection "distance" clean up. rev-list --bisect: Move some bisection code into best_bisection. rev-list --bisect: Move finding bisection into do_find_bisection. Document ls-files --with-tree= git-commit: partial commit of paths only removed from the index git-commit: Allow partial commit of file removal. send-email: make message-id generation a bit more robust git-apply: fix whitespace stripping git-gui: Disable native platform text selection in "lists" apply --index-info: fall back to current index for mode changes ... --- 39bd2eb56af89d43a08ba54699d9a1849ab57b39 diff --combined builtin-apply.c index 61b51315ed,86d89a4a7e..f953c5b768 --- a/builtin-apply.c +++ b/builtin-apply.c @@@ -181,21 -181,34 +181,21 @@@ static void say_patch_name(FILE *output static void *read_patch_file(int fd, unsigned long *sizep) { - unsigned long size = 0, alloc = CHUNKSIZE; - void *buffer = xmalloc(alloc); + struct strbuf buf; - for (;;) { - ssize_t nr = alloc - size; - if (nr < 1024) { - alloc += CHUNKSIZE; - buffer = xrealloc(buffer, alloc); - nr = alloc - size; - } - nr = xread(fd, (char *) buffer + size, nr); - if (!nr) - break; - if (nr < 0) - die("git-apply: read returned %s", strerror(errno)); - size += nr; - } - *sizep = size; + strbuf_init(&buf, 0); + if (strbuf_read(&buf, fd, 0) < 0) + die("git-apply: read returned %s", strerror(errno)); + *sizep = buf.len; /* * Make sure that we have some slop in the buffer * so that we can do speculative "memcmp" etc, and * see to it that it is NUL-filled. */ - if (alloc < size + SLOP) - buffer = xrealloc(buffer, size + SLOP); - memset((char *) buffer + size, 0, SLOP); - return buffer; + strbuf_grow(&buf, SLOP); + memset(buf.buf + buf.len, 0, SLOP); + return strbuf_detach(&buf); } static unsigned long linelen(const char *buffer, unsigned long size) @@@ -241,7 -254,7 +241,7 @@@ static char *find_name(const char *line if (name) { char *cp = name; while (p_value) { - cp = strchr(name, '/'); + cp = strchr(cp, '/'); if (!cp) break; cp++; @@@ -1441,28 -1454,39 +1441,28 @@@ static void show_stats(struct patch *pa free(qname); } -static int read_old_data(struct stat *st, const char *path, char **buf_p, unsigned long *alloc_p, unsigned long *size_p) +static int read_old_data(struct stat *st, const char *path, struct strbuf *buf) { int fd; - unsigned long got; - unsigned long nsize; - char *nbuf; - unsigned long size = *size_p; - char *buf = *buf_p; switch (st->st_mode & S_IFMT) { case S_IFLNK: - return readlink(path, buf, size) != size; + strbuf_grow(buf, st->st_size); + if (readlink(path, buf->buf, st->st_size) != st->st_size) + return -1; + strbuf_setlen(buf, st->st_size); + return 0; case S_IFREG: fd = open(path, O_RDONLY); if (fd < 0) return error("unable to open %s", path); - got = 0; - for (;;) { - ssize_t ret = xread(fd, buf + got, size - got); - if (ret <= 0) - break; - got += ret; + if (strbuf_read(buf, fd, st->st_size) < 0) { + close(fd); + return -1; } close(fd); - nsize = got; - nbuf = convert_to_git(path, buf, &nsize); - if (nbuf) { - free(buf); - *buf_p = nbuf; - *alloc_p = nsize; - *size_p = nsize; - } - return got != size; + convert_to_git(path, buf->buf, buf->len, buf); + return 0; default: return -1; } @@@ -1567,6 -1591,12 +1567,6 @@@ static void remove_last_line(const cha *rsize = offset + 1; } -struct buffer_desc { - char *buffer; - unsigned long size; - unsigned long alloc; -}; - static int apply_line(char *output, const char *patch, int plen) { /* plen is number of bytes to be copied from patch, @@@ -1612,15 -1642,22 +1612,22 @@@ buf = output; if (need_fix_leading_space) { + int consecutive_spaces = 0; /* between patch[1..last_tab_in_indent] strip the * funny spaces, updating them to tab as needed. */ for (i = 1; i < last_tab_in_indent; i++, plen--) { char ch = patch[i]; - if (ch != ' ') + if (ch != ' ') { + consecutive_spaces = 0; *output++ = ch; - else if ((i % 8) == 0) - *output++ = '\t'; + } else { + consecutive_spaces++; + if (consecutive_spaces == 8) { + *output++ = '\t'; + consecutive_spaces = 0; + } + } } fixed = 1; i = last_tab_in_indent; @@@ -1636,9 -1673,10 +1643,9 @@@ return output + plen - buf; } -static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag, int inaccurate_eof) +static int apply_one_fragment(struct strbuf *buf, struct fragment *frag, int inaccurate_eof) { int match_beginning, match_end; - char *buf = desc->buffer; const char *patch = frag->patch; int offset, size = frag->size; char *old = xmalloc(size); @@@ -1749,17 -1787,24 +1756,17 @@@ lines = 0; pos = frag->newpos; for (;;) { - offset = find_offset(buf, desc->size, + offset = find_offset(buf->buf, buf->len, oldlines, oldsize, pos, &lines); - if (match_end && offset + oldsize != desc->size) + if (match_end && offset + oldsize != buf->len) offset = -1; if (match_beginning && offset) offset = -1; if (offset >= 0) { - int diff; - unsigned long size, alloc; - if (new_whitespace == strip_whitespace && - (desc->size - oldsize - offset == 0)) /* end of file? */ + (buf->len - oldsize - offset == 0)) /* end of file? */ newsize -= new_blank_lines_at_end; - diff = newsize - oldsize; - size = desc->size + diff; - alloc = desc->alloc; - /* Warn if it was necessary to reduce the number * of context lines. */ @@@ -1769,8 -1814,19 +1776,8 @@@ " to apply fragment at %d\n", leading, trailing, pos + lines); - if (size > alloc) { - alloc = size + 8192; - desc->alloc = alloc; - buf = xrealloc(buf, alloc); - desc->buffer = buf; - } - desc->size = size; - memmove(buf + offset + newsize, - buf + offset + oldsize, - size - offset - newsize); - memcpy(buf + offset, newlines, newsize); + strbuf_splice(buf, offset, oldsize, newlines, newsize); offset = 0; - break; } @@@ -1806,11 -1862,12 +1813,11 @@@ return offset; } -static int apply_binary_fragment(struct buffer_desc *desc, struct patch *patch) +static int apply_binary_fragment(struct strbuf *buf, struct patch *patch) { - unsigned long dst_size; struct fragment *fragment = patch->fragments; - void *data; - void *result; + unsigned long len; + void *dst; /* Binary patch is irreversible without the optional second hunk */ if (apply_in_reverse) { @@@ -1821,24 -1878,29 +1828,24 @@@ ? patch->new_name : patch->old_name); fragment = fragment->next; } - data = (void*) fragment->patch; switch (fragment->binary_patch_method) { case BINARY_DELTA_DEFLATED: - result = patch_delta(desc->buffer, desc->size, - data, - fragment->size, - &dst_size); - free(desc->buffer); - desc->buffer = result; - break; + dst = patch_delta(buf->buf, buf->len, fragment->patch, + fragment->size, &len); + if (!dst) + return -1; + /* XXX patch_delta NUL-terminates */ + strbuf_attach(buf, dst, len, len + 1); + return 0; case BINARY_LITERAL_DEFLATED: - free(desc->buffer); - desc->buffer = data; - dst_size = fragment->size; - break; + strbuf_reset(buf); + strbuf_add(buf, fragment->patch, fragment->size); + return 0; } - if (!desc->buffer) - return -1; - desc->size = desc->alloc = dst_size; - return 0; + return -1; } -static int apply_binary(struct buffer_desc *desc, struct patch *patch) +static int apply_binary(struct strbuf *buf, struct patch *patch) { const char *name = patch->old_name ? patch->old_name : patch->new_name; unsigned char sha1[20]; @@@ -1857,7 -1919,7 +1864,7 @@@ /* See if the old one matches what the patch * applies to. */ - hash_sha1_file(desc->buffer, desc->size, blob_type, sha1); + hash_sha1_file(buf->buf, buf->len, blob_type, sha1); if (strcmp(sha1_to_hex(sha1), patch->old_sha1_prefix)) return error("the patch applies to '%s' (%s), " "which does not match the " @@@ -1866,14 -1928,16 +1873,14 @@@ } else { /* Otherwise, the old one must be empty. */ - if (desc->size) + if (buf->len) return error("the patch applies to an empty " "'%s' but it is not empty", name); } get_sha1_hex(patch->new_sha1_prefix, sha1); if (is_null_sha1(sha1)) { - free(desc->buffer); - desc->alloc = desc->size = 0; - desc->buffer = NULL; + strbuf_release(buf); return 0; /* deletion patch */ } @@@ -1881,44 -1945,43 +1888,44 @@@ /* We already have the postimage */ enum object_type type; unsigned long size; + char *result; - free(desc->buffer); - desc->buffer = read_sha1_file(sha1, &type, &size); - if (!desc->buffer) + result = read_sha1_file(sha1, &type, &size); + if (!result) return error("the necessary postimage %s for " "'%s' cannot be read", patch->new_sha1_prefix, name); - desc->alloc = desc->size = size; - } - else { - /* We have verified desc matches the preimage; + /* XXX read_sha1_file NUL-terminates */ + strbuf_attach(buf, result, size, size + 1); + } else { + /* We have verified buf matches the preimage; * apply the patch data to it, which is stored * in the patch->fragments->{patch,size}. */ - if (apply_binary_fragment(desc, patch)) + if (apply_binary_fragment(buf, patch)) return error("binary patch does not apply to '%s'", name); /* verify that the result matches */ - hash_sha1_file(desc->buffer, desc->size, blob_type, sha1); + hash_sha1_file(buf->buf, buf->len, blob_type, sha1); if (strcmp(sha1_to_hex(sha1), patch->new_sha1_prefix)) - return error("binary patch to '%s' creates incorrect result (expecting %s, got %s)", name, patch->new_sha1_prefix, sha1_to_hex(sha1)); + return error("binary patch to '%s' creates incorrect result (expecting %s, got %s)", + name, patch->new_sha1_prefix, sha1_to_hex(sha1)); } return 0; } -static int apply_fragments(struct buffer_desc *desc, struct patch *patch) +static int apply_fragments(struct strbuf *buf, struct patch *patch) { struct fragment *frag = patch->fragments; const char *name = patch->old_name ? patch->old_name : patch->new_name; if (patch->is_binary) - return apply_binary(desc, patch); + return apply_binary(buf, patch); while (frag) { - if (apply_one_fragment(desc, frag, patch->inaccurate_eof)) { + if (apply_one_fragment(buf, frag, patch->inaccurate_eof)) { error("patch failed: %s:%ld", name, frag->oldpos); if (!apply_with_reject) return -1; @@@ -1929,57 -1992,76 +1936,57 @@@ return 0; } -static int read_file_or_gitlink(struct cache_entry *ce, char **buf_p, - unsigned long *size_p) +static int read_file_or_gitlink(struct cache_entry *ce, struct strbuf *buf) { if (!ce) return 0; if (S_ISGITLINK(ntohl(ce->ce_mode))) { - *buf_p = xmalloc(100); - *size_p = snprintf(*buf_p, 100, - "Subproject commit %s\n", sha1_to_hex(ce->sha1)); + strbuf_grow(buf, 100); + strbuf_addf(buf, "Subproject commit %s\n", sha1_to_hex(ce->sha1)); } else { enum object_type type; - *buf_p = read_sha1_file(ce->sha1, &type, size_p); - if (!*buf_p) + unsigned long sz; + char *result; + + result = read_sha1_file(ce->sha1, &type, &sz); + if (!result) return -1; + /* XXX read_sha1_file NUL-terminates */ + strbuf_attach(buf, result, sz, sz + 1); } return 0; } static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *ce) { - char *buf; - unsigned long size, alloc; - struct buffer_desc desc; + struct strbuf buf; - size = 0; - alloc = 0; - buf = NULL; + strbuf_init(&buf, 0); if (cached) { - if (read_file_or_gitlink(ce, &buf, &size)) + if (read_file_or_gitlink(ce, &buf)) return error("read of %s failed", patch->old_name); - alloc = size; } else if (patch->old_name) { if (S_ISGITLINK(patch->old_mode)) { - if (ce) - read_file_or_gitlink(ce, &buf, &size); - else { + if (ce) { + read_file_or_gitlink(ce, &buf); + } else { /* * There is no way to apply subproject * patch without looking at the index. */ patch->fragments = NULL; - size = 0; } - } - else { - size = xsize_t(st->st_size); - alloc = size + 8192; - buf = xmalloc(alloc); - if (read_old_data(st, patch->old_name, - &buf, &alloc, &size)) - return error("read of %s failed", - patch->old_name); + } else { + if (read_old_data(st, patch->old_name, &buf)) + return error("read of %s failed", patch->old_name); } } - desc.size = size; - desc.alloc = alloc; - desc.buffer = buf; - - if (apply_fragments(&desc, patch) < 0) + if (apply_fragments(&buf, patch) < 0) return -1; /* note with --reject this succeeds. */ - - /* NUL terminate the result */ - if (desc.alloc <= desc.size) - desc.buffer = xrealloc(desc.buffer, desc.size + 1); - desc.buffer[desc.size] = 0; - - patch->result = desc.buffer; - patch->resultsize = desc.size; + patch->result = buf.buf; + patch->resultsize = buf.len; if (0 < patch->is_delete && patch->resultsize) return error("removal patch leaves file contents"); @@@ -2152,6 -2234,20 +2159,20 @@@ static int check_patch_list(struct patc return err; } + /* This function tries to read the sha1 from the current index */ + static int get_current_sha1(const char *path, unsigned char *sha1) + { + int pos; + + if (read_cache() < 0) + return -1; + pos = cache_name_pos(path, strlen(path)); + if (pos < 0) + return -1; + hashcpy(sha1, active_cache[pos]->sha1); + return 0; + } + static void show_index_list(struct patch *list) { struct patch *patch; @@@ -2168,8 -2264,16 +2189,16 @@@ if (0 < patch->is_new) sha1_ptr = null_sha1; else if (get_sha1(patch->old_sha1_prefix, sha1)) - die("sha1 information is lacking or useless (%s).", - name); + /* git diff has no index line for mode/type changes */ + if (!patch->lines_added && !patch->lines_deleted) { + if (get_current_sha1(patch->new_name, sha1) || + get_current_sha1(patch->old_name, sha1)) + die("mode change for %s, which is not " + "in current HEAD", name); + sha1_ptr = sha1; + } else + die("sha1 information is lacking or useless " + "(%s).", name); else sha1_ptr = sha1; @@@ -2319,7 -2423,6 +2348,6 @@@ static void remove_file(struct patch *p if (update_index) { if (remove_file_from_cache(patch->old_name) < 0) die("unable to remove %s from index", patch->old_name); - cache_tree_invalidate_path(active_cache_tree, patch->old_name); } if (!cached) { if (S_ISGITLINK(patch->old_mode)) { @@@ -2376,7 -2479,7 +2404,7 @@@ static void add_index_file(const char * static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size) { int fd; - char *nbuf; + struct strbuf nbuf; if (S_ISGITLINK(mode)) { struct stat st; @@@ -2395,16 -2498,23 +2423,16 @@@ if (fd < 0) return -1; - nbuf = convert_to_working_tree(path, buf, &size); - if (nbuf) - buf = nbuf; - - while (size) { - int written = xwrite(fd, buf, size); - if (written < 0) - die("writing file %s: %s", path, strerror(errno)); - if (!written) - die("out of space writing file %s", path); - buf += written; - size -= written; + strbuf_init(&nbuf, 0); + if (convert_to_working_tree(path, buf, size, &nbuf)) { + size = nbuf.len; + buf = nbuf.buf; } + write_or_die(fd, buf, size); + strbuf_release(&nbuf); + if (close(fd) < 0) die("closing file %s: %s", path, strerror(errno)); - if (nbuf) - free(nbuf); return 0; } @@@ -2467,7 -2577,6 +2495,6 @@@ static void create_file(struct patch *p mode = S_IFREG | 0644; create_one_file(path, mode, buf, size); add_index_file(path, mode, buf, size); - cache_tree_invalidate_path(active_cache_tree, path); } /* phase zero is to remove, phase one is to create */ diff --combined builtin-log.c index e1d3e7d74b,c6cc3aef52..60819d15c5 --- a/builtin-log.c +++ b/builtin-log.c @@@ -437,6 -437,34 +437,34 @@@ static void gen_message_id(char *dest, (int)(email_end - email_start - 1), email_start + 1); } + static const char *clean_message_id(const char *msg_id) + { + char ch; + const char *a, *z, *m; + char *n; + size_t len; + + m = msg_id; + while ((ch = *m) && (isspace(ch) || (ch == '<'))) + m++; + a = m; + z = NULL; + while ((ch = *m)) { + if (!isspace(ch) && (ch != '>')) + z = m; + m++; + } + if (!z) + die("insane in-reply-to: %s", msg_id); + if (++z == m) + return a; + len = z - a; + n = xmalloc(len + 1); + memcpy(n, a, len); + n[len] = 0; + return n; + } + int cmd_format_patch(int argc, const char **argv, const char *prefix) { struct commit *commit; @@@ -625,7 -653,8 +653,8 @@@ if (numbered) rev.total = total + start_number - 1; rev.add_signoff = add_signoff; - rev.ref_message_id = in_reply_to; + if (in_reply_to) + rev.ref_message_id = clean_message_id(in_reply_to); while (0 <= --nr) { int shown; commit = list[nr]; @@@ -763,13 -792,13 +792,13 @@@ int cmd_cherry(int argc, const char **a sign = '-'; if (verbose) { - char *buf = NULL; - unsigned long buflen = 0; - pretty_print_commit(CMIT_FMT_ONELINE, commit, ~0, - &buf, &buflen, 0, NULL, NULL, 0); + struct strbuf buf; + strbuf_init(&buf, 0); + pretty_print_commit(CMIT_FMT_ONELINE, commit, + &buf, 0, NULL, NULL, 0); printf("%c %s %s\n", sign, - sha1_to_hex(commit->object.sha1), buf); - free(buf); + sha1_to_hex(commit->object.sha1), buf.buf); + strbuf_release(&buf); } else { printf("%c %s\n", sign, diff --combined builtin-rev-list.c index 4fd4b6bec1,899a31d09a..43b88fae29 --- a/builtin-rev-list.c +++ b/builtin-rev-list.c @@@ -80,12 -80,13 +80,12 @@@ static void show_commit(struct commit * putchar('\n'); if (revs.verbose_header) { - char *buf = NULL; - unsigned long buflen = 0; - pretty_print_commit(revs.commit_format, commit, ~0, - &buf, &buflen, - revs.abbrev, NULL, NULL, revs.date_mode); - printf("%s%c", buf, hdr_termination); - free(buf); + struct strbuf buf; + strbuf_init(&buf, 0); + pretty_print_commit(revs.commit_format, commit, + &buf, revs.abbrev, NULL, NULL, revs.date_mode); + printf("%s%c", buf.buf, hdr_termination); + strbuf_release(&buf); } maybe_flush_or_die(stdout, "stdout"); if (commit->parents) { @@@ -188,7 -189,7 +188,7 @@@ static int count_interesting_parents(st return count; } - static inline int halfway(struct commit_list *p, int distance, int nr) + static inline int halfway(struct commit_list *p, int nr) { /* * Don't short-cut something we are not going to return! @@@ -201,8 -202,7 +201,7 @@@ * 2 and 3 are halfway of 5. * 3 is halfway of 6 but 2 and 4 are not. */ - distance *= 2; - switch (distance - nr) { + switch (2 * weight(p) - nr) { case -1: case 0: case 1: return 1; default: @@@ -254,6 -254,30 +253,30 @@@ static void show_list(const char *debug } #endif /* DEBUG_BISECT */ + static struct commit_list *best_bisection(struct commit_list *list, int nr) + { + struct commit_list *p, *best; + int best_distance = -1; + + best = list; + for (p = list; p; p = p->next) { + int distance; + unsigned flags = p->item->object.flags; + + if (revs.prune_fn && !(flags & TREECHANGE)) + continue; + distance = weight(p); + if (nr - distance < distance) + distance = nr - distance; + if (distance > best_distance) { + best = p; + best_distance = distance; + } + } + + return best; + } + /* * zero or positive weight is the number of interesting commits it can * reach, including itself. Especially, weight = 0 means it does not @@@ -267,39 -291,12 +290,12 @@@ * unknown. After running count_distance() first, they will get zero * or positive distance. */ - - static struct commit_list *find_bisection(struct commit_list *list, - int *reaches, int *all) + static struct commit_list *do_find_bisection(struct commit_list *list, + int nr, int *weights) { - int n, nr, on_list, counted, distance; - struct commit_list *p, *best, *next, *last; - int *weights; - - show_list("bisection 2 entry", 0, 0, list); - - /* - * Count the number of total and tree-changing items on the - * list, while reversing the list. - */ - for (nr = on_list = 0, last = NULL, p = list; - p; - p = next) { - unsigned flags = p->item->object.flags; - - next = p->next; - if (flags & UNINTERESTING) - continue; - p->next = last; - last = p; - if (!revs.prune_fn || (flags & TREECHANGE)) - nr++; - on_list++; - } - list = last; - show_list("bisection 2 sorted", 0, nr, list); + int n, counted; + struct commit_list *p; - *all = nr; - weights = xcalloc(on_list, sizeof(*weights)); counted = 0; for (n = 0, p = list; p; p = p->next) { @@@ -348,20 -345,14 +344,14 @@@ for (p = list; p; p = p->next) { if (p->item->object.flags & UNINTERESTING) continue; - n = weight(p); - if (n != -2) + if (weight(p) != -2) continue; - distance = count_distance(p); + weight_set(p, count_distance(p)); clear_distance(list); - weight_set(p, distance); /* Does it happen to be at exactly half-way? */ - if (halfway(p, distance, nr)) { - p->next = NULL; - *reaches = distance; - free(weights); + if (halfway(p, nr)) return p; - } counted++; } @@@ -398,38 -389,59 +388,59 @@@ weight_set(p, weight(q)); /* Does it happen to be at exactly half-way? */ - distance = weight(p); - if (halfway(p, distance, nr)) { - p->next = NULL; - *reaches = distance; - free(weights); + if (halfway(p, nr)) return p; - } } } show_list("bisection 2 counted all", counted, nr, list); /* Then find the best one */ - counted = -1; - best = list; - for (p = list; p; p = p->next) { + return best_bisection(list, nr); + } + + static struct commit_list *find_bisection(struct commit_list *list, + int *reaches, int *all) + { + int nr, on_list; + struct commit_list *p, *best, *next, *last; + int *weights; + + show_list("bisection 2 entry", 0, 0, list); + + /* + * Count the number of total and tree-changing items on the + * list, while reversing the list. + */ + for (nr = on_list = 0, last = NULL, p = list; + p; + p = next) { unsigned flags = p->item->object.flags; - if (revs.prune_fn && !(flags & TREECHANGE)) + next = p->next; + if (flags & UNINTERESTING) continue; - distance = weight(p); - if (nr - distance < distance) - distance = nr - distance; - if (distance > counted) { - best = p; - counted = distance; - *reaches = weight(p); - } + p->next = last; + last = p; + if (!revs.prune_fn || (flags & TREECHANGE)) + nr++; + on_list++; } + list = last; + show_list("bisection 2 sorted", 0, nr, list); + + *all = nr; + weights = xcalloc(on_list, sizeof(*weights)); + + /* Do the real work of finding bisection commit. */ + best = do_find_bisection(list, nr, weights); + if (best) best->next = NULL; + + *reaches = weight(best); free(weights); + return best; } diff --combined builtin-update-index.c index 45e33f5584,55fb679d68..acd5ab5926 --- a/builtin-update-index.c +++ b/builtin-update-index.c @@@ -4,6 -4,7 +4,6 @@@ * Copyright (C) Linus Torvalds, 2005 */ #include "cache.h" -#include "strbuf.h" #include "quote.h" #include "cache-tree.h" #include "tree-walk.h" @@@ -194,11 -195,6 +194,6 @@@ static int process_path(const char *pat int len; struct stat st; - /* We probably want to do this in remove_file_from_cache() and - * add_cache_entry() instead... - */ - cache_tree_invalidate_path(active_cache_tree, path); - /* * First things first: get the stat information, to decide * what to do about the pathname! @@@ -238,7 -234,6 +233,6 @@@ static int add_cacheinfo(unsigned int m return error("%s: cannot add to the index - missing --add option?", path); report("add '%s'", path); - cache_tree_invalidate_path(active_cache_tree, path); return 0; } @@@ -283,7 -278,6 +277,6 @@@ static void update_one(const char *path die("Unable to mark file %s", path); goto free_return; } - cache_tree_invalidate_path(active_cache_tree, path); if (force_remove) { if (remove_file_from_cache(p)) @@@ -302,7 -296,7 +295,7 @@@ static void read_index_info(int line_termination) { struct strbuf buf; - strbuf_init(&buf); + strbuf_init(&buf, 0); while (1) { char *ptr, *tab; char *path_name; @@@ -327,7 -321,8 +320,7 @@@ * This format is to put higher order stages into the * index file and matches git-ls-files --stage output. */ - read_line(&buf, stdin, line_termination); - if (buf.eof) + if (strbuf_getline(&buf, stdin, line_termination) == EOF) break; errno = 0; @@@ -365,7 -360,6 +358,6 @@@ free(path_name); continue; } - cache_tree_invalidate_path(active_cache_tree, path_name); if (!mode) { /* mode == 0 means there is no such path -- remove */ @@@ -390,7 -384,6 +382,7 @@@ bad_line: die("malformed index info %s", buf.buf); } + strbuf_release(&buf); } static const char update_index_usage[] = @@@ -473,7 -466,6 +465,6 @@@ static int unresolve_one(const char *pa goto free_return; } - cache_tree_invalidate_path(active_cache_tree, path); remove_file_from_cache(path); if (add_cache_entry(ce_2, ADD_CACHE_OK_TO_ADD)) { error("%s: cannot add our version to the index.", path); @@@ -715,11 -707,12 +706,11 @@@ int cmd_update_index(int argc, const ch } if (read_from_stdin) { struct strbuf buf; - strbuf_init(&buf); + strbuf_init(&buf, 0); while (1) { char *path_name; const char *p; - read_line(&buf, stdin, line_termination); - if (buf.eof) + if (strbuf_getline(&buf, stdin, line_termination) == EOF) break; if (line_termination && buf.buf[0] == '"') path_name = unquote_c_style(buf.buf, NULL); @@@ -734,7 -727,6 +725,7 @@@ if (path_name != buf.buf) free(path_name); } + strbuf_release(&buf); } finish: diff --combined cache.h index 37eb57eaba,8246500166..8650d62334 --- a/cache.h +++ b/cache.h @@@ -2,7 -2,6 +2,7 @@@ #define CACHE_H #include "git-compat-util.h" +#include "strbuf.h" #include SHA1_HEADER #include @@@ -265,11 -264,13 +265,12 @@@ extern struct cache_entry *refresh_cach extern int remove_index_entry_at(struct index_state *, int pos); extern int remove_file_from_index(struct index_state *, const char *path); extern int add_file_to_index(struct index_state *, const char *path, int verbose); + extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh); extern int ce_same_name(struct cache_entry *a, struct cache_entry *b); extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, int); extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, int); extern int ce_path_match(const struct cache_entry *ce, const char **pathspec); extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path); -extern int read_fd(int fd, char **return_buf, unsigned long *return_size); extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object); extern int index_path(unsigned char *sha1, const char *path, struct stat *st, int write_object); extern void fill_stat_cache_info(struct cache_entry *ce, struct stat *st); @@@ -590,9 -591,8 +591,9 @@@ extern void trace_printf(const char *fo extern void trace_argv_printf(const char **argv, int count, const char *format, ...); /* convert.c */ -extern char *convert_to_git(const char *path, const char *src, unsigned long *sizep); -extern char *convert_to_working_tree(const char *path, const char *src, unsigned long *sizep); +/* returns 1 if *dst was used */ +extern int convert_to_git(const char *path, const char *src, size_t len, struct strbuf *dst); +extern int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst); /* diff.c */ extern int diff_auto_refresh_index; diff --combined diff.c index 56b672c4f0,0ee9ea1c1b..a5b69ed2d2 --- a/diff.c +++ b/diff.c @@@ -17,7 -17,7 +17,7 @@@ #endif static int diff_detect_rename_default; - static int diff_rename_limit_default = -1; + static int diff_rename_limit_default = 100; static int diff_use_color_default; int diff_auto_refresh_index = 1; @@@ -1545,16 -1545,26 +1545,16 @@@ static int reuse_worktree_file(const ch static int populate_from_stdin(struct diff_filespec *s) { -#define INCREMENT 1024 - char *buf; - unsigned long size; - ssize_t got; - - size = 0; - buf = NULL; - while (1) { - buf = xrealloc(buf, size + INCREMENT); - got = xread(0, buf + size, INCREMENT); - if (!got) - break; /* EOF */ - if (got < 0) - return error("error while reading from stdin %s", + struct strbuf buf; + + strbuf_init(&buf, 0); + if (strbuf_read(&buf, 0, 0) < 0) + return error("error while reading from stdin %s", strerror(errno)); - size += got; - } + s->should_munmap = 0; - s->data = buf; - s->size = size; + s->size = buf.len; + s->data = strbuf_detach(&buf); s->should_free = 1; return 0; } @@@ -1599,9 -1609,10 +1599,9 @@@ int diff_populate_filespec(struct diff_ if (!s->sha1_valid || reuse_worktree_file(s->path, s->sha1, 0)) { + struct strbuf buf; struct stat st; int fd; - char *buf; - unsigned long size; if (!strcmp(s->path, "-")) return populate_from_stdin(s); @@@ -1642,12 -1653,13 +1642,12 @@@ /* * Convert from working tree format to canonical git format */ - size = s->size; - buf = convert_to_git(s->path, s->data, &size); - if (buf) { + strbuf_init(&buf, 0); + if (convert_to_git(s->path, s->data, s->size, &buf)) { munmap(s->data, s->size); s->should_munmap = 0; - s->data = buf; - s->size = size; + s->data = buf.buf; + s->size = buf.len; s->should_free = 1; } }