From: Junio C Hamano Date: Sun, 27 Jun 2010 19:07:55 +0000 (-0700) Subject: Merge branch 'cp/textconv-cat-file' X-Git-Tag: v1.7.2-rc0~1 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/cf4403a01070f03e5c5cc65b52c1351d20ff4e91?ds=inline;hp=-c Merge branch 'cp/textconv-cat-file' * cp/textconv-cat-file: git-cat-file.txt: Document --textconv t/t8007: test textconv support for cat-file textconv: support for cat_file sha1_name: add get_sha1_with_context() --- cf4403a01070f03e5c5cc65b52c1351d20ff4e91 diff --combined builtin.h index 1054c6e295,5a1dba0069..ed6ee26933 --- a/builtin.h +++ b/builtin.h @@@ -16,20 -16,19 +16,20 @@@ extern const char *help_unknown_cmd(con extern void prune_packed_objects(int); extern int fmt_merge_msg(int merge_summary, struct strbuf *in, struct strbuf *out); +extern int fmt_merge_msg_shortlog(struct strbuf *in, struct strbuf *out); extern int commit_notes(struct notes_tree *t, const char *msg); struct notes_rewrite_cfg { struct notes_tree **trees; const char *cmd; int enabled; - combine_notes_fn *combine; + combine_notes_fn combine; struct string_list *refs; int refs_from_env; int mode_from_env; }; -combine_notes_fn *parse_combine_notes_fn(const char *v); +combine_notes_fn parse_combine_notes_fn(const char *v); struct notes_rewrite_cfg *init_copy_notes_for_rewrite(const char *cmd); int copy_note_for_rewrite(struct notes_rewrite_cfg *c, const unsigned char *from_obj, const unsigned char *to_obj); @@@ -37,6 -36,8 +37,8 @@@ 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 cmd_add(int argc, const char **argv, const char *prefix); extern int cmd_annotate(int argc, const char **argv, const char *prefix); extern int cmd_apply(int argc, const char **argv, const char *prefix); diff --combined builtin/blame.c index 9b88ce9256,2e63648ea0..01e62fdeb0 --- a/builtin/blame.c +++ b/builtin/blame.c @@@ -40,7 -40,7 +40,7 @@@ static int show_root static int reverse; static int blank_boundary; static int incremental; -static int xdl_opts = XDF_NEED_MINIMAL; +static int xdl_opts; static enum date_mode blame_date_mode = DATE_ISO8601; static size_t blame_date_width; @@@ -91,10 -91,10 +91,10 @@@ struct origin * if the textconv driver exists. * Return 1 if the conversion succeeds, 0 otherwise. */ - static int textconv_object(const char *path, - const unsigned char *sha1, - char **buf, - unsigned long *buf_size) + int textconv_object(const char *path, + const unsigned char *sha1, + char **buf, + unsigned long *buf_size) { struct diff_filespec *df; struct userdiff_driver *textconv; @@@ -767,11 -767,10 +767,11 @@@ static int pass_blame_to_parent(struct { int last_in_target; mmfile_t file_p, file_o; - struct blame_chunk_cb_data d = { sb, target, parent, 0, 0 }; + struct blame_chunk_cb_data d; xpparam_t xpp; xdemitconf_t xecfg; - + memset(&d, 0, sizeof(d)); + d.sb = sb; d.target = target; d.parent = parent; last_in_target = find_last_in_target(sb, target); if (last_in_target < 0) return 1; /* nothing remains for this target */ @@@ -910,11 -909,10 +910,11 @@@ static void find_copy_in_blob(struct sc const char *cp; int cnt; mmfile_t file_o; - struct handle_split_cb_data d = { sb, ent, parent, split, 0, 0 }; + struct handle_split_cb_data d; xpparam_t xpp; xdemitconf_t xecfg; - + memset(&d, 0, sizeof(d)); + d.sb = sb; d.ent = ent; d.parent = parent; d.split = split; /* * Prepare mmfile that contains only the lines in ent. */ diff --combined builtin/cat-file.c index e5118c57da,cada5d2257..76ec3fec92 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@@ -9,6 -9,8 +9,8 @@@ #include "tree.h" #include "builtin.h" #include "parse-options.h" + #include "diff.h" + #include "userdiff.h" #define BATCH 1 #define BATCH_CHECK 2 @@@ -84,10 -86,11 +86,11 @@@ static int cat_one_file(int opt, const { unsigned char sha1[20]; enum object_type type; - void *buf; + char *buf; unsigned long size; + struct object_context obj_context; - if (get_sha1(obj_name, sha1)) + if (get_sha1_with_context(obj_name, sha1, &obj_context)) die("Not a valid object name %s", obj_name); buf = NULL; @@@ -118,9 -121,7 +121,9 @@@ /* custom pretty-print here */ if (type == OBJ_TREE) { - const char *ls_args[3] = {"ls-tree", obj_name, NULL}; + const char *ls_args[3] = { NULL }; + ls_args[0] = "ls-tree"; + ls_args[1] = obj_name; return cmd_ls_tree(2, ls_args, NULL); } @@@ -134,6 -135,17 +137,17 @@@ /* otherwise just spit out the data */ break; + + case 'c': + if (!obj_context.path[0]) + die("git cat-file --textconv %s: must be ", + obj_name); + + if (!textconv_object(obj_context.path, sha1, &buf, &size)) + die("git cat-file --textconv: unable to run textconv on %s", + obj_name); + break; + case 0: buf = read_object_with_reference(sha1, exp_type, &size, NULL); break; @@@ -203,11 -215,25 +217,25 @@@ static int batch_objects(int print_cont } static const char * const cat_file_usage[] = { - "git cat-file (-t|-s|-e|-p|) ", + "git cat-file (-t|-s|-e|-p||--textconv) ", "git cat-file (--batch|--batch-check) < ", NULL }; + static int git_cat_file_config(const char *var, const char *value, void *cb) + { + switch (userdiff_config(var, value)) { + case 0: + break; + case -1: + return -1; + default: + return 0; + } + + return git_default_config(var, value, cb); + } + int cmd_cat_file(int argc, const char **argv, const char *prefix) { int opt = 0, batch = 0; @@@ -220,6 -246,8 +248,8 @@@ OPT_SET_INT('e', NULL, &opt, "exit with zero when there's no error", 'e'), OPT_SET_INT('p', NULL, &opt, "pretty-print object's content", 'p'), + OPT_SET_INT(0, "textconv", &opt, + "for blob objects, run textconv on object's content", 'c'), OPT_SET_INT(0, "batch", &batch, "show info and content of objects fed from the standard input", BATCH), @@@ -229,7 -257,7 +259,7 @@@ OPT_END() }; - git_config(git_default_config, NULL); + git_config(git_cat_file_config, NULL); if (argc != 3 && argc != 2) usage_with_options(cat_file_usage, options); diff --combined cache.h index ff4a7c26d3,67030dbfca..c9fa3df7f5 --- a/cache.h +++ b/cache.h @@@ -361,7 -361,7 +361,7 @@@ enum object_type OBJ_OFS_DELTA = 6, OBJ_REF_DELTA = 7, OBJ_ANY, - OBJ_MAX, + OBJ_MAX }; static inline enum object_type object_type(unsigned int mode) @@@ -547,6 -547,7 +547,6 @@@ extern int core_compression_seen extern size_t packed_git_window_size; extern size_t packed_git_limit; extern size_t delta_base_cache_limit; -extern int auto_crlf; extern int read_replace_refs; extern int fsync_object_files; extern int core_preload_index; @@@ -555,53 -556,32 +555,53 @@@ extern int core_apply_sparse_checkout enum safe_crlf { SAFE_CRLF_FALSE = 0, SAFE_CRLF_FAIL = 1, - SAFE_CRLF_WARN = 2, + SAFE_CRLF_WARN = 2 }; extern enum safe_crlf safe_crlf; +enum auto_crlf { + AUTO_CRLF_FALSE = 0, + AUTO_CRLF_TRUE = 1, + AUTO_CRLF_INPUT = -1, +}; + +extern enum auto_crlf auto_crlf; + +enum eol { + EOL_UNSET, + EOL_CRLF, + EOL_LF, +#ifdef NATIVE_CRLF + EOL_NATIVE = EOL_CRLF +#else + EOL_NATIVE = EOL_LF +#endif +}; + +extern enum eol eol; + enum branch_track { BRANCH_TRACK_UNSPECIFIED = -1, BRANCH_TRACK_NEVER = 0, BRANCH_TRACK_REMOTE, BRANCH_TRACK_ALWAYS, BRANCH_TRACK_EXPLICIT, - BRANCH_TRACK_OVERRIDE, + BRANCH_TRACK_OVERRIDE }; enum rebase_setup_type { AUTOREBASE_NEVER = 0, AUTOREBASE_LOCAL, AUTOREBASE_REMOTE, - AUTOREBASE_ALWAYS, + AUTOREBASE_ALWAYS }; enum push_default_type { PUSH_DEFAULT_NOTHING = 0, PUSH_DEFAULT_MATCHING, PUSH_DEFAULT_TRACKING, - PUSH_DEFAULT_CURRENT, + PUSH_DEFAULT_CURRENT }; extern enum branch_track git_branch_track; @@@ -610,7 -590,7 +610,7 @@@ extern enum push_default_type push_defa enum object_creation_mode { OBJECT_CREATION_USES_HARDLINKS = 0, - OBJECT_CREATION_USES_RENAMES = 1, + OBJECT_CREATION_USES_RENAMES = 1 }; extern enum object_creation_mode object_creation_mode; @@@ -690,7 -670,7 +690,7 @@@ enum sharedrepo OLD_PERM_GROUP = 1, OLD_PERM_EVERYBODY = 2, PERM_GROUP = 0660, - PERM_EVERYBODY = 0664, + PERM_EVERYBODY = 0664 }; int git_config_perm(const char *var, const char *value); int set_shared_perm(const char *path, int mode); @@@ -750,12 -730,23 +750,23 @@@ static inline unsigned int hexval(unsig #define MINIMUM_ABBREV 4 #define DEFAULT_ABBREV 7 + struct object_context { + unsigned char tree[20]; + char path[PATH_MAX]; + unsigned mode; + }; + extern int get_sha1(const char *str, unsigned char *sha1); extern int get_sha1_with_mode_1(const char *str, unsigned char *sha1, unsigned *mode, int gently, const char *prefix); static inline int get_sha1_with_mode(const char *str, unsigned char *sha1, unsigned *mode) { return get_sha1_with_mode_1(str, sha1, mode, 1, NULL); } + extern int get_sha1_with_context_1(const char *name, unsigned char *sha1, struct object_context *orc, int gently, const char *prefix); + static inline int get_sha1_with_context(const char *str, unsigned char *sha1, struct object_context *orc) + { + return get_sha1_with_context_1(str, sha1, orc, 1, NULL); + } extern int get_sha1_hex(const char *hex, unsigned char *sha1); extern char *sha1_to_hex(const unsigned char *sha1); /* static buffer result! */ extern int read_ref(const char *filename, unsigned char *sha1); @@@ -902,7 -893,7 +913,7 @@@ struct ref REF_STATUS_REJECT_NODELETE, REF_STATUS_UPTODATE, REF_STATUS_REMOTE_REJECT, - REF_STATUS_EXPECTING_REPORT, + REF_STATUS_EXPECTING_REPORT } status; char *remote_status; struct ref *peer_ref; /* when renaming */ diff --combined sha1_name.c index 8cf635af54,7fdb20277f..4f2af8da93 --- a/sha1_name.c +++ b/sha1_name.c @@@ -679,8 -679,8 +679,8 @@@ static int handle_one_ref(const char *p /* * This interprets names like ':/Initial revision of "git"' by searching - * through history and returning the first commit whose message starts - * with the given string. + * through history and returning the first commit whose message matches + * the given regular expression. * * For future extension, ':/!' is reserved. If you want to match a message * beginning with a '!', you have to repeat the exclamation mark. @@@ -692,17 -692,12 +692,17 @@@ static int get_sha1_oneline(const char struct commit_list *list = NULL, *backup = NULL, *l; int retval = -1; char *temp_commit_buffer = NULL; + regex_t regex; if (prefix[0] == '!') { if (prefix[1] != '!') die ("Invalid search pattern: %s", prefix); prefix++; } + + if (regcomp(®ex, prefix, REG_EXTENDED)) + die("Invalid search pattern: %s", prefix); + for_each_ref(handle_one_ref, &list); for (l = list; l; l = l->next) commit_list_insert(l->item, &backup); @@@ -726,13 -721,12 +726,13 @@@ } if (!(p = strstr(p, "\n\n"))) continue; - if (!prefixcmp(p + 2, prefix)) { + if (!regexec(®ex, p + 2, 0, NULL, 0)) { hashcpy(sha1, commit->object.sha1); retval = 0; break; } } + regfree(®ex); free(temp_commit_buffer); free_commit_list(list); for (l = backup; l; l = l->next) @@@ -939,8 -933,8 +939,8 @@@ int interpret_branch_name(const char *n */ int get_sha1(const char *name, unsigned char *sha1) { - unsigned unused; - return get_sha1_with_mode(name, sha1, &unused); + struct object_context unused; + return get_sha1_with_context(name, sha1, &unused); } /* Must be called only when object_name:filename doesn't exist. */ @@@ -1037,12 -1031,24 +1037,24 @@@ static void diagnose_invalid_index_path int get_sha1_with_mode_1(const char *name, unsigned char *sha1, unsigned *mode, int gently, const char *prefix) + { + struct object_context oc; + int ret; + ret = get_sha1_with_context_1(name, sha1, &oc, gently, prefix); + *mode = oc.mode; + return ret; + } + + int get_sha1_with_context_1(const char *name, unsigned char *sha1, + struct object_context *oc, + int gently, const char *prefix) { int ret, bracket_depth; int namelen = strlen(name); const char *cp; - *mode = S_IFINVALID; + memset(oc, 0, sizeof(*oc)); + oc->mode = S_IFINVALID; ret = get_sha1_1(name, namelen, sha1); if (!ret) return ret; @@@ -1065,6 -1071,11 +1077,11 @@@ cp = name + 3; } namelen = namelen - (cp - name); + + strncpy(oc->path, cp, + sizeof(oc->path)); + oc->path[sizeof(oc->path)-1] = '\0'; + if (!active_cache) read_cache(); pos = cache_name_pos(cp, namelen); @@@ -1077,7 -1088,6 +1094,6 @@@ break; if (ce_stage(ce) == stage) { hashcpy(sha1, ce->sha1); - *mode = ce->ce_mode; return 0; } pos++; @@@ -1104,12 -1114,17 +1120,17 @@@ } if (!get_sha1_1(name, cp-name, tree_sha1)) { const char *filename = cp+1; - ret = get_tree_entry(tree_sha1, filename, sha1, mode); + ret = get_tree_entry(tree_sha1, filename, sha1, &oc->mode); if (!gently) { diagnose_invalid_sha1_path(prefix, filename, tree_sha1, object_name); free(object_name); } + hashcpy(oc->tree, tree_sha1); + strncpy(oc->path, filename, + sizeof(oc->path)); + oc->path[sizeof(oc->path)-1] = '\0'; + return ret; } else { if (!gently)