X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=sha1_name.c;h=36c9cbf1acd94b4614f1a66e73664910309c279a;hb=55e7c0aaa1b2c00d147b1b4b1aa88a71d90dacf4;hp=bf924178380c42a50b2fd7a02ff869dcc3ddff6a;hpb=72d9b222a940c93a8d915c26a4d5d077e23be871;p=thirdparty%2Fgit.git diff --git a/sha1_name.c b/sha1_name.c index bf92417838..36c9cbf1ac 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -659,6 +659,16 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1) return get_short_sha1(name, len, sha1, 0); } +/* + * This interprets names like ':/Initial revision of "git"' by searching + * through history and returning the first commit whose message starts + * 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. + */ +#define ONELINE_SEEN (1u<<20) + static int handle_one_ref(const char *path, const unsigned char *sha1, int flag, void *cb_data) { @@ -674,30 +684,26 @@ static int handle_one_ref(const char *path, if (object->type != OBJ_COMMIT) return 0; insert_by_date((struct commit *)object, list); + object->flags |= ONELINE_SEEN; return 0; } -/* - * This interprets names like ':/Initial revision of "git"' by searching - * through history and returning the first commit whose message starts - * with the given string. - * - * For future extension, ':/!' is reserved. If you want to match a message - * beginning with a '!', you have to repeat the exclamation mark. - */ - -#define ONELINE_SEEN (1u<<20) static int get_sha1_oneline(const char *prefix, unsigned char *sha1) { 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); @@ -721,12 +727,13 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1) } 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) @@ -933,8 +940,8 @@ int interpret_branch_name(const char *name, struct strbuf *buf) */ 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. */ @@ -1031,12 +1038,24 @@ static void diagnose_invalid_index_path(int stage, 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; @@ -1049,6 +1068,7 @@ int get_sha1_with_mode_1(const char *name, unsigned char *sha1, unsigned *mode, 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] != ':' || @@ -1059,6 +1079,11 @@ int get_sha1_with_mode_1(const char *name, unsigned char *sha1, unsigned *mode, 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); @@ -1071,7 +1096,7 @@ int get_sha1_with_mode_1(const char *name, unsigned char *sha1, unsigned *mode, break; if (ce_stage(ce) == stage) { hashcpy(sha1, ce->sha1); - *mode = ce->ce_mode; + oc->mode = ce->ce_mode; return 0; } pos++; @@ -1098,12 +1123,17 @@ int get_sha1_with_mode_1(const char *name, unsigned char *sha1, unsigned *mode, } 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)