Skip to content

Commit da66b27

Browse files
peffgitster
authored andcommitted
remote.c: provide per-branch pushremote name
When remote.c loads its config, it records the branch.*.pushremote for the current branch along with the global remote.pushDefault value, and then binds them into a single value: the default push for the current branch. We then pass this value (which may be NULL) to remote_get_1 when looking up a remote for push. This has a few downsides: 1. It's confusing. The early-binding of the "current value" led to bugs like the one fixed by 98b406f (remote: handle pushremote config in any order, 2014-02-24). And the fact that pushremotes fall back to ordinary remotes is not explicit at all; it happens because remote_get_1 cannot tell the difference between "we are not asking for the push remote" and "there is no push remote configured". 2. It throws away intermediate data. After read_config() finishes, we have no idea what the value of remote.pushDefault was, because the string has been overwritten by the current branch's branch.*.pushremote. 3. It doesn't record other data. We don't note the branch.*.pushremote value for anything but the current branch. Let's make this more like the fetch-remote config. We'll record the pushremote for each branch, and then explicitly compute the correct remote for the current branch at the time of reading. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f052154 commit da66b27

File tree

2 files changed

+24
-18
lines changed

2 files changed

+24
-18
lines changed

remote.c

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ static int branches_alloc;
4949
static int branches_nr;
5050

5151
static struct branch *current_branch;
52-
static const char *branch_pushremote_name;
5352
static const char *pushremote_name;
5453

5554
static struct rewrites rewrites;
@@ -367,9 +366,7 @@ static int handle_config(const char *key, const char *value, void *cb)
367366
if (!strcmp(subkey, ".remote")) {
368367
return git_config_string(&branch->remote_name, key, value);
369368
} else if (!strcmp(subkey, ".pushremote")) {
370-
if (branch == current_branch)
371-
if (git_config_string(&branch_pushremote_name, key, value))
372-
return -1;
369+
return git_config_string(&branch->pushremote_name, key, value);
373370
} else if (!strcmp(subkey, ".merge")) {
374371
if (!value)
375372
return config_error_nonbool(key);
@@ -510,10 +507,6 @@ static void read_config(void)
510507
current_branch = make_branch(head_ref, 0);
511508
}
512509
git_config(handle_config, NULL);
513-
if (branch_pushremote_name) {
514-
free((char *)pushremote_name);
515-
pushremote_name = branch_pushremote_name;
516-
}
517510
alias_all_urls();
518511
}
519512

@@ -704,20 +697,31 @@ const char *remote_for_branch(struct branch *branch, int *explicit)
704697
return "origin";
705698
}
706699

707-
static struct remote *remote_get_1(const char *name, const char *pushremote_name)
700+
const char *pushremote_for_branch(struct branch *branch, int *explicit)
701+
{
702+
if (branch && branch->pushremote_name) {
703+
if (explicit)
704+
*explicit = 1;
705+
return branch->pushremote_name;
706+
}
707+
if (pushremote_name) {
708+
if (explicit)
709+
*explicit = 1;
710+
return pushremote_name;
711+
}
712+
return remote_for_branch(branch, explicit);
713+
}
714+
715+
static struct remote *remote_get_1(const char *name,
716+
const char *(*get_default)(struct branch *, int *))
708717
{
709718
struct remote *ret;
710719
int name_given = 0;
711720

712721
if (name)
713722
name_given = 1;
714-
else {
715-
if (pushremote_name) {
716-
name = pushremote_name;
717-
name_given = 1;
718-
} else
719-
name = remote_for_branch(current_branch, &name_given);
720-
}
723+
else
724+
name = get_default(current_branch, &name_given);
721725

722726
ret = make_remote(name, 0);
723727
if (valid_remote_nick(name)) {
@@ -738,13 +742,13 @@ static struct remote *remote_get_1(const char *name, const char *pushremote_name
738742
struct remote *remote_get(const char *name)
739743
{
740744
read_config();
741-
return remote_get_1(name, NULL);
745+
return remote_get_1(name, remote_for_branch);
742746
}
743747

744748
struct remote *pushremote_get(const char *name)
745749
{
746750
read_config();
747-
return remote_get_1(name, pushremote_name);
751+
return remote_get_1(name, pushremote_for_branch);
748752
}
749753

750754
int remote_is_configured(const char *name)

remote.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ struct branch {
203203
const char *refname;
204204

205205
const char *remote_name;
206+
const char *pushremote_name;
206207

207208
const char **merge_name;
208209
struct refspec **merge;
@@ -212,6 +213,7 @@ struct branch {
212213

213214
struct branch *branch_get(const char *name);
214215
const char *remote_for_branch(struct branch *branch, int *explicit);
216+
const char *pushremote_for_branch(struct branch *branch, int *explicit);
215217

216218
int branch_has_merge_config(struct branch *branch);
217219
int branch_merge_matches(struct branch *, int n, const char *);

0 commit comments

Comments
 (0)