Browse Source

Merge branch 'tg/git-remote'

The internal API to interact with "remote.*" configuration
variables has been streamlined.

* tg/git-remote:
  remote: use remote_is_configured() for add and rename
  remote: actually check if remote exits
  remote: simplify remote_is_configured()
  remote: use parse_config_key
maint
Junio C Hamano 9 years ago
parent
commit
ae2f25542f
  1. 5
      builtin/fetch.c
  2. 23
      builtin/remote.c
  3. 82
      remote.c
  4. 3
      remote.h
  5. 33
      t/t5505-remote.sh

5
builtin/fetch.c

@ -1022,10 +1022,9 @@ static int add_remote_or_group(const char *name, struct string_list *list)


git_config(get_remote_group, &g); git_config(get_remote_group, &g);
if (list->nr == prev_nr) { if (list->nr == prev_nr) {
struct remote *remote; struct remote *remote = remote_get(name);
if (!remote_is_configured(name)) if (!remote_is_configured(remote))
return 0; return 0;
remote = remote_get(name);
string_list_append(list, remote->name); string_list_append(list, remote->name);
} }
return 1; return 1;

23
builtin/remote.c

@ -186,10 +186,7 @@ static int add(int argc, const char **argv)
url = argv[1]; url = argv[1];


remote = remote_get(name); remote = remote_get(name);
if (remote && (remote->url_nr > 1 || if (remote_is_configured(remote))
(strcmp(name, remote->url[0]) &&
strcmp(url, remote->url[0])) ||
remote->fetch_refspec_nr))
die(_("remote %s already exists."), name); die(_("remote %s already exists."), name);


strbuf_addf(&buf2, "refs/heads/test:refs/remotes/%s/test", name); strbuf_addf(&buf2, "refs/heads/test:refs/remotes/%s/test", name);
@ -634,14 +631,14 @@ static int mv(int argc, const char **argv)
rename.remote_branches = &remote_branches; rename.remote_branches = &remote_branches;


oldremote = remote_get(rename.old); oldremote = remote_get(rename.old);
if (!oldremote) if (!remote_is_configured(oldremote))
die(_("No such remote: %s"), rename.old); die(_("No such remote: %s"), rename.old);


if (!strcmp(rename.old, rename.new) && oldremote->origin != REMOTE_CONFIG) if (!strcmp(rename.old, rename.new) && oldremote->origin != REMOTE_CONFIG)
return migrate_file(oldremote); return migrate_file(oldremote);


newremote = remote_get(rename.new); newremote = remote_get(rename.new);
if (newremote && (newremote->url_nr > 1 || newremote->fetch_refspec_nr)) if (remote_is_configured(newremote))
die(_("remote %s already exists."), rename.new); die(_("remote %s already exists."), rename.new);


strbuf_addf(&buf, "refs/heads/test:refs/remotes/%s/test", rename.new); strbuf_addf(&buf, "refs/heads/test:refs/remotes/%s/test", rename.new);
@ -773,7 +770,7 @@ static int rm(int argc, const char **argv)
usage_with_options(builtin_remote_rm_usage, options); usage_with_options(builtin_remote_rm_usage, options);


remote = remote_get(argv[1]); remote = remote_get(argv[1]);
if (!remote) if (!remote_is_configured(remote))
die(_("No such remote: %s"), argv[1]); die(_("No such remote: %s"), argv[1]);


known_remotes.to_delete = remote; known_remotes.to_delete = remote;
@ -1441,9 +1438,9 @@ static int set_remote_branches(const char *remotename, const char **branches,


strbuf_addf(&key, "remote.%s.fetch", remotename); strbuf_addf(&key, "remote.%s.fetch", remotename);


if (!remote_is_configured(remotename))
die(_("No such remote '%s'"), remotename);
remote = remote_get(remotename); remote = remote_get(remotename);
if (!remote_is_configured(remote))
die(_("No such remote '%s'"), remotename);


if (!add_mode && remove_all_fetch_refspecs(remotename, key.buf)) { if (!add_mode && remove_all_fetch_refspecs(remotename, key.buf)) {
strbuf_release(&key); strbuf_release(&key);
@ -1498,9 +1495,9 @@ static int get_url(int argc, const char **argv)


remotename = argv[0]; remotename = argv[0];


if (!remote_is_configured(remotename))
die(_("No such remote '%s'"), remotename);
remote = remote_get(remotename); remote = remote_get(remotename);
if (!remote_is_configured(remote))
die(_("No such remote '%s'"), remotename);


url_nr = 0; url_nr = 0;
if (push_mode) { if (push_mode) {
@ -1566,9 +1563,9 @@ static int set_url(int argc, const char **argv)
if (delete_mode) if (delete_mode)
oldurl = newurl; oldurl = newurl;


if (!remote_is_configured(remotename))
die(_("No such remote '%s'"), remotename);
remote = remote_get(remotename); remote = remote_get(remotename);
if (!remote_is_configured(remote))
die(_("No such remote '%s'"), remotename);


if (push_mode) { if (push_mode) {
strbuf_addf(&name_buf, "remote.%s.pushurl", remotename); strbuf_addf(&name_buf, "remote.%s.pushurl", remotename);

82
remote.c

@ -318,93 +318,88 @@ static void read_branches_file(struct remote *remote)
static int handle_config(const char *key, const char *value, void *cb) static int handle_config(const char *key, const char *value, void *cb)
{ {
const char *name; const char *name;
int namelen;
const char *subkey; const char *subkey;
struct remote *remote; struct remote *remote;
struct branch *branch; struct branch *branch;
if (starts_with(key, "branch.")) { if (parse_config_key(key, "branch", &name, &namelen, &subkey) >= 0) {
name = key + 7; if (!name)
subkey = strrchr(name, '.');
if (!subkey)
return 0; return 0;
branch = make_branch(name, subkey - name); branch = make_branch(name, namelen);
if (!strcmp(subkey, ".remote")) { if (!strcmp(subkey, "remote")) {
return git_config_string(&branch->remote_name, key, value); return git_config_string(&branch->remote_name, key, value);
} else if (!strcmp(subkey, ".pushremote")) { } else if (!strcmp(subkey, "pushremote")) {
return git_config_string(&branch->pushremote_name, key, value); return git_config_string(&branch->pushremote_name, key, value);
} else if (!strcmp(subkey, ".merge")) { } else if (!strcmp(subkey, "merge")) {
if (!value) if (!value)
return config_error_nonbool(key); return config_error_nonbool(key);
add_merge(branch, xstrdup(value)); add_merge(branch, xstrdup(value));
} }
return 0; return 0;
} }
if (starts_with(key, "url.")) { if (parse_config_key(key, "url", &name, &namelen, &subkey) >= 0) {
struct rewrite *rewrite; struct rewrite *rewrite;
name = key + 4; if (!name)
subkey = strrchr(name, '.');
if (!subkey)
return 0; return 0;
if (!strcmp(subkey, ".insteadof")) { if (!strcmp(subkey, "insteadof")) {
rewrite = make_rewrite(&rewrites, name, subkey - name); rewrite = make_rewrite(&rewrites, name, namelen);
if (!value) if (!value)
return config_error_nonbool(key); return config_error_nonbool(key);
add_instead_of(rewrite, xstrdup(value)); add_instead_of(rewrite, xstrdup(value));
} else if (!strcmp(subkey, ".pushinsteadof")) { } else if (!strcmp(subkey, "pushinsteadof")) {
rewrite = make_rewrite(&rewrites_push, name, subkey - name); rewrite = make_rewrite(&rewrites_push, name, namelen);
if (!value) if (!value)
return config_error_nonbool(key); return config_error_nonbool(key);
add_instead_of(rewrite, xstrdup(value)); add_instead_of(rewrite, xstrdup(value));
} }
} }


if (!starts_with(key, "remote.")) if (parse_config_key(key, "remote", &name, &namelen, &subkey) < 0)
return 0; return 0;
name = key + 7;


/* Handle remote.* variables */ /* Handle remote.* variables */
if (!strcmp(name, "pushdefault")) if (!name && !strcmp(subkey, "pushdefault"))
return git_config_string(&pushremote_name, key, value); return git_config_string(&pushremote_name, key, value);


if (!name)
return 0;
/* Handle remote.<name>.* variables */ /* Handle remote.<name>.* variables */
if (*name == '/') { if (*name == '/') {
warning("Config remote shorthand cannot begin with '/': %s", warning("Config remote shorthand cannot begin with '/': %s",
name); name);
return 0; return 0;
} }
subkey = strrchr(name, '.'); remote = make_remote(name, namelen);
if (!subkey)
return 0;
remote = make_remote(name, subkey - name);
remote->origin = REMOTE_CONFIG; remote->origin = REMOTE_CONFIG;
if (!strcmp(subkey, ".mirror")) if (!strcmp(subkey, "mirror"))
remote->mirror = git_config_bool(key, value); remote->mirror = git_config_bool(key, value);
else if (!strcmp(subkey, ".skipdefaultupdate")) else if (!strcmp(subkey, "skipdefaultupdate"))
remote->skip_default_update = git_config_bool(key, value); remote->skip_default_update = git_config_bool(key, value);
else if (!strcmp(subkey, ".skipfetchall")) else if (!strcmp(subkey, "skipfetchall"))
remote->skip_default_update = git_config_bool(key, value); remote->skip_default_update = git_config_bool(key, value);
else if (!strcmp(subkey, ".prune")) else if (!strcmp(subkey, "prune"))
remote->prune = git_config_bool(key, value); remote->prune = git_config_bool(key, value);
else if (!strcmp(subkey, ".url")) { else if (!strcmp(subkey, "url")) {
const char *v; const char *v;
if (git_config_string(&v, key, value)) if (git_config_string(&v, key, value))
return -1; return -1;
add_url(remote, v); add_url(remote, v);
} else if (!strcmp(subkey, ".pushurl")) { } else if (!strcmp(subkey, "pushurl")) {
const char *v; const char *v;
if (git_config_string(&v, key, value)) if (git_config_string(&v, key, value))
return -1; return -1;
add_pushurl(remote, v); add_pushurl(remote, v);
} else if (!strcmp(subkey, ".push")) { } else if (!strcmp(subkey, "push")) {
const char *v; const char *v;
if (git_config_string(&v, key, value)) if (git_config_string(&v, key, value))
return -1; return -1;
add_push_refspec(remote, v); add_push_refspec(remote, v);
} else if (!strcmp(subkey, ".fetch")) { } else if (!strcmp(subkey, "fetch")) {
const char *v; const char *v;
if (git_config_string(&v, key, value)) if (git_config_string(&v, key, value))
return -1; return -1;
add_fetch_refspec(remote, v); add_fetch_refspec(remote, v);
} else if (!strcmp(subkey, ".receivepack")) { } else if (!strcmp(subkey, "receivepack")) {
const char *v; const char *v;
if (git_config_string(&v, key, value)) if (git_config_string(&v, key, value))
return -1; return -1;
@ -412,7 +407,7 @@ static int handle_config(const char *key, const char *value, void *cb)
remote->receivepack = v; remote->receivepack = v;
else else
error("more than one receivepack given, using the first"); error("more than one receivepack given, using the first");
} else if (!strcmp(subkey, ".uploadpack")) { } else if (!strcmp(subkey, "uploadpack")) {
const char *v; const char *v;
if (git_config_string(&v, key, value)) if (git_config_string(&v, key, value))
return -1; return -1;
@ -420,18 +415,18 @@ static int handle_config(const char *key, const char *value, void *cb)
remote->uploadpack = v; remote->uploadpack = v;
else else
error("more than one uploadpack given, using the first"); error("more than one uploadpack given, using the first");
} else if (!strcmp(subkey, ".tagopt")) { } else if (!strcmp(subkey, "tagopt")) {
if (!strcmp(value, "--no-tags")) if (!strcmp(value, "--no-tags"))
remote->fetch_tags = -1; remote->fetch_tags = -1;
else if (!strcmp(value, "--tags")) else if (!strcmp(value, "--tags"))
remote->fetch_tags = 2; remote->fetch_tags = 2;
} else if (!strcmp(subkey, ".proxy")) { } else if (!strcmp(subkey, "proxy")) {
return git_config_string((const char **)&remote->http_proxy, return git_config_string((const char **)&remote->http_proxy,
key, value); key, value);
} else if (!strcmp(subkey, ".proxyauthmethod")) { } else if (!strcmp(subkey, "proxyauthmethod")) {
return git_config_string((const char **)&remote->http_proxy_authmethod, return git_config_string((const char **)&remote->http_proxy_authmethod,
key, value); key, value);
} else if (!strcmp(subkey, ".vcs")) { } else if (!strcmp(subkey, "vcs")) {
return git_config_string(&remote->foreign_vcs, key, value); return git_config_string(&remote->foreign_vcs, key, value);
} }
return 0; return 0;
@ -718,18 +713,9 @@ struct remote *pushremote_get(const char *name)
return remote_get_1(name, pushremote_for_branch); return remote_get_1(name, pushremote_for_branch);
} }


int remote_is_configured(const char *name) int remote_is_configured(struct remote *remote)
{ {
struct remotes_hash_key lookup; return remote && remote->origin;
struct hashmap_entry lookup_entry;
read_config();

init_remotes_hash();
lookup.str = name;
lookup.len = strlen(name);
hashmap_entry_init(&lookup_entry, memhash(name, lookup.len));

return hashmap_get(&remotes_hash, &lookup_entry, &lookup) != NULL;
} }


int for_each_remote(each_remote_fn fn, void *priv) int for_each_remote(each_remote_fn fn, void *priv)

3
remote.h

@ -5,6 +5,7 @@
#include "hashmap.h" #include "hashmap.h"


enum { enum {
REMOTE_UNCONFIGURED = 0,
REMOTE_CONFIG, REMOTE_CONFIG,
REMOTE_REMOTES, REMOTE_REMOTES,
REMOTE_BRANCHES REMOTE_BRANCHES
@ -59,7 +60,7 @@ struct remote {


struct remote *remote_get(const char *name); struct remote *remote_get(const char *name);
struct remote *pushremote_get(const char *name); struct remote *pushremote_get(const char *name);
int remote_is_configured(const char *name); int remote_is_configured(struct remote *remote);


typedef int each_remote_fn(struct remote *remote, void *priv); typedef int each_remote_fn(struct remote *remote, void *priv);
int for_each_remote(each_remote_fn fn, void *priv); int for_each_remote(each_remote_fn fn, void *priv);

33
t/t5505-remote.sh

@ -144,6 +144,39 @@ test_expect_success 'remove remote protects local branches' '
) )
' '


test_expect_success 'remove errors out early when deleting non-existent branch' '
(
cd test &&
echo "fatal: No such remote: foo" >expect &&
test_must_fail git remote rm foo 2>actual &&
test_i18ncmp expect actual
)
'

test_expect_success 'rename errors out early when deleting non-existent branch' '
(
cd test &&
echo "fatal: No such remote: foo" >expect &&
test_must_fail git remote rename foo bar 2>actual &&
test_i18ncmp expect actual
)
'

test_expect_success 'add existing foreign_vcs remote' '
test_config remote.foo.vcs bar &&
echo "fatal: remote foo already exists." >expect &&
test_must_fail git remote add foo bar 2>actual &&
test_i18ncmp expect actual
'

test_expect_success 'add existing foreign_vcs remote' '
test_config remote.foo.vcs bar &&
test_config remote.bar.vcs bar &&
echo "fatal: remote bar already exists." >expect &&
test_must_fail git remote rename foo bar 2>actual &&
test_i18ncmp expect actual
'

cat >test/expect <<EOF cat >test/expect <<EOF
* remote origin * remote origin
Fetch URL: $(pwd)/one Fetch URL: $(pwd)/one

Loading…
Cancel
Save