Skip to content

Commit 4a88fb7

Browse files
committed
Merge branch 'jc/rerere'
* jc/rerere: Teach --[no-]rerere-autoupdate option to merge, revert and friends
2 parents 26b9f5c + cb6020b commit 4a88fb7

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
@@ -1255,7 +1255,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
12551255
"new_index file. Check that disk is not full or quota is\n"
12561256
"not exceeded, and then \"git reset HEAD\" to recover.");
12571257

1258-
rerere();
1258+
rerere(0);
12591259
run_hook(get_index_file(), "post-commit", NULL);
12601260
if (!quiet)
12611261
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
@@ -103,15 +103,24 @@ static int diff_two(const char *file1, const char *label1,
103103
int cmd_rerere(int argc, const char **argv, const char *prefix)
104104
{
105105
struct string_list merge_rr = { NULL, 0, 0, 1 };
106-
int i, fd;
107-
106+
int i, fd, flags = 0;
107+
108+
if (2 < argc) {
109+
if (!strcmp(argv[1], "-h"))
110+
usage(git_rerere_usage);
111+
if (!strcmp(argv[1], "--rerere-autoupdate"))
112+
flags = RERERE_AUTOUPDATE;
113+
else if (!strcmp(argv[1], "--no-rerere-autoupdate"))
114+
flags = RERERE_NOAUTOUPDATE;
115+
if (flags) {
116+
argc--;
117+
argv++;
118+
}
119+
}
108120
if (argc < 2)
109-
return rerere();
110-
111-
if (!strcmp(argv[1], "-h"))
112-
usage(git_rerere_usage);
121+
return rerere(flags);
113122

114-
fd = setup_rerere(&merge_rr);
123+
fd = setup_rerere(&merge_rr, flags);
115124
if (fd < 0)
116125
return 0;
117126

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
@@ -52,6 +52,7 @@ diffstat=$(git config --bool rebase.stat)
5252
git_am_opt=
5353
rebase_root=
5454
force_rebase=
55+
allow_rerere_autoupdate=
5556

5657
continue_merge () {
5758
test -n "$prev_head" || die "prev_head must be defined"
@@ -120,7 +121,7 @@ call_merge () {
120121
return
121122
;;
122123
1)
123-
git rerere
124+
git rerere $allow_rerere_autoupdate
124125
die "$RESOLVEMSG"
125126
;;
126127
2)
@@ -351,6 +352,9 @@ do
351352
-f|--f|--fo|--for|--forc|force|--force-r|--force-re|--force-reb|--force-reba|--force-rebas|--force-rebase)
352353
force_rebase=t
353354
;;
355+
--rerere-autoupdate|--no-rerere-autoupdate)
356+
allow_rerere_autoupdate="$1"
357+
;;
354358
-*)
355359
usage
356360
;;

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)