2525
2626typedef struct config_entry_list {
2727 struct config_entry_list * next ;
28+ struct config_entry_list * last ;
2829 git_config_entry * entry ;
2930} config_entry_list ;
3031
@@ -131,15 +132,11 @@ int git_config_file_normalize_section(char *start, char *end)
131132
132133static void config_entry_list_append (config_entry_list * * list , config_entry_list * entry )
133134{
134- config_entry_list * head = * list ;
135-
136- if (head ) {
137- while (head -> next != NULL )
138- head = head -> next ;
139- head -> next = entry ;
140- } else {
135+ if (* list )
136+ (* list )-> last -> next = entry ;
137+ else
141138 * list = entry ;
142- }
139+ ( * list ) -> last = entry ;
143140}
144141
145142/* Add or append the new config option */
@@ -155,6 +152,17 @@ static int diskfile_entries_append(diskfile_entries *entries, git_config_entry *
155152
156153 pos = git_strmap_lookup_index (entries -> map , entry -> name );
157154 if (!git_strmap_valid_index (entries -> map , pos )) {
155+ /*
156+ * We only ever inspect `last` from the first config
157+ * entry in a multivar. In case where this new entry is
158+ * the first one in the entry map, it will also be the
159+ * last one at the time of adding it, which is
160+ * why we set `last` here to itself. Otherwise we
161+ * do not have to set `last` and leave it set to
162+ * `NULL`.
163+ */
164+ var -> last = var ;
165+
158166 git_strmap_insert (entries -> map , entry -> name , var , & error );
159167
160168 if (error > 0 )
@@ -517,10 +525,7 @@ static int config_get(git_config_backend *cfg, const char *key, git_config_entry
517525 }
518526
519527 var = git_strmap_value_at (entry_map , pos );
520- while (var -> next )
521- var = var -> next ;
522-
523- * out = var -> entry ;
528+ * out = var -> last -> entry ;
524529 (* out )-> free = free_diskfile_entry ;
525530 (* out )-> payload = entries ;
526531
0 commit comments