diff options
Diffstat (limited to 'remote.c')
-rw-r--r-- | remote.c | 57 |
1 files changed, 57 insertions, 0 deletions
@@ -1921,3 +1921,60 @@ struct ref *get_stale_heads(struct refspec *refs, int ref_count, struct ref *fet string_list_clear(&ref_names, 0); return stale_refs; } + +/* + * Compare-and-swap + */ +void clear_cas_option(struct push_cas_option *cas) +{ + int i; + + for (i = 0; i < cas->nr; i++) + free(cas->entry[i].refname); + free(cas->entry); + memset(cas, 0, sizeof(*cas)); +} + +static struct push_cas *add_cas_entry(struct push_cas_option *cas, + const char *refname, + size_t refnamelen) +{ + struct push_cas *entry; + ALLOC_GROW(cas->entry, cas->nr + 1, cas->alloc); + entry = &cas->entry[cas->nr++]; + memset(entry, 0, sizeof(*entry)); + entry->refname = xmemdupz(refname, refnamelen); + return entry; +} + +int parse_push_cas_option(struct push_cas_option *cas, const char *arg, int unset) +{ + const char *colon; + struct push_cas *entry; + + if (unset) { + /* "--no-<option>" */ + clear_cas_option(cas); + return 0; + } + + if (!arg) { + /* just "--<option>" */ + cas->use_tracking_for_rest = 1; + return 0; + } + + /* "--<option>=refname" or "--<option>=refname:value" */ + colon = strchrnul(arg, ':'); + entry = add_cas_entry(cas, arg, colon - arg); + if (!*colon) + entry->use_tracking = 1; + else if (get_sha1(colon + 1, entry->expect)) + return error("cannot parse expected object name '%s'", colon + 1); + return 0; +} + +int parseopt_push_cas_option(const struct option *opt, const char *arg, int unset) +{ + return parse_push_cas_option(opt->value, arg, unset); +} |