diff --git a/branch.c b/branch.c
index df5d24fec6..e1585b10c2 100644
--- a/branch.c
+++ b/branch.c
@@ -38,7 +38,7 @@ static int find_tracked_branch(struct remote *remote, void *priv)
if (!remote_find_tracking(remote, &tracking->spec)) {
switch (++tracking->matches) {
case 1:
- string_list_append_nodup(tracking->srcs, tracking->spec.src);
+ string_list_append_nodup(tracking->srcs, tracking->spec.src_storage);
tracking->remote = remote->name;
break;
case 2:@@ -47,7 +47,7 @@ static int find_tracked_branch(struct remote *remote, void *priv)
/* fall through */
default:
string_list_append(&ftb->ambiguous_remotes, remote->name);
- free(tracking->spec.src);
+ free(tracking->spec.src_storage);
string_list_clear(tracking->srcs, 0);
break;
}
@@ -489,7 +489,7 @@ static int check_tracking_branch(struct remote *remote, void *cb_data)
memset(&query, 0, sizeof(struct refspec_item));
query.dst = tracking_branch;
res = !remote_find_tracking(remote, &query);
- free(query.src);
+ free(query.src_storage);
return res;
}
diff --git a/builtin/fetch.c b/builtin/fetch.c
index 06b60867f5..00a67c99ef 100644
--- a/builtin/fetch.c
+++ b/builtin/fetch.c
@@ -443,7 +443,7 @@ static void filter_prefetch_refspec(struct refspec *rs)
for (i = 0; i < rs->nr; i++) {
struct strbuf new_dst = STRBUF_INIT;
- char *old_dst;
+ const char *old_dst;
const char *sub = NULL;
if (rs->items[i].negative)@@ -454,8 +454,8 @@ static void filter_prefetch_refspec(struct refspec *rs)
ref_namespace[NAMESPACE_TAGS].ref))) {
int j;
- free(rs->items[i].src);
- free(rs->items[i].dst);
+ free(rs->items[i].src_storage);
+ free(rs->items[i].dst_storage);
for (j = i + 1; j < rs->nr; j++) {
rs->items[j - 1] = rs->items[j];@@ -481,7 +481,7 @@ static void filter_prefetch_refspec(struct refspec *rs)
rs->items[i].dst = strbuf_detach(&new_dst, NULL);
rs->items[i].force = 1;
- free(old_dst);
+ free(rs->items[i].dst_storage);
}
}
diff --git a/builtin/remote.c b/builtin/remote.c
index b44f580b8c..87b97f5ef1 100644
--- a/builtin/remote.c
+++ b/builtin/remote.c
@@ -496,8 +496,8 @@ static int get_head_names(const struct ref *remote_refs, struct ref_states *stat
struct refspec_item refspec = {
.force = 0,
.pattern = 1,
- .src = (char *) "refs/heads/*",
- .dst = (char *) "refs/heads/*",
+ .src = "refs/heads/*",
+ .dst = "refs/heads/*",
};
get_fetch_map(remote_refs, &refspec, &fetch_map_tail, 0);@@ -981,7 +981,7 @@ static int append_ref_to_tracked_list(const char *refname,
return 0;
memset(&refspec, 0, sizeof(refspec));
- refspec.dst = (char *)refname;
+ refspec.dst = refname;
if (!remote_find_tracking(states->remote, &refspec))
string_list_append(&states->tracked, abbrev_branch(refspec.src));
diff --git a/checkout.c b/checkout.c
index cfaea4bd10..327ab5f6e3 100644
--- a/checkout.c
+++ b/checkout.c
@@ -8,7 +8,7 @@
#include "strbuf.h"
struct tracking_name_data {
- /* const */ char *src_ref;
+ const char *src_ref;
char *dst_ref;
struct object_id *dst_oid;
int num_matches;@@ -27,7 +27,7 @@ static int check_tracking_name(struct remote *remote, void *cb_data)
query.src = cb->src_ref;
if (remote_find_tracking(remote, &query) ||
repo_get_oid(the_repository, query.dst, cb->dst_oid)) {
- free(query.dst);
+ free(query.dst_storage);
return 0;
}
cb->num_matches++;@@ -38,10 +38,10 @@ static int check_tracking_name(struct remote *remote, void *cb_data)
cb->default_dst_oid = dst;
}
if (cb->dst_ref) {
- free(query.dst);
+ free(query.dst_storage);
return 0;
}
- cb->dst_ref = query.dst;
+ cb->dst_ref = query.dst_storage;
return 0;
}
@@ -50,14 +50,15 @@ char *unique_tracking_name(const char *name, struct object_id *oid,
{
struct tracking_name_data cb_data = TRACKING_NAME_DATA_INIT;
const char *default_remote = NULL;
+ char *src_ref;
if (!git_config_get_string_tmp("checkout.defaultremote", &default_remote))
cb_data.default_remote = default_remote;
- cb_data.src_ref = xstrfmt("refs/heads/%s", name);
+ cb_data.src_ref = src_ref = xstrfmt("refs/heads/%s", name);
cb_data.dst_oid = oid;
for_each_remote(check_tracking_name, &cb_data);
if (dwim_remotes_matched)
*dwim_remotes_matched = cb_data.num_matches;
- free(cb_data.src_ref);
+ free(src_ref);
if (cb_data.num_matches == 1) {
free(cb_data.default_dst_ref);
free(cb_data.default_dst_oid);diff --git a/refspec.c b/refspec.c
index 1df5de6c2f..a7473c9628 100644
--- a/refspec.c
+++ b/refspec.c
@@ -163,8 +163,10 @@ void refspec_item_init_or_die(struct refspec_item *item, const char *refspec,
void refspec_item_clear(struct refspec_item *item)
{
- FREE_AND_NULL(item->src);
- FREE_AND_NULL(item->dst);
+ FREE_AND_NULL(item->src_storage);
+ item->src = NULL;
+ FREE_AND_NULL(item->dst_storage);
+ item->dst = NULL;
item->force = 0;
item->pattern = 0;
item->matching = 0;diff --git a/refspec.h b/refspec.h
index 754be45cee..fbc4352397 100644
--- a/refspec.h
+++ b/refspec.h
@@ -24,8 +24,10 @@ struct refspec_item {
unsigned exact_sha1 : 1;
unsigned negative : 1;
- char *src;
- char *dst;
+ const char *src;
+ const char *dst;
+ char *src_storage;
+ char *dst_storage;
};
#define REFSPEC_FETCH 1diff --git a/remote.c b/remote.c
index d319f28757..5cdc3a17cc 100644
--- a/remote.c
+++ b/remote.c
@@ -827,7 +827,8 @@ int remote_has_url(struct remote *remote, const char *url)
}
static int match_name_with_pattern(const char *key, const char *name,
- const char *value, char **result)
+ const char *value, char **result,
+ const char **result_const)
{
const char *kstar = strchr(key, '*');
size_t klen;@@ -850,6 +851,8 @@ static int match_name_with_pattern(const char *key, const char *name,
strbuf_add(&sb, name + klen, namelen - klen - ksuffixlen);
strbuf_addstr(&sb, vstar + 1);
*result = strbuf_detach(&sb, NULL);
+ if (result_const)
+ *result_const = *result;
}
return ret;
}
@@ -858,7 +861,7 @@ static int refspec_match(const struct refspec_item *refspec,
const char *name)
{
if (refspec->pattern)
- return match_name_with_pattern(refspec->src, name, NULL, NULL);
+ return match_name_with_pattern(refspec->src, name, NULL, NULL, NULL);
return !strcmp(refspec->src, name);
}@@ -927,7 +930,7 @@ static int query_matches_negative_refspec(struct refspec *rs, struct refspec_ite
const char *key = refspec->dst ? refspec->dst : refspec->src;
const char *value = refspec->src;
- if (match_name_with_pattern(key, needle, value, &expn_name))
+ if (match_name_with_pattern(key, needle, value, &expn_name, NULL))
string_list_append_nodup(&reversed, expn_name);
} else if (refspec->matching) {
/* For the special matching refspec, any query should match */@@ -967,12 +970,12 @@ static void query_refspecs_multiple(struct refspec *rs,
const char *key = find_src ? refspec->dst : refspec->src;
const char *value = find_src ? refspec->src : refspec->dst;
const char *needle = find_src ? query->dst : query->src;
- char **result = find_src ? &query->src : &query->dst;
+ char **result = find_src ? &query->src_storage : &query->dst_storage;
if (!refspec->dst || refspec->negative)
continue;
if (refspec->pattern) {
- if (match_name_with_pattern(key, needle, value, result))
+ if (match_name_with_pattern(key, needle, value, result, NULL))
string_list_append_nodup(results, *result);
} else if (!strcmp(needle, key)) {
string_list_append(results, value);@@ -985,7 +988,8 @@ int query_refspecs(struct refspec *rs, struct refspec_item *query)
int i;
int find_src = !query->src;
const char *needle = find_src ? query->dst : query->src;
- char **result = find_src ? &query->src : &query->dst;
+ char **result = find_src ? &query->src_storage : &query->dst_storage;
+ const char **result_const = find_src ? &query->src : &query->dst;
if (find_src && !query->dst)
BUG("query_refspecs: need either src or dst");@@ -1001,12 +1005,12 @@ int query_refspecs(struct refspec *rs, struct refspec_item *query)
if (!refspec->dst || refspec->negative)
continue;
if (refspec->pattern) {
- if (match_name_with_pattern(key, needle, value, result)) {
+ if (match_name_with_pattern(key, needle, value, result, result_const)) {
query->force = refspec->force;
return 0;
}
} else if (!strcmp(needle, key)) {
- *result = xstrdup(value);
+ *result_const = *result = xstrdup(value);
query->force = refspec->force;
return 0;
}@@ -1019,12 +1023,12 @@ char *apply_refspecs(struct refspec *rs, const char *name)
struct refspec_item query;
memset(&query, 0, sizeof(struct refspec_item));
- query.src = (char *)name;
+ query.src = name;
if (query_refspecs(rs, &query))
return NULL;
- return query.dst;
+ return query.dst_storage;
}
int remote_find_tracking(struct remote *remote, struct refspec_item *refspec)
@@ -1399,9 +1403,9 @@ static char *get_ref_match(const struct refspec *rs, const struct ref *ref,
const char *dst_side = item->dst ? item->dst : item->src;
int match;
if (direction == FROM_SRC)
- match = match_name_with_pattern(item->src, ref->name, dst_side, &name);
+ match = match_name_with_pattern(item->src, ref->name, dst_side, &name, NULL);
else
- match = match_name_with_pattern(dst_side, ref->name, item->src, &name);
+ match = match_name_with_pattern(dst_side, ref->name, item->src, &name, NULL);
if (match) {
matching_refs = i;
break;@@ -2020,7 +2024,7 @@ static struct ref *get_expanded_map(const struct ref *remote_refs,
if (strchr(ref->name, '^'))
continue; /* a dereference item */
if (match_name_with_pattern(refspec->src, ref->name,
- refspec->dst, &expn_name) &&
+ refspec->dst, &expn_name, NULL) &&
!ignore_symref_update(expn_name, &scratch)) {
struct ref *cpy = copy_ref(ref);
diff --git a/transport.c b/transport.c
index 83ddea8fbc..0cedda425c 100644
--- a/transport.c
+++ b/transport.c
@@ -550,7 +550,7 @@ static void update_one_tracking_ref(struct remote *remote, char *refname,
refs_update_ref(get_main_ref_store(the_repository),
"update by push", rs.dst, new_oid,
NULL, 0, 0);
- free(rs.dst);
+ free(rs.dst_storage);
}
}