@@ -166,25 +166,74 @@ static void add_merge(struct branch *branch, const char *name)
166
166
branch -> merge_name [branch -> merge_nr ++ ] = name ;
167
167
}
168
168
169
+ struct branches_hash_key {
170
+ const char * str ;
171
+ int len ;
172
+ };
173
+
174
+ static int branches_hash_cmp (const void * unused_cmp_data ,
175
+ const struct hashmap_entry * eptr ,
176
+ const struct hashmap_entry * entry_or_key ,
177
+ const void * keydata )
178
+ {
179
+ const struct branch * a , * b ;
180
+ const struct branches_hash_key * key = keydata ;
181
+
182
+ a = container_of (eptr , const struct branch , ent );
183
+ b = container_of (entry_or_key , const struct branch , ent );
184
+
185
+ if (key )
186
+ return strncmp (a -> name , key -> str , key -> len ) ||
187
+ a -> name [key -> len ];
188
+ else
189
+ return strcmp (a -> name , b -> name );
190
+ }
191
+
192
+ static struct branch * find_branch (struct remote_state * remote_state ,
193
+ const char * name , size_t len )
194
+ {
195
+ struct branches_hash_key lookup ;
196
+ struct hashmap_entry lookup_entry , * e ;
197
+
198
+ if (!len )
199
+ len = strlen (name );
200
+
201
+ lookup .str = name ;
202
+ lookup .len = len ;
203
+ hashmap_entry_init (& lookup_entry , memhash (name , len ));
204
+
205
+ e = hashmap_get (& remote_state -> branches_hash , & lookup_entry , & lookup );
206
+ if (e )
207
+ return container_of (e , struct branch , ent );
208
+
209
+ return NULL ;
210
+ }
211
+
212
+ static void die_on_missing_branch (struct repository * repo ,
213
+ struct branch * branch )
214
+ {
215
+ /* branch == NULL is always valid because it represents detached HEAD. */
216
+ if (branch &&
217
+ branch != find_branch (repo -> remote_state , branch -> name , 0 ))
218
+ die ("branch %s was not found in the repository" , branch -> name );
219
+ }
220
+
169
221
static struct branch * make_branch (struct remote_state * remote_state ,
170
222
const char * name , size_t len )
171
223
{
172
224
struct branch * ret ;
173
- int i ;
174
225
175
- for (i = 0 ; i < remote_state -> branches_nr ; i ++ ) {
176
- if (!strncmp (name , remote_state -> branches [i ]-> name , len ) &&
177
- !remote_state -> branches [i ]-> name [len ])
178
- return remote_state -> branches [i ];
179
- }
226
+ ret = find_branch (remote_state , name , len );
227
+ if (ret )
228
+ return ret ;
180
229
181
- ALLOC_GROW (remote_state -> branches , remote_state -> branches_nr + 1 ,
182
- remote_state -> branches_alloc );
183
230
CALLOC_ARRAY (ret , 1 );
184
- remote_state -> branches [remote_state -> branches_nr ++ ] = ret ;
185
231
ret -> name = xstrndup (name , len );
186
232
ret -> refname = xstrfmt ("refs/heads/%s" , ret -> name );
187
233
234
+ hashmap_entry_init (& ret -> ent , memhash (name , len ));
235
+ if (hashmap_put_entry (& remote_state -> branches_hash , ret , ent ))
236
+ BUG ("hashmap_put overwrote entry after hashmap_get returned NULL" );
188
237
return ret ;
189
238
}
190
239
@@ -500,6 +549,8 @@ static const char *remotes_remote_for_branch(struct remote_state *remote_state,
500
549
const char * remote_for_branch (struct branch * branch , int * explicit )
501
550
{
502
551
read_config (the_repository );
552
+ die_on_missing_branch (the_repository , branch );
553
+
503
554
return remotes_remote_for_branch (the_repository -> remote_state , branch ,
504
555
explicit );
505
556
}
@@ -524,6 +575,8 @@ remotes_pushremote_for_branch(struct remote_state *remote_state,
524
575
const char * pushremote_for_branch (struct branch * branch , int * explicit )
525
576
{
526
577
read_config (the_repository );
578
+ die_on_missing_branch (the_repository , branch );
579
+
527
580
return remotes_pushremote_for_branch (the_repository -> remote_state ,
528
581
branch , explicit );
529
582
}
@@ -534,6 +587,8 @@ static struct remote *remotes_remote_get(struct remote_state *remote_state,
534
587
const char * remote_ref_for_branch (struct branch * branch , int for_push )
535
588
{
536
589
read_config (the_repository );
590
+ die_on_missing_branch (the_repository , branch );
591
+
537
592
if (branch ) {
538
593
if (!for_push ) {
539
594
if (branch -> merge_nr ) {
@@ -1879,6 +1934,8 @@ static const char *branch_get_push_1(struct remote_state *remote_state,
1879
1934
const char * branch_get_push (struct branch * branch , struct strbuf * err )
1880
1935
{
1881
1936
read_config (the_repository );
1937
+ die_on_missing_branch (the_repository , branch );
1938
+
1882
1939
if (!branch )
1883
1940
return error_buf (err , _ ("HEAD does not point to a branch" ));
1884
1941
@@ -2652,6 +2709,7 @@ struct remote_state *remote_state_new(void)
2652
2709
memset (r , 0 , sizeof (* r ));
2653
2710
2654
2711
hashmap_init (& r -> remotes_hash , remotes_hash_cmp , NULL , 0 );
2712
+ hashmap_init (& r -> branches_hash , branches_hash_cmp , NULL , 0 );
2655
2713
return r ;
2656
2714
}
2657
2715
@@ -2667,11 +2725,5 @@ void remote_state_clear(struct remote_state *remote_state)
2667
2725
remote_state -> remotes_nr = 0 ;
2668
2726
2669
2727
hashmap_clear_and_free (& remote_state -> remotes_hash , struct remote , ent );
2670
-
2671
- for (i = 0 ; i < remote_state -> branches_nr ; i ++ ) {
2672
- FREE_AND_NULL (remote_state -> branches [i ]);
2673
- }
2674
- FREE_AND_NULL (remote_state -> branches );
2675
- remote_state -> branches_alloc = 0 ;
2676
- remote_state -> branches_nr = 0 ;
2728
+ hashmap_clear_and_free (& remote_state -> branches_hash , struct remote , ent );
2677
2729
}
0 commit comments