Browse Source

Merge branch 'js/remote-rename-with-half-configured-remote'

With anticipatory tweaking for remotes defined in ~/.gitconfig
(e.g. "remote.origin.prune" set to true, even though there may or
may not actually be "origin" remote defined in a particular Git
repository), "git remote rename" and other commands misinterpreted
and behaved as if such a non-existing remote actually existed.

* js/remote-rename-with-half-configured-remote:
  remote rename: more carefully determine whether a remote is configured
  remote rename: demonstrate a bogus "remote exists" bug
maint
Junio C Hamano 8 years ago
parent
commit
fe575f0653
  1. 2
      builtin/fetch.c
  2. 14
      builtin/remote.c
  3. 12
      remote.c
  4. 4
      remote.h
  5. 7
      t/t5505-remote.sh

2
builtin/fetch.c

@ -1177,7 +1177,7 @@ 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 = remote_get(name); struct remote *remote = remote_get(name);
if (!remote_is_configured(remote)) if (!remote_is_configured(remote, 0))
return 0; return 0;
string_list_append(list, remote->name); string_list_append(list, remote->name);
} }

14
builtin/remote.c

@ -186,7 +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_is_configured(remote)) if (remote_is_configured(remote, 1))
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);
@ -618,14 +618,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 (!remote_is_configured(oldremote)) if (!remote_is_configured(oldremote, 1))
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 (remote_is_configured(newremote)) if (remote_is_configured(newremote, 1))
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);
@ -753,7 +753,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_is_configured(remote)) if (!remote_is_configured(remote, 1))
die(_("No such remote: %s"), argv[1]); die(_("No such remote: %s"), argv[1]);


known_remotes.to_delete = remote; known_remotes.to_delete = remote;
@ -1415,7 +1415,7 @@ 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);


remote = remote_get(remotename); remote = remote_get(remotename);
if (!remote_is_configured(remote)) if (!remote_is_configured(remote, 1))
die(_("No such remote '%s'"), remotename); 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)) {
@ -1469,7 +1469,7 @@ static int get_url(int argc, const char **argv)
remotename = argv[0]; remotename = argv[0];


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


url_nr = 0; url_nr = 0;
@ -1537,7 +1537,7 @@ static int set_url(int argc, const char **argv)
oldurl = newurl; oldurl = newurl;


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


if (push_mode) { if (push_mode) {

12
remote.c

@ -255,6 +255,7 @@ static void read_remotes_file(struct remote *remote)


if (!f) if (!f)
return; return;
remote->configured_in_repo = 1;
remote->origin = REMOTE_REMOTES; remote->origin = REMOTE_REMOTES;
while (strbuf_getline(&buf, f) != EOF) { while (strbuf_getline(&buf, f) != EOF) {
const char *v; const char *v;
@ -289,6 +290,7 @@ static void read_branches_file(struct remote *remote)
return; return;
} }


remote->configured_in_repo = 1;
remote->origin = REMOTE_BRANCHES; remote->origin = REMOTE_BRANCHES;


/* /*
@ -371,6 +373,8 @@ static int handle_config(const char *key, const char *value, void *cb)
} }
remote = make_remote(name, namelen); remote = make_remote(name, namelen);
remote->origin = REMOTE_CONFIG; remote->origin = REMOTE_CONFIG;
if (current_config_scope() == CONFIG_SCOPE_REPO)
remote->configured_in_repo = 1;
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"))
@ -714,9 +718,13 @@ 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(struct remote *remote) int remote_is_configured(struct remote *remote, int in_repo)
{ {
return remote && remote->origin; if (!remote)
return 0;
if (in_repo)
return remote->configured_in_repo;
return !!remote->origin;
} }


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

4
remote.h

@ -15,7 +15,7 @@ struct remote {
struct hashmap_entry ent; /* must be first */ struct hashmap_entry ent; /* must be first */


const char *name; const char *name;
int origin; int origin, configured_in_repo;


const char *foreign_vcs; const char *foreign_vcs;


@ -60,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(struct remote *remote); int remote_is_configured(struct remote *remote, int in_repo);


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);

7
t/t5505-remote.sh

@ -764,6 +764,13 @@ test_expect_success 'rename a remote with name prefix of other remote' '
) )
' '


test_expect_success 'rename succeeds with existing remote.<target>.prune' '
git clone one four.four &&
test_when_finished git config --global --unset remote.upstream.prune &&
git config --global remote.upstream.prune true &&
git -C four.four remote rename origin upstream
'

cat >remotes_origin <<EOF cat >remotes_origin <<EOF
URL: $(pwd)/one URL: $(pwd)/one
Push: refs/heads/master:refs/heads/upstream Push: refs/heads/master:refs/heads/upstream

Loading…
Cancel
Save