summaryrefslogtreecommitdiff
path: root/contrib/perf/01-git-peel-decoration.patch
blob: 909f872369226c4edfe9b9163900dc8776f0dd88 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
diff --git a/log-tree.c b/log-tree.c
index 7e048701d0..ad2b19fda2 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -196,6 +196,27 @@ static int add_ref_decoration(const struct reference *ref, void *cb_data)
 	}
 
 	add_name_decoration(deco_type, ref->name, obj);
+	if (obj->type == OBJ_TAG) {
+		struct object_id peeled;
+		/*
+		 * The ref backend often already knows what a tag peels to
+		 * (packed-refs records it). Using that saves inflating every
+		 * tag object just to walk the chain, which dominates
+		 * --decorate on tag-heavy repositories.
+		 */
+		if (ref->peeled_oid &&
+		    !reference_get_peeled_oid(the_repository, ref, &peeled)) {
+			enum object_type ptype;
+			ptype = odb_read_object_info(the_repository->objects,
+						     &peeled, NULL);
+			if (ptype < 0)
+				return 0;
+			obj = lookup_object_by_type(the_repository, &peeled, ptype);
+			if (obj)
+				add_name_decoration(DECORATION_REF_TAG, ref->name, obj);
+			return 0;
+		}
+	}
 	while (obj->type == OBJ_TAG) {
 		if (!obj->parsed)
 			parse_object(the_repository, &obj->oid);