6
6
#include "tag.h"
7
7
#include "refs.h"
8
8
#include "parse-options.h"
9
+ #include "prio-queue.h"
9
10
#include "sha1-lookup.h"
10
11
#include "commit-slab.h"
11
12
@@ -79,30 +80,16 @@ static int is_better_name(struct rev_name *name,
79
80
return 0 ;
80
81
}
81
82
82
- static void name_rev (struct commit * commit ,
83
- const char * tip_name , timestamp_t taggerdate ,
84
- int generation , int distance , int from_tag ,
85
- int deref )
83
+ static struct rev_name * create_or_update_name (struct commit * commit ,
84
+ const char * tip_name ,
85
+ timestamp_t taggerdate ,
86
+ int generation , int distance ,
87
+ int from_tag )
86
88
{
87
89
struct rev_name * name = get_commit_rev_name (commit );
88
- struct commit_list * parents ;
89
- int parent_number = 1 ;
90
- char * to_free = NULL ;
91
-
92
- parse_commit (commit );
93
-
94
- if (commit -> date < cutoff )
95
- return ;
96
-
97
- if (deref ) {
98
- tip_name = to_free = xstrfmt ("%s^0" , tip_name );
99
-
100
- if (generation )
101
- die ("generation: %d, but deref?" , generation );
102
- }
103
90
104
91
if (name == NULL ) {
105
- name = xmalloc (sizeof (rev_name ));
92
+ name = xmalloc (sizeof (* name ));
106
93
set_commit_rev_name (commit , name );
107
94
goto copy_data ;
108
95
} else if (is_better_name (name , taggerdate , distance , from_tag )) {
@@ -112,35 +99,97 @@ static void name_rev(struct commit *commit,
112
99
name -> generation = generation ;
113
100
name -> distance = distance ;
114
101
name -> from_tag = from_tag ;
115
- } else {
102
+
103
+ return name ;
104
+ } else
105
+ return NULL ;
106
+ }
107
+
108
+ static void name_rev (struct commit * start_commit ,
109
+ const char * tip_name , timestamp_t taggerdate ,
110
+ int from_tag , int deref )
111
+ {
112
+ struct prio_queue queue ;
113
+ struct commit * commit ;
114
+ struct commit * * parents_to_queue = NULL ;
115
+ size_t parents_to_queue_nr , parents_to_queue_alloc = 0 ;
116
+ char * to_free = NULL ;
117
+
118
+ parse_commit (start_commit );
119
+ if (start_commit -> date < cutoff )
120
+ return ;
121
+
122
+ if (deref )
123
+ tip_name = to_free = xstrfmt ("%s^0" , tip_name );
124
+
125
+ if (!create_or_update_name (start_commit , tip_name , taggerdate , 0 , 0 ,
126
+ from_tag )) {
116
127
free (to_free );
117
128
return ;
118
129
}
119
130
120
- for (parents = commit -> parents ;
121
- parents ;
122
- parents = parents -> next , parent_number ++ ) {
123
- if (parent_number > 1 ) {
124
- size_t len ;
125
- char * new_name ;
126
-
127
- strip_suffix (tip_name , "^0" , & len );
128
- if (generation > 0 )
129
- new_name = xstrfmt ("%.*s~%d^%d" , (int )len , tip_name ,
130
- generation , parent_number );
131
- else
132
- new_name = xstrfmt ("%.*s^%d" , (int )len , tip_name ,
133
- parent_number );
134
-
135
- name_rev (parents -> item , new_name , taggerdate , 0 ,
136
- distance + MERGE_TRAVERSAL_WEIGHT ,
137
- from_tag , 0 );
138
- } else {
139
- name_rev (parents -> item , tip_name , taggerdate ,
140
- generation + 1 , distance + 1 ,
141
- from_tag , 0 );
131
+ memset (& queue , 0 , sizeof (queue )); /* Use the prio_queue as LIFO */
132
+ prio_queue_put (& queue , start_commit );
133
+
134
+ while ((commit = prio_queue_get (& queue ))) {
135
+ struct rev_name * name = get_commit_rev_name (commit );
136
+ struct commit_list * parents ;
137
+ int parent_number = 1 ;
138
+
139
+ parents_to_queue_nr = 0 ;
140
+
141
+ for (parents = commit -> parents ;
142
+ parents ;
143
+ parents = parents -> next , parent_number ++ ) {
144
+ struct commit * parent = parents -> item ;
145
+ const char * new_name ;
146
+ int generation , distance ;
147
+
148
+ parse_commit (parent );
149
+ if (parent -> date < cutoff )
150
+ continue ;
151
+
152
+ if (parent_number > 1 ) {
153
+ size_t len ;
154
+
155
+ strip_suffix (name -> tip_name , "^0" , & len );
156
+ if (name -> generation > 0 )
157
+ new_name = xstrfmt ("%.*s~%d^%d" ,
158
+ (int )len ,
159
+ name -> tip_name ,
160
+ name -> generation ,
161
+ parent_number );
162
+ else
163
+ new_name = xstrfmt ("%.*s^%d" , (int )len ,
164
+ name -> tip_name ,
165
+ parent_number );
166
+ generation = 0 ;
167
+ distance = name -> distance + MERGE_TRAVERSAL_WEIGHT ;
168
+ } else {
169
+ new_name = name -> tip_name ;
170
+ generation = name -> generation + 1 ;
171
+ distance = name -> distance + 1 ;
172
+ }
173
+
174
+ if (create_or_update_name (parent , new_name , taggerdate ,
175
+ generation , distance ,
176
+ from_tag )) {
177
+ ALLOC_GROW (parents_to_queue ,
178
+ parents_to_queue_nr + 1 ,
179
+ parents_to_queue_alloc );
180
+ parents_to_queue [parents_to_queue_nr ] = parent ;
181
+ parents_to_queue_nr ++ ;
182
+ }
142
183
}
184
+
185
+ /* The first parent must come out first from the prio_queue */
186
+ while (parents_to_queue_nr )
187
+ prio_queue_put (& queue ,
188
+ parents_to_queue [-- parents_to_queue_nr ]);
143
189
}
190
+
191
+ clear_prio_queue (& queue );
192
+ free (parents_to_queue );
144
193
}
145
194
146
195
static int subpath_matches (const char * path , const char * filter )
@@ -272,10 +321,9 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo
272
321
int from_tag = starts_with (path , "refs/tags/" );
273
322
274
323
if (taggerdate == TIME_MAX )
275
- taggerdate = (( struct commit * ) o ) -> date ;
324
+ taggerdate = commit -> date ;
276
325
path = name_ref_abbrev (path , can_abbreviate_output );
277
- name_rev (commit , xstrdup (path ), taggerdate , 0 , 0 ,
278
- from_tag , deref );
326
+ name_rev (commit , xstrdup (path ), taggerdate , from_tag , deref );
279
327
}
280
328
return 0 ;
281
329
}
@@ -321,11 +369,10 @@ static const char *get_rev_name(const struct object *o, struct strbuf *buf)
321
369
if (!n -> generation )
322
370
return n -> tip_name ;
323
371
else {
324
- int len = strlen (n -> tip_name );
325
- if (len > 2 && !strcmp (n -> tip_name + len - 2 , "^0" ))
326
- len -= 2 ;
327
372
strbuf_reset (buf );
328
- strbuf_addf (buf , "%.*s~%d" , len , n -> tip_name , n -> generation );
373
+ strbuf_addstr (buf , n -> tip_name );
374
+ strbuf_strip_suffix (buf , "^0" );
375
+ strbuf_addf (buf , "~%d" , n -> generation );
329
376
return buf -> buf ;
330
377
}
331
378
}
0 commit comments