166
branch->merge_name[branch->merge_nr++] = name;
167
}
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
+
221
static struct branch *make_branch(struct remote_state *remote_state,
222
const char *name, size_t len)
223
{
224
struct branch *ret;
173
- int i;
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;
229
181
- ALLOC_GROW(remote_state->branches, remote_state->branches_nr + 1,
182
- remote_state->branches_alloc);
230
CALLOC_ARRAY(ret, 1);
184
- remote_state->branches[remote_state->branches_nr++] = ret;
231
ret->name = xstrndup(name, len);
232
ret->refname = xstrfmt("refs/heads/%s", ret->name);
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");
237
return ret;
238
}
239
549
const char *remote_for_branch(struct branch *branch, int *explicit)
550
{
551
read_config(the_repository);
552
+ die_on_missing_branch(the_repository, branch);
553
+
554
return remotes_remote_for_branch(the_repository->remote_state, branch,
555
explicit);
556
}
575
const char *pushremote_for_branch(struct branch *branch, int *explicit)
576
{
577
read_config(the_repository);
578
+ die_on_missing_branch(the_repository, branch);
579
+
580
return remotes_pushremote_for_branch(the_repository->remote_state,
581
branch, explicit);
582
}
587
const char *remote_ref_for_branch(struct branch *branch, int for_push)
588
{
589
read_config(the_repository);
590
+ die_on_missing_branch(the_repository, branch);
591
+
592
if (branch) {
593
if (!for_push) {
594
if (branch->merge_nr) {
1934
const char *branch_get_push(struct branch *branch, struct strbuf *err)
1935
{
1936
read_config(the_repository);
1937
+ die_on_missing_branch(the_repository, branch);
1938
+
1939
if (!branch)
1940
return error_buf(err, _("HEAD does not point to a branch"));
1941
2709
memset(r, 0, sizeof(*r));
2710
2711
hashmap_init(&r->remotes_hash, remotes_hash_cmp, NULL, 0);
2712
+ hashmap_init(&r->branches_hash, branches_hash_cmp, NULL, 0);
2713
return r;
2714
}
2715
2725
remote_state->remotes_nr = 0;
2726
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);
2729
}