#include "remote.h"
#include "refs.h"
+static struct refspec s_tag_refspec = {
+ 0,
+ 1,
+ 0,
+ "refs/tags/",
+ "refs/tags/"
+};
+
+const struct refspec *tag_refspec = &s_tag_refspec;
+
struct counted_string {
size_t len;
const char *s;
remote->fetch_tags = 1; /* always auto-follow */
}
-static int handle_config(const char *key, const char *value)
+static int handle_config(const char *key, const char *value, void *cb)
{
const char *name;
const char *subkey;
return 0;
}
remote = make_remote(name, subkey - name);
- if (!value) {
- /* if we ever have a boolean variable, e.g. "remote.*.disabled"
- * [remote "frotz"]
- * disabled
- * is a valid way to set it to true; we get NULL in value so
- * we need to handle it here.
- *
- * if (!strcmp(subkey, ".disabled")) {
- * val = git_config_bool(key, value);
- * return 0;
- * } else
- *
- */
- return 0; /* ignore unknown booleans */
- }
- if (!strcmp(subkey, ".url")) {
- add_url(remote, xstrdup(value));
+ if (!strcmp(subkey, ".mirror"))
+ remote->mirror = git_config_bool(key, value);
+ else if (!strcmp(subkey, ".skipdefaultupdate"))
+ remote->skip_default_update = git_config_bool(key, value);
+
+ else if (!strcmp(subkey, ".url")) {
+ const char *v;
+ if (git_config_string(&v, key, value))
+ return -1;
+ add_url(remote, v);
} else if (!strcmp(subkey, ".push")) {
- add_push_refspec(remote, xstrdup(value));
+ const char *v;
+ if (git_config_string(&v, key, value))
+ return -1;
+ add_push_refspec(remote, v);
} else if (!strcmp(subkey, ".fetch")) {
- add_fetch_refspec(remote, xstrdup(value));
+ const char *v;
+ if (git_config_string(&v, key, value))
+ return -1;
+ add_fetch_refspec(remote, v);
} else if (!strcmp(subkey, ".receivepack")) {
+ const char *v;
+ if (git_config_string(&v, key, value))
+ return -1;
if (!remote->receivepack)
- remote->receivepack = xstrdup(value);
+ remote->receivepack = v;
else
error("more than one receivepack given, using the first");
} else if (!strcmp(subkey, ".uploadpack")) {
+ const char *v;
+ if (git_config_string(&v, key, value))
+ return -1;
if (!remote->uploadpack)
- remote->uploadpack = xstrdup(value);
+ remote->uploadpack = v;
else
error("more than one uploadpack given, using the first");
} else if (!strcmp(subkey, ".tagopt")) {
if (!strcmp(value, "--no-tags"))
remote->fetch_tags = -1;
} else if (!strcmp(subkey, ".proxy")) {
- remote->http_proxy = xstrdup(value);
- } else if (!strcmp(subkey, ".skipdefaultupdate"))
- remote->skip_default_update = 1;
+ return git_config_string((const char **)&remote->http_proxy,
+ key, value);
+ }
return 0;
}
current_branch =
make_branch(head_ref + strlen("refs/heads/"), 0);
}
- git_config(handle_config);
+ git_config(handle_config, NULL);
alias_all_urls();
}
return ret;
}
+struct ref *alloc_ref_from_str(const char* str)
+{
+ struct ref *ret = alloc_ref(strlen(str) + 1);
+ strcpy(ret->name, str);
+ return ret;
+}
+
static struct ref *copy_ref(const struct ref *ref)
{
struct ref *ret = xmalloc(sizeof(struct ref) + strlen(ref->name) + 1);
return ret;
}
+void free_ref(struct ref *ref)
+{
+ if (!ref)
+ return;
+ free(ref->remote_status);
+ free(ref->symref);
+ free(ref);
+}
+
void free_refs(struct ref *ref)
{
struct ref *next;
while (ref) {
next = ref->next;
free(ref->peer_ref);
- free(ref);
+ free_ref(ref);
ref = next;
}
}
{
unsigned char sha1[20];
struct ref *ref;
- int len;
if (!*name) {
ref = alloc_ref(20);
}
if (get_sha1(name, sha1))
return NULL;
- len = strlen(name) + 1;
- ref = alloc_ref(len);
- memcpy(ref->name, name, len);
+ ref = alloc_ref_from_str(name);
hashcpy(ref->new_sha1, sha1);
return ref;
}
static struct ref *make_linked_ref(const char *name, struct ref ***tail)
{
- struct ref *ret;
- size_t len;
-
- len = strlen(name) + 1;
- ret = alloc_ref(len);
- memcpy(ret->name, name, len);
+ struct ref *ret = alloc_ref_from_str(name);
tail_link_ref(ret, tail);
return ret;
}
static int match_explicit(struct ref *src, struct ref *dst,
struct ref ***dst_tail,
- struct refspec *rs,
- int errs)
+ struct refspec *rs)
{
struct ref *matched_src, *matched_dst;
char *dst_guess;
if (rs->pattern || rs->matching)
- return errs;
+ return 0;
matched_src = matched_dst = NULL;
switch (count_refspec_match(rs->src, src, &matched_src)) {
*/
matched_src = try_explicit_object_name(rs->src);
if (!matched_src)
- error("src refspec %s does not match any.", rs->src);
+ return error("src refspec %s does not match any.", rs->src);
break;
default:
- matched_src = NULL;
- error("src refspec %s matches more than one.", rs->src);
- break;
+ return error("src refspec %s matches more than one.", rs->src);
}
- if (!matched_src)
- errs = 1;
-
if (!dst_value) {
unsigned char sha1[20];
int flag;
- if (!matched_src)
- return errs;
dst_value = resolve_ref(matched_src->name, sha1, 1, &flag);
if (!dst_value ||
((flag & REF_ISSYMREF) &&
dst_value);
break;
}
- if (errs || !matched_dst)
- return 1;
- if (matched_dst->peer_ref) {
- errs = 1;
- error("dst ref %s receives from more than one src.",
+ if (!matched_dst)
+ return -1;
+ if (matched_dst->peer_ref)
+ return error("dst ref %s receives from more than one src.",
matched_dst->name);
- }
else {
matched_dst->peer_ref = matched_src;
matched_dst->force = rs->force;
}
- return errs;
+ return 0;
}
static int match_explicit_refs(struct ref *src, struct ref *dst,
{
int i, errs;
for (i = errs = 0; i < rs_nr; i++)
- errs |= match_explicit(src, dst, dst_tail, &rs[i], errs);
- return -errs;
+ errs += match_explicit(src, dst, dst_tail, &rs[i]);
+ return errs;
}
static const struct refspec *check_pattern_match(const struct refspec *rs,
return NULL;
if (!prefixcmp(name, "refs/")) {
- ret = alloc_ref(strlen(name) + 1);
- strcpy(ret->name, name);
- return ret;
+ return alloc_ref_from_str(name);
}
if (!prefixcmp(name, "heads/") ||
return 0;
}
+
+int resolve_remote_symref(struct ref *ref, struct ref *list)
+{
+ if (!ref->symref)
+ return 0;
+ for (; list; list = list->next)
+ if (!strcmp(ref->symref, list->name)) {
+ hashcpy(ref->old_sha1, list->old_sha1);
+ return 0;
+ }
+ return 1;
+}