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
This commit is contained in:
		@ -1177,7 +1177,7 @@ static int add_remote_or_group(const char *name, struct string_list *list)
 | 
			
		||||
	git_config(get_remote_group, &g);
 | 
			
		||||
	if (list->nr == prev_nr) {
 | 
			
		||||
		struct remote *remote = remote_get(name);
 | 
			
		||||
		if (!remote_is_configured(remote))
 | 
			
		||||
		if (!remote_is_configured(remote, 0))
 | 
			
		||||
			return 0;
 | 
			
		||||
		string_list_append(list, remote->name);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -186,7 +186,7 @@ static int add(int argc, const char **argv)
 | 
			
		||||
	url = argv[1];
 | 
			
		||||
 | 
			
		||||
	remote = remote_get(name);
 | 
			
		||||
	if (remote_is_configured(remote))
 | 
			
		||||
	if (remote_is_configured(remote, 1))
 | 
			
		||||
		die(_("remote %s already exists."), 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;
 | 
			
		||||
 | 
			
		||||
	oldremote = remote_get(rename.old);
 | 
			
		||||
	if (!remote_is_configured(oldremote))
 | 
			
		||||
	if (!remote_is_configured(oldremote, 1))
 | 
			
		||||
		die(_("No such remote: %s"), rename.old);
 | 
			
		||||
 | 
			
		||||
	if (!strcmp(rename.old, rename.new) && oldremote->origin != REMOTE_CONFIG)
 | 
			
		||||
		return migrate_file(oldremote);
 | 
			
		||||
 | 
			
		||||
	newremote = remote_get(rename.new);
 | 
			
		||||
	if (remote_is_configured(newremote))
 | 
			
		||||
	if (remote_is_configured(newremote, 1))
 | 
			
		||||
		die(_("remote %s already exists."), 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);
 | 
			
		||||
 | 
			
		||||
	remote = remote_get(argv[1]);
 | 
			
		||||
	if (!remote_is_configured(remote))
 | 
			
		||||
	if (!remote_is_configured(remote, 1))
 | 
			
		||||
		die(_("No such remote: %s"), argv[1]);
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
 | 
			
		||||
	remote = remote_get(remotename);
 | 
			
		||||
	if (!remote_is_configured(remote))
 | 
			
		||||
	if (!remote_is_configured(remote, 1))
 | 
			
		||||
		die(_("No such remote '%s'"), remotename);
 | 
			
		||||
 | 
			
		||||
	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];
 | 
			
		||||
 | 
			
		||||
	remote = remote_get(remotename);
 | 
			
		||||
	if (!remote_is_configured(remote))
 | 
			
		||||
	if (!remote_is_configured(remote, 1))
 | 
			
		||||
		die(_("No such remote '%s'"), remotename);
 | 
			
		||||
 | 
			
		||||
	url_nr = 0;
 | 
			
		||||
@ -1537,7 +1537,7 @@ static int set_url(int argc, const char **argv)
 | 
			
		||||
		oldurl = newurl;
 | 
			
		||||
 | 
			
		||||
	remote = remote_get(remotename);
 | 
			
		||||
	if (!remote_is_configured(remote))
 | 
			
		||||
	if (!remote_is_configured(remote, 1))
 | 
			
		||||
		die(_("No such remote '%s'"), remotename);
 | 
			
		||||
 | 
			
		||||
	if (push_mode) {
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										12
									
								
								remote.c
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								remote.c
									
									
									
									
									
								
							@ -255,6 +255,7 @@ static void read_remotes_file(struct remote *remote)
 | 
			
		||||
 | 
			
		||||
	if (!f)
 | 
			
		||||
		return;
 | 
			
		||||
	remote->configured_in_repo = 1;
 | 
			
		||||
	remote->origin = REMOTE_REMOTES;
 | 
			
		||||
	while (strbuf_getline(&buf, f) != EOF) {
 | 
			
		||||
		const char *v;
 | 
			
		||||
@ -289,6 +290,7 @@ static void read_branches_file(struct remote *remote)
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	remote->configured_in_repo = 1;
 | 
			
		||||
	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->origin = REMOTE_CONFIG;
 | 
			
		||||
	if (current_config_scope() == CONFIG_SCOPE_REPO)
 | 
			
		||||
		remote->configured_in_repo = 1;
 | 
			
		||||
	if (!strcmp(subkey, "mirror"))
 | 
			
		||||
		remote->mirror = git_config_bool(key, value);
 | 
			
		||||
	else if (!strcmp(subkey, "skipdefaultupdate"))
 | 
			
		||||
@ -714,9 +718,13 @@ struct remote *pushremote_get(const char *name)
 | 
			
		||||
	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)
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								remote.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								remote.h
									
									
									
									
									
								
							@ -15,7 +15,7 @@ struct remote {
 | 
			
		||||
	struct hashmap_entry ent;  /* must be first */
 | 
			
		||||
 | 
			
		||||
	const char *name;
 | 
			
		||||
	int origin;
 | 
			
		||||
	int origin, configured_in_repo;
 | 
			
		||||
 | 
			
		||||
	const char *foreign_vcs;
 | 
			
		||||
 | 
			
		||||
@ -60,7 +60,7 @@ struct remote {
 | 
			
		||||
 | 
			
		||||
struct remote *remote_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);
 | 
			
		||||
int for_each_remote(each_remote_fn fn, void *priv);
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
URL: $(pwd)/one
 | 
			
		||||
Push: refs/heads/master:refs/heads/upstream
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user