Skip to content

Commit cb6020b

Browse files
committed
Teach --[no-]rerere-autoupdate option to merge, revert and friends
Introduce a command line option to override rerere.autoupdate configuration variable to make it more useful. Signed-off-by: Junio C Hamano <[email protected]>
1 parent 1a56be1 commit cb6020b

File tree

12 files changed

+77
-18
lines changed

12 files changed

+77
-18
lines changed

Documentation/git-merge.txt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ SYNOPSIS
1010
--------
1111
[verse]
1212
'git merge' [-n] [--stat] [--no-commit] [--squash] [-s <strategy>]...
13-
[-m <msg>] <remote>...
13+
[--[no-]rerere-autoupdate] [-m <msg>] <remote>...
1414
'git merge' <msg> HEAD <remote>...
1515

1616
DESCRIPTION
@@ -33,6 +33,11 @@ include::merge-options.txt[]
3333
used to give a good default for automated 'git merge'
3434
invocations.
3535

36+
--rerere-autoupdate::
37+
--no-rerere-autoupdate::
38+
Allow the rerere mechanism to update the index with the
39+
result of auto-conflict resolution if possible.
40+
3641
<remote>...::
3742
Other branch heads to merge into our branch. You need at
3843
least one <remote>. Specifying more than one <remote>

builtin-commit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1150,7 +1150,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
11501150
"new_index file. Check that disk is not full or quota is\n"
11511151
"not exceeded, and then \"git reset HEAD\" to recover.");
11521152

1153-
rerere();
1153+
rerere(0);
11541154
run_hook(get_index_file(), "post-commit", NULL);
11551155
if (!quiet)
11561156
print_summary(prefix, commit_sha1);

builtin-merge.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ static struct strategy **use_strategies;
5252
static size_t use_strategies_nr, use_strategies_alloc;
5353
static const char *branch;
5454
static int verbosity;
55+
static int allow_rerere_auto;
5556

5657
static struct strategy all_strategy[] = {
5758
{ "recursive", DEFAULT_TWOHEAD | NO_TRIVIAL },
@@ -170,6 +171,7 @@ static struct option builtin_merge_options[] = {
170171
"allow fast-forward (default)"),
171172
OPT_BOOLEAN(0, "ff-only", &fast_forward_only,
172173
"abort if fast-forward is not possible"),
174+
OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
173175
OPT_CALLBACK('s', "strategy", &use_strategies, "strategy",
174176
"merge strategy to use", option_parse_strategy),
175177
OPT_CALLBACK('m', "message", &merge_msg, "message",
@@ -790,7 +792,7 @@ static int suggest_conflicts(void)
790792
}
791793
}
792794
fclose(fp);
793-
rerere();
795+
rerere(allow_rerere_auto);
794796
printf("Automatic merge failed; "
795797
"fix conflicts and then commit the result.\n");
796798
return 1;

builtin-rerere.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,15 +101,24 @@ static int diff_two(const char *file1, const char *label1,
101101
int cmd_rerere(int argc, const char **argv, const char *prefix)
102102
{
103103
struct string_list merge_rr = { NULL, 0, 0, 1 };
104-
int i, fd;
105-
104+
int i, fd, flags = 0;
105+
106+
if (2 < argc) {
107+
if (!strcmp(argv[1], "-h"))
108+
usage(git_rerere_usage);
109+
if (!strcmp(argv[1], "--rerere-autoupdate"))
110+
flags = RERERE_AUTOUPDATE;
111+
else if (!strcmp(argv[1], "--no-rerere-autoupdate"))
112+
flags = RERERE_NOAUTOUPDATE;
113+
if (flags) {
114+
argc--;
115+
argv++;
116+
}
117+
}
106118
if (argc < 2)
107-
return rerere();
108-
109-
if (!strcmp(argv[1], "-h"))
110-
usage(git_rerere_usage);
119+
return rerere(flags);
111120

112-
fd = setup_rerere(&merge_rr);
121+
fd = setup_rerere(&merge_rr, flags);
113122
if (fd < 0)
114123
return 0;
115124

builtin-revert.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ static const char * const cherry_pick_usage[] = {
3838
static int edit, no_replay, no_commit, mainline, signoff;
3939
static enum { REVERT, CHERRY_PICK } action;
4040
static struct commit *commit;
41+
static int allow_rerere_auto;
4142

4243
static const char *me;
4344

@@ -57,6 +58,7 @@ static void parse_args(int argc, const char **argv)
5758
OPT_BOOLEAN('r', NULL, &noop, "no-op (backward compatibility)"),
5859
OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
5960
OPT_INTEGER('m', "mainline", &mainline, "parent number"),
61+
OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
6062
OPT_END(),
6163
};
6264

@@ -395,7 +397,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)
395397
die ("Error wrapping up %s", defmsg);
396398
fprintf(stderr, "Automatic %s failed.%s\n",
397399
me, help_msg(commit->object.sha1));
398-
rerere();
400+
rerere(allow_rerere_auto);
399401
exit(1);
400402
}
401403
if (commit_lock_file(&msg_file) < 0)

git-am.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ skip skip the current patch
3030
abort restore the original branch and abort the patching operation.
3131
committer-date-is-author-date lie about committer date
3232
ignore-date use current timestamp for author date
33+
rerere-autoupdate update the index with reused conflict resolution if possible
3334
rebasing* (internal use for git-rebase)"
3435

3536
. git-sh-setup
@@ -135,7 +136,7 @@ It does not apply to blobs recorded in its index."
135136
export GIT_MERGE_VERBOSITY=0
136137
fi
137138
git-merge-recursive $orig_tree -- HEAD $his_tree || {
138-
git rerere
139+
git rerere $allow_rerere_autoupdate
139140
echo Failed to merge in the changes.
140141
exit 1
141142
}
@@ -293,6 +294,7 @@ resolvemsg= resume= scissors= no_inbody_headers=
293294
git_apply_opt=
294295
committer_date_is_author_date=
295296
ignore_date=
297+
allow_rerere_autoupdate=
296298

297299
while test $# != 0
298300
do
@@ -340,6 +342,8 @@ do
340342
committer_date_is_author_date=t ;;
341343
--ignore-date)
342344
ignore_date=t ;;
345+
--rerere-autoupdate|--no-rerere-autoupdate)
346+
allow_rerere_autoupdate="$1" ;;
343347
-q|--quiet)
344348
GIT_QUIET=t ;;
345349
--)

git-rebase.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ diffstat=$(git config --bool rebase.stat)
5050
git_am_opt=
5151
rebase_root=
5252
force_rebase=
53+
allow_rerere_autoupdate=
5354

5455
continue_merge () {
5556
test -n "$prev_head" || die "prev_head must be defined"
@@ -118,7 +119,7 @@ call_merge () {
118119
return
119120
;;
120121
1)
121-
git rerere
122+
git rerere $allow_rerere_autoupdate
122123
die "$RESOLVEMSG"
123124
;;
124125
2)
@@ -349,6 +350,9 @@ do
349350
-f|--f|--fo|--for|--forc|force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase)
350351
force_rebase=t
351352
;;
353+
--rerere-autoupdate|--no-rerere-autoupdate)
354+
allow_rerere_autoupdate="$1"
355+
;;
352356
-*)
353357
usage
354358
;;

parse-options.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,3 +633,10 @@ int parse_opt_with_commit(const struct option *opt, const char *arg, int unset)
633633
commit_list_insert(commit, opt->value);
634634
return 0;
635635
}
636+
637+
int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)
638+
{
639+
int *target = opt->value;
640+
*target = unset ? 2 : 1;
641+
return 0;
642+
}

parse-options.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ struct option {
123123
(h), PARSE_OPT_NOARG, NULL, (p) }
124124
#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), "n", (h) }
125125
#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) }
126+
#define OPT_UYN(s, l, v, h) { OPTION_CALLBACK, (s), (l), (v), NULL, \
127+
(h), PARSE_OPT_NOARG, &parse_opt_tertiary }
126128
#define OPT_DATE(s, l, v, h) \
127129
{ OPTION_CALLBACK, (s), (l), (v), "time",(h), 0, \
128130
parse_opt_approxidate_cb }
@@ -190,6 +192,7 @@ extern int parse_opt_abbrev_cb(const struct option *, const char *, int);
190192
extern int parse_opt_approxidate_cb(const struct option *, const char *, int);
191193
extern int parse_opt_verbosity_cb(const struct option *, const char *, int);
192194
extern int parse_opt_with_commit(const struct option *, const char *, int);
195+
extern int parse_opt_tertiary(const struct option *, const char *, int);
193196

194197
#define OPT__VERBOSE(var) OPT_BOOLEAN('v', "verbose", (var), "be verbose")
195198
#define OPT__QUIET(var) OPT_BOOLEAN('q', "quiet", (var), "be quiet")

rerere.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,27 +367,29 @@ static int is_rerere_enabled(void)
367367
return 1;
368368
}
369369

370-
int setup_rerere(struct string_list *merge_rr)
370+
int setup_rerere(struct string_list *merge_rr, int flags)
371371
{
372372
int fd;
373373

374374
git_config(git_rerere_config, NULL);
375375
if (!is_rerere_enabled())
376376
return -1;
377377

378+
if (flags & (RERERE_AUTOUPDATE|RERERE_NOAUTOUPDATE))
379+
rerere_autoupdate = !!(flags & RERERE_AUTOUPDATE);
378380
merge_rr_path = git_pathdup("MERGE_RR");
379381
fd = hold_lock_file_for_update(&write_lock, merge_rr_path,
380382
LOCK_DIE_ON_ERROR);
381383
read_rr(merge_rr);
382384
return fd;
383385
}
384386

385-
int rerere(void)
387+
int rerere(int flags)
386388
{
387389
struct string_list merge_rr = { NULL, 0, 0, 1 };
388390
int fd;
389391

390-
fd = setup_rerere(&merge_rr);
392+
fd = setup_rerere(&merge_rr, flags);
391393
if (fd < 0)
392394
return 0;
393395
return do_plain_rerere(&merge_rr, fd);

0 commit comments

Comments
 (0)