Jiang Xin <worldhello.net@xxxxxxxxx> writes: > diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c > index a687218167..b7e4ee1483 100644 > --- a/builtin/receive-pack.c > +++ b/builtin/receive-pack.c > @@ -98,6 +98,16 @@ static int keepalive_in_sec = 5; > > static struct tmp_objdir *tmp_objdir; > > +static struct proc_receive_ref { > + unsigned int want_add:1, > + want_delete:1, > + want_modify:1; > + char *ref_prefix; > + struct proc_receive_ref *next; > +} *proc_receive_ref = NULL; Let BSS do its job here. > +static void proc_receive_ref_append(const char *prefix); > + > static enum deny_action parse_deny_action(const char *var, const char *value) > { > if (value) { > @@ -230,6 +240,13 @@ static int receive_pack_config(const char *var, const char *value, void *cb) > return 0; > } > > + if (strcmp(var, "receive.procreceiverefs") == 0) { We may want to fix the style of this function in a preliminary clean-up, but not in the middle of the series, so let's agree to let this pass. > @@ -325,6 +342,84 @@ struct command { > char ref_name[FLEX_ARRAY]; /* more */ > }; > > +static void proc_receive_ref_append(const char *prefix) > +{ > + struct proc_receive_ref *ref_pattern; > + char *p; > + int len; > + > + ref_pattern = xcalloc(1, sizeof(struct proc_receive_ref)); > + p = strchr(prefix, ':'); A colon ':' is not a valid character in a refname, so the use of it as a separator for the prefix would be reasonable. > + if (p) { > + while (prefix < p) { > + if (*prefix == 'a') > + ref_pattern->want_add = 1; > + else if (*prefix == 'd') > + ref_pattern->want_delete = 1; > + else if (*prefix == 'm') > + ref_pattern->want_modify = 1; > + prefix++; > + } > + prefix++; > + } else { > + ref_pattern->want_add = 1; > + ref_pattern->want_delete = 1; > + ref_pattern->want_modify = 1; > + } > + ref_pattern->next = NULL; > + ref_pattern->ref_prefix = xstrdup(prefix); > + len = strlen(ref_pattern->ref_prefix); > + while (len && ref_pattern->ref_prefix[len - 1] == '/') > + ref_pattern->ref_prefix[--len] = '\0'; Why not count "size_t len" before you make a copy of prefix with tail adjustment, so that you can do xmemdupz() at the end without need for potential overallocation? > + if (proc_receive_ref == NULL) { Style: if (!proc_receive_ref) { like you did below. > +static int proc_receive_ref_matches(struct command *cmd) > +{ > + struct proc_receive_ref *p; > + > + if (!proc_receive_ref) > + return 0; > + > + for (p = proc_receive_ref; p; p = p->next) { > + const char *match = p->ref_prefix; > + int neg = 0; > + const char *remains; > + > + if (!p->want_add && is_null_oid(&cmd->old_oid)) > + continue; > + else if (!p->want_delete && is_null_oid(&cmd->new_oid)) > + continue; > + else if (!p->want_modify && > + !is_null_oid(&cmd->old_oid) && > + !is_null_oid(&cmd->new_oid)) > + continue; > + > + if (*match == '!') { > + neg = 1; > + match++; > + } Shouldn't the "negate" bit be jsut another field that has want_{add,delete,modify}, so that proc_receive_ref_append() can parse it only once without these four lines?