Skip to content

Commit 9b67eb6

Browse files
pks-tttaylorr
authored andcommitted
refs: get rid of global list of hidden refs
We're about to add a new argument to git-rev-list(1) that allows it to add all references that are visible when taking `transfer.hideRefs` et al into account. This will require us to potentially parse multiple sets of hidden refs, which is not easily possible right now as there is only a single, global instance of the list of parsed hidden refs. Refactor `parse_hide_refs_config()` and `ref_is_hidden()` so that both take the list of hidden references as input and adjust callers to keep a local list, instead. This allows us to easily use multiple hidden-ref lists. Furthermore, it allows us to properly free this list before we exit. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Taylor Blau <[email protected]>
1 parent 5eeb9aa commit 9b67eb6

File tree

5 files changed

+39
-31
lines changed

5 files changed

+39
-31
lines changed

builtin/receive-pack.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ static struct object_id push_cert_oid;
8080
static struct signature_check sigcheck;
8181
static const char *push_cert_nonce;
8282
static const char *cert_nonce_seed;
83+
static struct string_list hidden_refs = STRING_LIST_INIT_DUP;
8384

8485
static const char *NONCE_UNSOLICITED = "UNSOLICITED";
8586
static const char *NONCE_BAD = "BAD";
@@ -130,7 +131,7 @@ static enum deny_action parse_deny_action(const char *var, const char *value)
130131

131132
static int receive_pack_config(const char *var, const char *value, void *cb)
132133
{
133-
int status = parse_hide_refs_config(var, value, "receive");
134+
int status = parse_hide_refs_config(var, value, "receive", &hidden_refs);
134135

135136
if (status)
136137
return status;
@@ -296,7 +297,7 @@ static int show_ref_cb(const char *path_full, const struct object_id *oid,
296297
struct oidset *seen = data;
297298
const char *path = strip_namespace(path_full);
298299

299-
if (ref_is_hidden(path, path_full))
300+
if (ref_is_hidden(path, path_full, &hidden_refs))
300301
return 0;
301302

302303
/*
@@ -1794,7 +1795,7 @@ static void reject_updates_to_hidden(struct command *commands)
17941795
strbuf_setlen(&refname_full, prefix_len);
17951796
strbuf_addstr(&refname_full, cmd->ref_name);
17961797

1797-
if (!ref_is_hidden(cmd->ref_name, refname_full.buf))
1798+
if (!ref_is_hidden(cmd->ref_name, refname_full.buf, &hidden_refs))
17981799
continue;
17991800
if (is_null_oid(&cmd->new_oid))
18001801
cmd->error_string = "deny deleting a hidden ref";
@@ -2591,6 +2592,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
25912592
packet_flush(1);
25922593
oid_array_clear(&shallow);
25932594
oid_array_clear(&ref);
2595+
string_list_clear(&hidden_refs, 0);
25942596
free((void *)push_cert_nonce);
25952597
return 0;
25962598
}

ls-refs.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "ls-refs.h"
77
#include "pkt-line.h"
88
#include "config.h"
9+
#include "string-list.h"
910

1011
static int config_read;
1112
static int advertise_unborn;
@@ -73,6 +74,7 @@ struct ls_refs_data {
7374
unsigned symrefs;
7475
struct strvec prefixes;
7576
struct strbuf buf;
77+
struct string_list hidden_refs;
7678
unsigned unborn : 1;
7779
};
7880

@@ -84,7 +86,7 @@ static int send_ref(const char *refname, const struct object_id *oid,
8486

8587
strbuf_reset(&data->buf);
8688

87-
if (ref_is_hidden(refname_nons, refname))
89+
if (ref_is_hidden(refname_nons, refname, &data->hidden_refs))
8890
return 0;
8991

9092
if (!ref_match(&data->prefixes, refname_nons))
@@ -137,14 +139,15 @@ static void send_possibly_unborn_head(struct ls_refs_data *data)
137139
}
138140

139141
static int ls_refs_config(const char *var, const char *value,
140-
void *data UNUSED)
142+
void *cb_data)
141143
{
144+
struct ls_refs_data *data = cb_data;
142145
/*
143146
* We only serve fetches over v2 for now, so respect only "uploadpack"
144147
* config. This may need to eventually be expanded to "receive", but we
145148
* don't yet know how that information will be passed to ls-refs.
146149
*/
147-
return parse_hide_refs_config(var, value, "uploadpack");
150+
return parse_hide_refs_config(var, value, "uploadpack", &data->hidden_refs);
148151
}
149152

150153
int ls_refs(struct repository *r, struct packet_reader *request)
@@ -154,9 +157,10 @@ int ls_refs(struct repository *r, struct packet_reader *request)
154157
memset(&data, 0, sizeof(data));
155158
strvec_init(&data.prefixes);
156159
strbuf_init(&data.buf, 0);
160+
string_list_init_dup(&data.hidden_refs);
157161

158162
ensure_config_read();
159-
git_config(ls_refs_config, NULL);
163+
git_config(ls_refs_config, &data);
160164

161165
while (packet_reader_read(request) == PACKET_READ_NORMAL) {
162166
const char *arg = request->line;
@@ -195,6 +199,7 @@ int ls_refs(struct repository *r, struct packet_reader *request)
195199
packet_fflush(stdout);
196200
strvec_clear(&data.prefixes);
197201
strbuf_release(&data.buf);
202+
string_list_clear(&data.hidden_refs, 0);
198203
return 0;
199204
}
200205

refs.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,9 +1414,8 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
14141414
refname, strict);
14151415
}
14161416

1417-
static struct string_list *hide_refs;
1418-
1419-
int parse_hide_refs_config(const char *var, const char *value, const char *section)
1417+
int parse_hide_refs_config(const char *var, const char *value, const char *section,
1418+
struct string_list *hide_refs)
14201419
{
14211420
const char *key;
14221421
if (!strcmp("transfer.hiderefs", var) ||
@@ -1431,21 +1430,16 @@ int parse_hide_refs_config(const char *var, const char *value, const char *secti
14311430
len = strlen(ref);
14321431
while (len && ref[len - 1] == '/')
14331432
ref[--len] = '\0';
1434-
if (!hide_refs) {
1435-
CALLOC_ARRAY(hide_refs, 1);
1436-
hide_refs->strdup_strings = 1;
1437-
}
14381433
string_list_append_nodup(hide_refs, ref);
14391434
}
14401435
return 0;
14411436
}
14421437

1443-
int ref_is_hidden(const char *refname, const char *refname_full)
1438+
int ref_is_hidden(const char *refname, const char *refname_full,
1439+
const struct string_list *hide_refs)
14441440
{
14451441
int i;
14461442

1447-
if (!hide_refs)
1448-
return 0;
14491443
for (i = hide_refs->nr - 1; i >= 0; i--) {
14501444
const char *match = hide_refs->items[i].string;
14511445
const char *subject;

refs.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -808,7 +808,8 @@ int update_ref(const char *msg, const char *refname,
808808
const struct object_id *new_oid, const struct object_id *old_oid,
809809
unsigned int flags, enum action_on_err onerr);
810810

811-
int parse_hide_refs_config(const char *var, const char *value, const char *);
811+
int parse_hide_refs_config(const char *var, const char *value, const char *,
812+
struct string_list *);
812813

813814
/*
814815
* Check whether a ref is hidden. If no namespace is set, both the first and
@@ -818,7 +819,7 @@ int parse_hide_refs_config(const char *var, const char *value, const char *);
818819
* the ref is outside that namespace, the first parameter is NULL. The second
819820
* parameter always points to the full ref name.
820821
*/
821-
int ref_is_hidden(const char *, const char *);
822+
int ref_is_hidden(const char *, const char *, const struct string_list *);
822823

823824
/* Is this a per-worktree ref living in the refs/ namespace? */
824825
int is_per_worktree_ref(const char *refname);

upload-pack.c

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ struct upload_pack_data {
6262
struct object_array have_obj;
6363
struct oid_array haves; /* v2 only */
6464
struct string_list wanted_refs; /* v2 only */
65+
struct string_list hidden_refs;
6566

6667
struct object_array shallows;
6768
struct string_list deepen_not;
@@ -118,6 +119,7 @@ static void upload_pack_data_init(struct upload_pack_data *data)
118119
{
119120
struct string_list symref = STRING_LIST_INIT_DUP;
120121
struct string_list wanted_refs = STRING_LIST_INIT_DUP;
122+
struct string_list hidden_refs = STRING_LIST_INIT_DUP;
121123
struct object_array want_obj = OBJECT_ARRAY_INIT;
122124
struct object_array have_obj = OBJECT_ARRAY_INIT;
123125
struct oid_array haves = OID_ARRAY_INIT;
@@ -130,6 +132,7 @@ static void upload_pack_data_init(struct upload_pack_data *data)
130132
memset(data, 0, sizeof(*data));
131133
data->symref = symref;
132134
data->wanted_refs = wanted_refs;
135+
data->hidden_refs = hidden_refs;
133136
data->want_obj = want_obj;
134137
data->have_obj = have_obj;
135138
data->haves = haves;
@@ -151,6 +154,7 @@ static void upload_pack_data_clear(struct upload_pack_data *data)
151154
{
152155
string_list_clear(&data->symref, 1);
153156
string_list_clear(&data->wanted_refs, 1);
157+
string_list_clear(&data->hidden_refs, 0);
154158
object_array_clear(&data->want_obj);
155159
object_array_clear(&data->have_obj);
156160
oid_array_clear(&data->haves);
@@ -842,8 +846,8 @@ static void deepen(struct upload_pack_data *data, int depth)
842846
* Checking for reachable shallows requires that our refs be
843847
* marked with OUR_REF.
844848
*/
845-
head_ref_namespaced(check_ref, NULL);
846-
for_each_namespaced_ref(check_ref, NULL);
849+
head_ref_namespaced(check_ref, data);
850+
for_each_namespaced_ref(check_ref, data);
847851

848852
get_reachable_list(data, &reachable_shallows);
849853
result = get_shallow_commits(&reachable_shallows,
@@ -1158,11 +1162,11 @@ static void receive_needs(struct upload_pack_data *data,
11581162

11591163
/* return non-zero if the ref is hidden, otherwise 0 */
11601164
static int mark_our_ref(const char *refname, const char *refname_full,
1161-
const struct object_id *oid)
1165+
const struct object_id *oid, const struct string_list *hidden_refs)
11621166
{
11631167
struct object *o = lookup_unknown_object(the_repository, oid);
11641168

1165-
if (ref_is_hidden(refname, refname_full)) {
1169+
if (ref_is_hidden(refname, refname_full, hidden_refs)) {
11661170
o->flags |= HIDDEN_REF;
11671171
return 1;
11681172
}
@@ -1171,11 +1175,12 @@ static int mark_our_ref(const char *refname, const char *refname_full,
11711175
}
11721176

11731177
static int check_ref(const char *refname_full, const struct object_id *oid,
1174-
int flag UNUSED, void *cb_data UNUSED)
1178+
int flag UNUSED, void *cb_data)
11751179
{
11761180
const char *refname = strip_namespace(refname_full);
1181+
struct upload_pack_data *data = cb_data;
11771182

1178-
mark_our_ref(refname, refname_full, oid);
1183+
mark_our_ref(refname, refname_full, oid, &data->hidden_refs);
11791184
return 0;
11801185
}
11811186

@@ -1204,7 +1209,7 @@ static int send_ref(const char *refname, const struct object_id *oid,
12041209
struct object_id peeled;
12051210
struct upload_pack_data *data = cb_data;
12061211

1207-
if (mark_our_ref(refname_nons, refname, oid))
1212+
if (mark_our_ref(refname_nons, refname, oid, &data->hidden_refs))
12081213
return 0;
12091214

12101215
if (capabilities) {
@@ -1327,7 +1332,7 @@ static int upload_pack_config(const char *var, const char *value, void *cb_data)
13271332
if (parse_object_filter_config(var, value, data) < 0)
13281333
return -1;
13291334

1330-
return parse_hide_refs_config(var, value, "uploadpack");
1335+
return parse_hide_refs_config(var, value, "uploadpack", &data->hidden_refs);
13311336
}
13321337

13331338
static int upload_pack_protected_config(const char *var, const char *value, void *cb_data)
@@ -1375,8 +1380,8 @@ void upload_pack(const int advertise_refs, const int stateless_rpc,
13751380
advertise_shallow_grafts(1);
13761381
packet_flush(1);
13771382
} else {
1378-
head_ref_namespaced(check_ref, NULL);
1379-
for_each_namespaced_ref(check_ref, NULL);
1383+
head_ref_namespaced(check_ref, &data);
1384+
for_each_namespaced_ref(check_ref, &data);
13801385
}
13811386

13821387
if (!advertise_refs) {
@@ -1441,6 +1446,7 @@ static int parse_want(struct packet_writer *writer, const char *line,
14411446

14421447
static int parse_want_ref(struct packet_writer *writer, const char *line,
14431448
struct string_list *wanted_refs,
1449+
struct string_list *hidden_refs,
14441450
struct object_array *want_obj)
14451451
{
14461452
const char *refname_nons;
@@ -1451,7 +1457,7 @@ static int parse_want_ref(struct packet_writer *writer, const char *line,
14511457
struct strbuf refname = STRBUF_INIT;
14521458

14531459
strbuf_addf(&refname, "%s%s", get_git_namespace(), refname_nons);
1454-
if (ref_is_hidden(refname_nons, refname.buf) ||
1460+
if (ref_is_hidden(refname_nons, refname.buf, hidden_refs) ||
14551461
read_ref(refname.buf, &oid)) {
14561462
packet_writer_error(writer, "unknown ref %s", refname_nons);
14571463
die("unknown ref %s", refname_nons);
@@ -1508,7 +1514,7 @@ static void process_args(struct packet_reader *request,
15081514
continue;
15091515
if (data->allow_ref_in_want &&
15101516
parse_want_ref(&data->writer, arg, &data->wanted_refs,
1511-
&data->want_obj))
1517+
&data->hidden_refs, &data->want_obj))
15121518
continue;
15131519
/* process have line */
15141520
if (parse_have(arg, &data->haves))

0 commit comments

Comments
 (0)