From: Junio C Hamano Date: Thu, 2 Dec 2010 19:26:24 +0000 (-0800) Subject: Merge branch 'ks/no-textconv-symlink' into maint X-Git-Tag: v1.7.3.3~9 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/9f6774ed86a9ac22142c0b37e26e67eb1d032962?ds=inline;hp=-c Merge branch 'ks/no-textconv-symlink' into maint * ks/no-textconv-symlink: blame,cat-file --textconv: Don't assume mode is ``S_IFREF | 0664'' blame,cat-file: Demonstrate --textconv is wrongly running converter on symlinks blame,cat-file: Prepare --textconv tests for correctly-failing conversion program --- 9f6774ed86a9ac22142c0b37e26e67eb1d032962 diff --combined builtin.h index 0398d24740,98b1e85e8b..9bf69eee0c --- a/builtin.h +++ b/builtin.h @@@ -11,6 -11,8 +11,6 @@@ extern const char git_version_string[] extern const char git_usage_string[]; extern const char git_more_info_string[]; -extern void list_common_cmds_help(void); -extern const char *help_unknown_cmd(const char *cmd); extern void prune_packed_objects(int); extern int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out); @@@ -35,7 -37,7 +35,7 @@@ void finish_copy_notes_for_rewrite(stru extern int check_pager_config(const char *cmd); - extern int textconv_object(const char *path, const unsigned char *sha1, char **buf, unsigned long *buf_size); + extern int textconv_object(const char *path, unsigned mode, const unsigned char *sha1, char **buf, unsigned long *buf_size); extern int cmd_add(int argc, const char **argv, const char *prefix); extern int cmd_annotate(int argc, const char **argv, const char *prefix); diff --combined builtin/blame.c index 101535448f,173f286b19..f5fccc1f67 --- a/builtin/blame.c +++ b/builtin/blame.c @@@ -83,6 -83,7 +83,7 @@@ struct origin struct commit *commit; mmfile_t file; unsigned char blob_sha1[20]; + unsigned mode; char path[FLEX_ARRAY]; }; @@@ -92,6 -93,7 +93,7 @@@ * Return 1 if the conversion succeeds, 0 otherwise. */ int textconv_object(const char *path, + unsigned mode, const unsigned char *sha1, char **buf, unsigned long *buf_size) @@@ -100,7 -102,7 +102,7 @@@ struct userdiff_driver *textconv; df = alloc_filespec(path); - fill_filespec(df, sha1, S_IFREG | 0664); + fill_filespec(df, sha1, mode); textconv = get_textconv(df); if (!textconv) { free_filespec(df); @@@ -125,7 -127,7 +127,7 @@@ static void fill_origin_blob(struct dif num_read_blob++; if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) && - textconv_object(o->path, o->blob_sha1, &file->ptr, &file_size)) + textconv_object(o->path, o->mode, o->blob_sha1, &file->ptr, &file_size)) ; else file->ptr = read_sha1_file(o->blob_sha1, &type, &file_size); @@@ -313,21 -315,23 +315,23 @@@ static struct origin *get_origin(struc * for an origin is also used to pass the blame for the entire file to * the parent to detect the case where a child's blob is identical to * that of its parent's. + * + * This also fills origin->mode for corresponding tree path. */ - static int fill_blob_sha1(struct origin *origin) + static int fill_blob_sha1_and_mode(struct origin *origin) { - unsigned mode; if (!is_null_sha1(origin->blob_sha1)) return 0; if (get_tree_entry(origin->commit->object.sha1, origin->path, - origin->blob_sha1, &mode)) + origin->blob_sha1, &origin->mode)) goto error_out; if (sha1_object_info(origin->blob_sha1, NULL) != OBJ_BLOB) goto error_out; return 0; error_out: hashclr(origin->blob_sha1); + origin->mode = S_IFINVALID; return -1; } @@@ -360,12 -364,14 +364,14 @@@ static struct origin *find_origin(struc /* * If the origin was newly created (i.e. get_origin * would call make_origin if none is found in the - * scoreboard), it does not know the blob_sha1, + * scoreboard), it does not know the blob_sha1/mode, * so copy it. Otherwise porigin was in the - * scoreboard and already knows blob_sha1. + * scoreboard and already knows blob_sha1/mode. */ - if (porigin->refcnt == 1) + if (porigin->refcnt == 1) { hashcpy(porigin->blob_sha1, cached->blob_sha1); + porigin->mode = cached->mode; + } return porigin; } /* otherwise it was not very useful; free it */ @@@ -400,6 -406,7 +406,7 @@@ /* The path is the same as parent */ porigin = get_origin(sb, parent, origin->path); hashcpy(porigin->blob_sha1, origin->blob_sha1); + porigin->mode = origin->mode; } else { /* * Since origin->path is a pathspec, if the parent @@@ -425,6 -432,7 +432,7 @@@ case 'M': porigin = get_origin(sb, parent, origin->path); hashcpy(porigin->blob_sha1, p->one->sha1); + porigin->mode = p->one->mode; break; case 'A': case 'T': @@@ -444,6 -452,7 +452,7 @@@ cached = make_origin(porigin->commit, porigin->path); hashcpy(cached->blob_sha1, porigin->blob_sha1); + cached->mode = porigin->mode; parent->util = cached; } return porigin; @@@ -486,6 -495,7 +495,7 @@@ static struct origin *find_rename(struc !strcmp(p->two->path, origin->path)) { porigin = get_origin(sb, parent, p->one->path); hashcpy(porigin->blob_sha1, p->one->sha1); + porigin->mode = p->one->mode; break; } } @@@ -1099,6 -1109,7 +1109,7 @@@ static int find_copy_in_parent(struct s norigin = get_origin(sb, parent, p->one->path); hashcpy(norigin->blob_sha1, p->one->sha1); + norigin->mode = p->one->mode; fill_origin_blob(&sb->revs->diffopt, norigin, &file_p); if (!file_p.ptr) continue; @@@ -1407,8 -1418,7 +1418,8 @@@ static void get_commit_info(struct comm int detailed) { int len; - char *tmp, *endp, *reencoded, *message; + const char *subject; + char *reencoded, *message; static char author_name[1024]; static char author_mail[1024]; static char committer_name[1024]; @@@ -1450,13 -1460,22 +1461,13 @@@ &ret->committer_time, &ret->committer_tz); ret->summary = summary_buf; - tmp = strstr(message, "\n\n"); - if (!tmp) { - error_out: + len = find_commit_subject(message, &subject); + if (len && len < sizeof(summary_buf)) { + memcpy(summary_buf, subject, len); + summary_buf[len] = 0; + } else { sprintf(summary_buf, "(%s)", sha1_to_hex(commit->object.sha1)); - free(reencoded); - return; } - tmp += 2; - endp = strchr(tmp, '\n'); - if (!endp) - endp = tmp + strlen(tmp); - len = endp - tmp; - if (len >= sizeof(summary_buf) || len == 0) - goto error_out; - memcpy(summary_buf, tmp, len); - summary_buf[len] = 0; free(reencoded); } @@@ -2075,7 -2094,7 +2086,7 @@@ static struct commit *fake_working_tree switch (st.st_mode & S_IFMT) { case S_IFREG: if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV) && - textconv_object(read_from, null_sha1, &buf.buf, &buf_len)) + textconv_object(read_from, mode, null_sha1, &buf.buf, &buf_len)) buf.len = buf_len; else if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size) die_errno("cannot open or read '%s'", read_from); @@@ -2455,11 -2474,11 +2466,11 @@@ parse_done } else { o = get_origin(&sb, sb.final, path); - if (fill_blob_sha1(o)) + if (fill_blob_sha1_and_mode(o)) die("no such path %s in %s", path, final_commit_name); if (DIFF_OPT_TST(&sb.revs->diffopt, ALLOW_TEXTCONV) && - textconv_object(path, o->blob_sha1, (char **) &sb.final_buf, + textconv_object(path, o->mode, o->blob_sha1, (char **) &sb.final_buf, &sb.final_buf_size)) ; else diff --combined sha1_name.c index 484081de82,36c9cbf1ac..3e856b8036 --- a/sha1_name.c +++ b/sha1_name.c @@@ -342,7 -342,7 +342,7 @@@ static int get_sha1_1(const char *name static int get_sha1_basic(const char *str, int len, unsigned char *sha1) { - static const char *warning = "warning: refname '%.*s' is ambiguous.\n"; + static const char *warn_msg = "refname '%.*s' is ambiguous."; char *real_ref = NULL; int refs_found = 0; int at, reflog_len; @@@ -390,7 -390,7 +390,7 @@@ return -1; if (warn_ambiguous_refs && refs_found > 1) - fprintf(stderr, warning, len, str); + warning(warn_msg, len, str); if (reflog_len) { int nth, i; @@@ -426,14 -426,14 +426,14 @@@ if (read_ref_at(real_ref, at_time, nth, sha1, NULL, &co_time, &co_tz, &co_cnt)) { if (at_time) - fprintf(stderr, - "warning: Log for '%.*s' only goes " - "back to %s.\n", len, str, + warning("Log for '%.*s' only goes " + "back to %s.", len, str, show_date(co_time, co_tz, DATE_RFC2822)); - else - fprintf(stderr, - "warning: Log for '%.*s' only has " - "%d entries.\n", len, str, co_cnt); + else { + free(real_ref); + die("Log for '%.*s' only has %d entries.", + len, str, co_cnt); + } } } @@@ -1062,13 -1062,13 +1062,14 @@@ int get_sha1_with_context_1(const char /* sha1:path --> object name of path in ent sha1 * :path -> object name of path in index * :[0-3]:path -> object name of path in index at stage + * :/foo -> recent commit matching foo */ if (name[0] == ':') { int stage = 0; struct cache_entry *ce; int pos; if (namelen > 2 && name[1] == '/') + /* don't need mode for commit */ return get_sha1_oneline(name + 2, sha1); if (namelen < 3 || name[2] != ':' || @@@ -1096,6 -1096,7 +1097,7 @@@ break; if (ce_stage(ce) == stage) { hashcpy(sha1, ce->sha1); + oc->mode = ce->ce_mode; return 0; } pos++;