diff options
-rw-r--r-- | builtin/log.c | 3 | ||||
-rw-r--r-- | log-tree.c | 24 | ||||
-rw-r--r-- | object.c | 18 | ||||
-rw-r--r-- | object.h | 20 | ||||
-rw-r--r-- | pretty.c | 4 | ||||
-rw-r--r-- | pretty.h | 8 | ||||
-rw-r--r-- | reachable.c | 18 | ||||
-rwxr-xr-x | t/t4202-log.sh | 14 |
8 files changed, 77 insertions, 32 deletions
diff --git a/builtin/log.c b/builtin/log.c index 516a1142dd..3d7717ba5c 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -245,6 +245,9 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, rev->abbrev_commit = 0; } + if (rev->commit_format == CMIT_FMT_USERFORMAT && !w.decorate) + decoration_style = 0; + if (decoration_style) { const struct string_list *config_exclude = repo_config_get_value_multi(the_repository, diff --git a/log-tree.c b/log-tree.c index 7b823786c2..6dc4412268 100644 --- a/log-tree.c +++ b/log-tree.c @@ -134,7 +134,8 @@ static int add_ref_decoration(const char *refname, const struct object_id *oid, int flags, void *cb_data) { struct object *obj; - enum decoration_type type = DECORATION_NONE; + enum object_type objtype; + enum decoration_type deco_type = DECORATION_NONE; struct decoration_filter *filter = (struct decoration_filter *)cb_data; if (filter && !ref_filter_match(refname, filter)) @@ -155,28 +156,29 @@ static int add_ref_decoration(const char *refname, const struct object_id *oid, return 0; } - obj = parse_object(the_repository, oid); - if (!obj) + objtype = oid_object_info(the_repository, oid, NULL); + if (objtype < 0) return 0; + obj = lookup_object_by_type(the_repository, oid, objtype); if (starts_with(refname, "refs/heads/")) - type = DECORATION_REF_LOCAL; + deco_type = DECORATION_REF_LOCAL; else if (starts_with(refname, "refs/remotes/")) - type = DECORATION_REF_REMOTE; + deco_type = DECORATION_REF_REMOTE; else if (starts_with(refname, "refs/tags/")) - type = DECORATION_REF_TAG; + deco_type = DECORATION_REF_TAG; else if (!strcmp(refname, "refs/stash")) - type = DECORATION_REF_STASH; + deco_type = DECORATION_REF_STASH; else if (!strcmp(refname, "HEAD")) - type = DECORATION_REF_HEAD; + deco_type = DECORATION_REF_HEAD; - add_name_decoration(type, refname, obj); + add_name_decoration(deco_type, refname, obj); while (obj->type == OBJ_TAG) { + if (!obj->parsed) + parse_object(the_repository, &obj->oid); obj = ((struct tag *)obj)->tagged; if (!obj) break; - if (!obj->parsed) - parse_object(the_repository, &obj->oid); add_name_decoration(DECORATION_REF_TAG, refname, obj); } return 0; @@ -185,6 +185,24 @@ struct object *lookup_unknown_object(struct repository *r, const struct object_i return obj; } +struct object *lookup_object_by_type(struct repository *r, + const struct object_id *oid, + enum object_type type) +{ + switch (type) { + case OBJ_COMMIT: + return (struct object *)lookup_commit(r, oid); + case OBJ_TREE: + return (struct object *)lookup_tree(r, oid); + case OBJ_TAG: + return (struct object *)lookup_tag(r, oid); + case OBJ_BLOB: + return (struct object *)lookup_blob(r, oid); + default: + die("BUG: unknown object type %d", type); + } +} + struct object *parse_object_buffer(struct repository *r, const struct object_id *oid, enum object_type type, unsigned long size, void *buffer, int *eaten_p) { struct object *obj; @@ -144,9 +144,27 @@ struct object *parse_object_or_die(const struct object_id *oid, const char *name */ struct object *parse_object_buffer(struct repository *r, const struct object_id *oid, enum object_type type, unsigned long size, void *buffer, int *eaten_p); -/** Returns the object, with potentially excess memory allocated. **/ +/* + * Allocate and return an object struct, even if you do not know the type of + * the object. The returned object may have its "type" field set to a real type + * (if somebody previously called lookup_blob(), etc), or it may be set to + * OBJ_NONE. In the latter case, subsequent calls to lookup_blob(), etc, will + * set the type field as appropriate. + * + * Use this when you do not know the expected type of an object and want to + * avoid parsing it for efficiency reasons. Try to avoid it otherwise; it + * may allocate excess memory, since the returned object must be as large as + * the maximum struct of any type. + */ struct object *lookup_unknown_object(struct repository *r, const struct object_id *oid); +/* + * Dispatch to the appropriate lookup_blob(), lookup_commit(), etc, based on + * "type". + */ +struct object *lookup_object_by_type(struct repository *r, const struct object_id *oid, + enum object_type type); + struct object_list *object_list_insert(struct object *item, struct object_list **list_p); @@ -1735,6 +1735,10 @@ static size_t userformat_want_item(struct strbuf *sb, const char *placeholder, case 'S': w->source = 1; break; + case 'd': + case 'D': + w->decorate = 1; + break; } return 0; } @@ -65,12 +65,16 @@ static inline int cmit_fmt_is_mail(enum cmit_fmt fmt) return (fmt == CMIT_FMT_EMAIL || fmt == CMIT_FMT_MBOXRD); } +/* + * Examine the user-specified format given by "fmt" (or if NULL, the global one + * previously saved by get_commit_format()), and set flags based on which items + * the format will need when it is expanded. + */ struct userformat_want { unsigned notes:1; unsigned source:1; + unsigned decorate:1; }; - -/* Set the flag "w->notes" if there is placeholder %N in "fmt". */ void userformat_find_requirements(const char *fmt, struct userformat_want *w); /* diff --git a/reachable.c b/reachable.c index c59847257a..84e3d0d75e 100644 --- a/reachable.c +++ b/reachable.c @@ -159,24 +159,6 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs, FOR_EACH_OBJECT_LOCAL_ONLY); } -static void *lookup_object_by_type(struct repository *r, - const struct object_id *oid, - enum object_type type) -{ - switch (type) { - case OBJ_COMMIT: - return lookup_commit(r, oid); - case OBJ_TREE: - return lookup_tree(r, oid); - case OBJ_TAG: - return lookup_tag(r, oid); - case OBJ_BLOB: - return lookup_blob(r, oid); - default: - die("BUG: unknown object type %d", type); - } -} - static int mark_object_seen(const struct object_id *oid, enum object_type type, int exclude, diff --git a/t/t4202-log.sh b/t/t4202-log.sh index 39e746fbcb..9dfead936b 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -1915,6 +1915,20 @@ test_expect_success '--exclude-promisor-objects does not BUG-crash' ' test_must_fail git log --exclude-promisor-objects source-a ' +test_expect_success 'log --decorate includes all levels of tag annotated tags' ' + git checkout -b branch && + git commit --allow-empty -m "new commit" && + git tag lightweight HEAD && + git tag -m annotated annotated HEAD && + git tag -m double-0 double-0 HEAD && + git tag -m double-1 double-1 double-0 && + cat >expect <<-\EOF && + HEAD -> branch, tag: lightweight, tag: double-1, tag: double-0, tag: annotated + EOF + git log -1 --format="%D" >actual && + test_cmp expect actual +' + test_expect_success 'log --end-of-options' ' git update-ref refs/heads/--source HEAD && git log --end-of-options --source >actual && |