Skip to content

Commit 8e1c21c

Browse files
committed
Merge branch 'bw/remote-rename-update-config' into pu
"git remote rename X Y" needs to adjust configuration variables (e.g. branch.<name>.remote) whose value used to be X to Y. branch.<name>.pushRemote is now also updated. * bw/remote-rename-update-config: SQUASH??? test_config cannot be used inside a subshell remote rename/remove: gently handle remote.pushDefault config config: provide access to the current line number remote rename/remove: handle branch.<name>.pushRemote config values remote: clean-up config callback remote: clean-up by returning early to avoid one indentation pull --rebase/remote rename: document and honor single-letter abbreviations rebase types
2 parents 5806881 + 05a4287 commit 8e1c21c

File tree

12 files changed

+304
-90
lines changed

12 files changed

+304
-90
lines changed

Documentation/config/branch.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,16 @@ branch.<name>.rebase::
8181
"git pull" is run. See "pull.rebase" for doing this in a non
8282
branch-specific manner.
8383
+
84-
When `merges`, pass the `--rebase-merges` option to 'git rebase'
84+
When `merges` (or just 'm'), pass the `--rebase-merges` option to 'git rebase'
8585
so that the local merge commits are included in the rebase (see
8686
linkgit:git-rebase[1] for details).
8787
+
88-
When `preserve` (deprecated in favor of `merges`), also pass
88+
When `preserve` (or just 'p', deprecated in favor of `merges`), also pass
8989
`--preserve-merges` along to 'git rebase' so that locally committed merge
9090
commits will not be flattened by running 'git pull'.
9191
+
92-
When the value is `interactive`, the rebase is run in interactive mode.
92+
When the value is `interactive` (or just 'i'), the rebase is run in interactive
93+
mode.
9394
+
9495
*NOTE*: this is a possibly dangerous operation; do *not* use
9596
it unless you understand the implications (see linkgit:git-rebase[1]

Documentation/config/pull.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,16 @@ pull.rebase::
1414
pull" is run. See "branch.<name>.rebase" for setting this on a
1515
per-branch basis.
1616
+
17-
When `merges`, pass the `--rebase-merges` option to 'git rebase'
17+
When `merges` (or just 'm'), pass the `--rebase-merges` option to 'git rebase'
1818
so that the local merge commits are included in the rebase (see
1919
linkgit:git-rebase[1] for details).
2020
+
21-
When `preserve` (deprecated in favor of `merges`), also pass
21+
When `preserve` (or just 'p', deprecated in favor of `merges`), also pass
2222
`--preserve-merges` along to 'git rebase' so that locally committed merge
2323
commits will not be flattened by running 'git pull'.
2424
+
25-
When the value is `interactive`, the rebase is run in interactive mode.
25+
When the value is `interactive` (or just 'i'), the rebase is run in interactive
26+
mode.
2627
+
2728
*NOTE*: this is a possibly dangerous operation; do *not* use
2829
it unless you understand the implications (see linkgit:git-rebase[1]

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,7 @@ LIB_OBJS += quote.o
955955
LIB_OBJS += range-diff.o
956956
LIB_OBJS += reachable.o
957957
LIB_OBJS += read-cache.o
958+
LIB_OBJS += rebase.o
958959
LIB_OBJS += rebase-interactive.o
959960
LIB_OBJS += ref-filter.o
960961
LIB_OBJS += reflog-walk.o

builtin/pull.c

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "sha1-array.h"
1616
#include "remote.h"
1717
#include "dir.h"
18+
#include "rebase.h"
1819
#include "refs.h"
1920
#include "refspec.h"
2021
#include "revision.h"
@@ -26,15 +27,6 @@
2627
#include "commit-reach.h"
2728
#include "sequencer.h"
2829

29-
enum rebase_type {
30-
REBASE_INVALID = -1,
31-
REBASE_FALSE = 0,
32-
REBASE_TRUE,
33-
REBASE_PRESERVE,
34-
REBASE_MERGES,
35-
REBASE_INTERACTIVE
36-
};
37-
3830
/**
3931
* Parses the value of --rebase. If value is a false value, returns
4032
* REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is
@@ -45,22 +37,9 @@ enum rebase_type {
4537
static enum rebase_type parse_config_rebase(const char *key, const char *value,
4638
int fatal)
4739
{
48-
int v = git_parse_maybe_bool(value);
49-
50-
if (!v)
51-
return REBASE_FALSE;
52-
else if (v > 0)
53-
return REBASE_TRUE;
54-
else if (!strcmp(value, "preserve") || !strcmp(value, "p"))
55-
return REBASE_PRESERVE;
56-
else if (!strcmp(value, "merges") || !strcmp(value, "m"))
57-
return REBASE_MERGES;
58-
else if (!strcmp(value, "interactive") || !strcmp(value, "i"))
59-
return REBASE_INTERACTIVE;
60-
/*
61-
* Please update _git_config() in git-completion.bash when you
62-
* add new rebase modes.
63-
*/
40+
enum rebase_type v = rebase_parse_value(value);
41+
if (v != REBASE_INVALID)
42+
return v;
6443

6544
if (fatal)
6645
die(_("Invalid value for %s: %s"), key, value);

builtin/remote.c

Lines changed: 132 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "string-list.h"
77
#include "strbuf.h"
88
#include "run-command.h"
9+
#include "rebase.h"
910
#include "refs.h"
1011
#include "refspec.h"
1112
#include "object-store.h"
@@ -248,9 +249,8 @@ static int add(int argc, const char **argv)
248249
struct branch_info {
249250
char *remote_name;
250251
struct string_list merge;
251-
enum {
252-
NO_REBASE, NORMAL_REBASE, INTERACTIVE_REBASE, REBASE_MERGES
253-
} rebase;
252+
enum rebase_type rebase;
253+
char *push_remote_name;
254254
};
255255

256256
static struct string_list branch_list = STRING_LIST_INIT_NODUP;
@@ -264,59 +264,69 @@ static const char *abbrev_ref(const char *name, const char *prefix)
264264

265265
static int config_read_branches(const char *key, const char *value, void *cb)
266266
{
267-
if (starts_with(key, "branch.")) {
268-
const char *orig_key = key;
269-
char *name;
270-
struct string_list_item *item;
271-
struct branch_info *info;
272-
enum { REMOTE, MERGE, REBASE } type;
273-
size_t key_len;
274-
275-
key += 7;
276-
if (strip_suffix(key, ".remote", &key_len)) {
277-
name = xmemdupz(key, key_len);
278-
type = REMOTE;
279-
} else if (strip_suffix(key, ".merge", &key_len)) {
280-
name = xmemdupz(key, key_len);
281-
type = MERGE;
282-
} else if (strip_suffix(key, ".rebase", &key_len)) {
283-
name = xmemdupz(key, key_len);
284-
type = REBASE;
285-
} else
286-
return 0;
267+
const char *orig_key = key;
268+
char *name;
269+
struct string_list_item *item;
270+
struct branch_info *info;
271+
enum { REMOTE, MERGE, REBASE, PUSH_REMOTE } type;
272+
size_t key_len;
287273

288-
item = string_list_insert(&branch_list, name);
274+
if (!starts_with(key, "branch."))
275+
return 0;
289276

290-
if (!item->util)
291-
item->util = xcalloc(1, sizeof(struct branch_info));
292-
info = item->util;
293-
if (type == REMOTE) {
294-
if (info->remote_name)
295-
warning(_("more than one %s"), orig_key);
296-
info->remote_name = xstrdup(value);
297-
} else if (type == MERGE) {
298-
char *space = strchr(value, ' ');
299-
value = abbrev_branch(value);
300-
while (space) {
301-
char *merge;
302-
merge = xstrndup(value, space - value);
303-
string_list_append(&info->merge, merge);
304-
value = abbrev_branch(space + 1);
305-
space = strchr(value, ' ');
306-
}
307-
string_list_append(&info->merge, xstrdup(value));
308-
} else {
309-
int v = git_parse_maybe_bool(value);
310-
if (v >= 0)
311-
info->rebase = v;
312-
else if (!strcmp(value, "preserve"))
313-
info->rebase = NORMAL_REBASE;
314-
else if (!strcmp(value, "merges"))
315-
info->rebase = REBASE_MERGES;
316-
else if (!strcmp(value, "interactive"))
317-
info->rebase = INTERACTIVE_REBASE;
277+
key += strlen("branch.");
278+
if (strip_suffix(key, ".remote", &key_len))
279+
type = REMOTE;
280+
else if (strip_suffix(key, ".merge", &key_len))
281+
type = MERGE;
282+
else if (strip_suffix(key, ".rebase", &key_len))
283+
type = REBASE;
284+
else if (strip_suffix(key, ".pushremote", &key_len))
285+
type = PUSH_REMOTE;
286+
else
287+
return 0;
288+
name = xmemdupz(key, key_len);
289+
290+
item = string_list_insert(&branch_list, name);
291+
292+
if (!item->util)
293+
item->util = xcalloc(1, sizeof(struct branch_info));
294+
info = item->util;
295+
switch (type) {
296+
case REMOTE:
297+
if (info->remote_name)
298+
warning(_("more than one %s"), orig_key);
299+
info->remote_name = xstrdup(value);
300+
break;
301+
case MERGE: {
302+
char *space = strchr(value, ' ');
303+
value = abbrev_branch(value);
304+
while (space) {
305+
char *merge;
306+
merge = xstrndup(value, space - value);
307+
string_list_append(&info->merge, merge);
308+
value = abbrev_branch(space + 1);
309+
space = strchr(value, ' ');
318310
}
311+
string_list_append(&info->merge, xstrdup(value));
312+
break;
313+
}
314+
case REBASE:
315+
/*
316+
* Consider invalid values as false and check the
317+
* truth value with >= REBASE_TRUE.
318+
*/
319+
info->rebase = rebase_parse_value(value);
320+
break;
321+
case PUSH_REMOTE:
322+
if (info->push_remote_name)
323+
warning(_("more than one %s"), orig_key);
324+
info->push_remote_name = xstrdup(value);
325+
break;
326+
default:
327+
BUG("unexpected type=%d", type);
319328
}
329+
320330
return 0;
321331
}
322332

@@ -605,6 +615,55 @@ static int migrate_file(struct remote *remote)
605615
return 0;
606616
}
607617

618+
struct push_default_info
619+
{
620+
const char *old_name;
621+
enum config_scope scope;
622+
struct strbuf origin;
623+
int linenr;
624+
};
625+
626+
static int config_read_push_default(const char *key, const char *value,
627+
void *cb)
628+
{
629+
struct push_default_info* info = cb;
630+
if (strcmp(key, "remote.pushdefault") || strcmp(value, info->old_name))
631+
return 0;
632+
633+
info->scope = current_config_scope();
634+
strbuf_reset(&info->origin);
635+
strbuf_addstr(&info->origin, current_config_name());
636+
info->linenr = current_config_line();
637+
638+
return 0;
639+
}
640+
641+
static void handle_push_default(const char* old_name, const char* new_name)
642+
{
643+
struct push_default_info push_default = {
644+
old_name, CONFIG_SCOPE_UNKNOWN, STRBUF_INIT, -1 };
645+
git_config(config_read_push_default, &push_default);
646+
if (push_default.scope >= CONFIG_SCOPE_COMMAND)
647+
; /* pass */
648+
else if (push_default.scope >= CONFIG_SCOPE_LOCAL) {
649+
int result = git_config_set_gently("remote.pushDefault",
650+
new_name);
651+
if (new_name && result && result != CONFIG_NOTHING_SET)
652+
die(_("could not set '%s'"), "remote.pushDefault");
653+
else if (!new_name && result && result != CONFIG_NOTHING_SET)
654+
die(_("could not unset '%s'"), "remote.pushDefault");
655+
} else if (push_default.scope >= CONFIG_SCOPE_SYSTEM) {
656+
/* warn */
657+
warning(_("The %s configuration remote.pushDefault in:\n"
658+
"\t%s:%d\n"
659+
"now names the non-existent remote '%s'"),
660+
config_scope_name(push_default.scope),
661+
push_default.origin.buf, push_default.linenr,
662+
old_name);
663+
}
664+
}
665+
666+
608667
static int mv(int argc, const char **argv)
609668
{
610669
struct option options[] = {
@@ -680,6 +739,11 @@ static int mv(int argc, const char **argv)
680739
strbuf_addf(&buf, "branch.%s.remote", item->string);
681740
git_config_set(buf.buf, rename.new_name);
682741
}
742+
if (info->push_remote_name && !strcmp(info->push_remote_name, rename.old_name)) {
743+
strbuf_reset(&buf);
744+
strbuf_addf(&buf, "branch.%s.pushremote", item->string);
745+
git_config_set(buf.buf, rename.new_name);
746+
}
683747
}
684748

685749
if (!refspec_updated)
@@ -735,6 +799,9 @@ static int mv(int argc, const char **argv)
735799
die(_("creating '%s' failed"), buf.buf);
736800
}
737801
string_list_clear(&remote_branches, 1);
802+
803+
handle_push_default(rename.old_name, rename.new_name);
804+
738805
return 0;
739806
}
740807

@@ -781,6 +848,13 @@ static int rm(int argc, const char **argv)
781848
die(_("could not unset '%s'"), buf.buf);
782849
}
783850
}
851+
if (info->push_remote_name && !strcmp(info->push_remote_name, remote->name)) {
852+
strbuf_reset(&buf);
853+
strbuf_addf(&buf, "branch.%s.pushremote", item->string);
854+
result = git_config_set_gently(buf.buf, NULL);
855+
if (result && result != CONFIG_NOTHING_SET)
856+
die(_("could not unset '%s'"), buf.buf);
857+
}
784858
}
785859

786860
/*
@@ -813,6 +887,8 @@ static int rm(int argc, const char **argv)
813887
strbuf_addf(&buf, "remote.%s", remote->name);
814888
if (git_config_rename_section(buf.buf, NULL) < 1)
815889
return error(_("Could not remove config section '%s'"), buf.buf);
890+
891+
handle_push_default(remote->name, NULL);
816892
}
817893

818894
return result;
@@ -943,7 +1019,7 @@ static int add_local_to_show_info(struct string_list_item *branch_item, void *cb
9431019
return 0;
9441020
if ((n = strlen(branch_item->string)) > show_info->width)
9451021
show_info->width = n;
946-
if (branch_info->rebase)
1022+
if (branch_info->rebase >= REBASE_TRUE)
9471023
show_info->any_rebase = 1;
9481024

9491025
item = string_list_insert(show_info->list, branch_item->string);
@@ -960,16 +1036,16 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data)
9601036
int width = show_info->width + 4;
9611037
int i;
9621038

963-
if (branch_info->rebase && branch_info->merge.nr > 1) {
1039+
if (branch_info->rebase >= REBASE_TRUE && branch_info->merge.nr > 1) {
9641040
error(_("invalid branch.%s.merge; cannot rebase onto > 1 branch"),
9651041
item->string);
9661042
return 0;
9671043
}
9681044

9691045
printf(" %-*s ", show_info->width, item->string);
970-
if (branch_info->rebase) {
1046+
if (branch_info->rebase >= REBASE_TRUE) {
9711047
const char *msg;
972-
if (branch_info->rebase == INTERACTIVE_REBASE)
1048+
if (branch_info->rebase == REBASE_INTERACTIVE)
9731049
msg = _("rebases interactively onto remote %s");
9741050
else if (branch_info->rebase == REBASE_MERGES)
9751051
msg = _("rebases interactively (with merges) onto "

config.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3343,6 +3343,14 @@ enum config_scope current_config_scope(void)
33433343
return current_parsing_scope;
33443344
}
33453345

3346+
int current_config_line(void)
3347+
{
3348+
if (current_config_kvi)
3349+
return current_config_kvi->linenr;
3350+
else
3351+
return cf->linenr;
3352+
}
3353+
33463354
int lookup_config(const char **mapping, int nr_mapping, const char *var)
33473355
{
33483356
int i;

config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ int git_config_parse_parameter(const char *, config_fn_t fn, void *data);
315315
enum config_scope current_config_scope(void);
316316
const char *current_config_origin_type(void);
317317
const char *current_config_name(void);
318+
int current_config_line(void);
318319

319320
/**
320321
* Include Directives

0 commit comments

Comments
 (0)