Skip to content

Commit ae76cb9

Browse files
committed
Merge branch 'jn/cherry-revert-message-clean-up'
* jn/cherry-revert-message-clean-up: tests: fix syntax error in "Use advise() for hints" test cherry-pick/revert: Use advise() for hints cherry-pick/revert: Use error() for failure message Introduce advise() to print hints Eliminate “Finished cherry-pick/revert” message t3508: add check_head_differs_from() helper function and use it revert: improve success message by adding abbreviated commit sha1 revert: don't print "Finished one cherry-pick." if commit failed revert: refactor commit code into a new run_git_commit() function revert: report success when using option --strategy
2 parents 7cc1e38 + 997b688 commit ae76cb9

6 files changed

Lines changed: 152 additions & 84 deletions

File tree

Documentation/howto/revert-branch-rebase.txt

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,25 +112,19 @@ $ git tag pu-anchor pu
112112
$ git rebase master
113113
* Applying: Redo "revert" using three-way merge machinery.
114114
First trying simple merge strategy to cherry-pick.
115-
Finished one cherry-pick.
116115
* Applying: Remove git-apply-patch-script.
117116
First trying simple merge strategy to cherry-pick.
118117
Simple cherry-pick fails; trying Automatic cherry-pick.
119118
Removing Documentation/git-apply-patch-script.txt
120119
Removing git-apply-patch-script
121-
Finished one cherry-pick.
122120
* Applying: Document "git cherry-pick" and "git revert"
123121
First trying simple merge strategy to cherry-pick.
124-
Finished one cherry-pick.
125122
* Applying: mailinfo and applymbox updates
126123
First trying simple merge strategy to cherry-pick.
127-
Finished one cherry-pick.
128124
* Applying: Show commits in topo order and name all commits.
129125
First trying simple merge strategy to cherry-pick.
130-
Finished one cherry-pick.
131126
* Applying: More documentation updates.
132127
First trying simple merge strategy to cherry-pick.
133-
Finished one cherry-pick.
134128
------------------------------------------------
135129

136130
The temporary tag 'pu-anchor' is me just being careful, in case 'git

builtin/revert.c

Lines changed: 70 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -231,27 +231,30 @@ static void set_author_ident_env(const char *message)
231231
sha1_to_hex(commit->object.sha1));
232232
}
233233

234-
static char *help_msg(void)
234+
static void advise(const char *advice, ...)
235235
{
236-
struct strbuf helpbuf = STRBUF_INIT;
237-
char *msg = getenv("GIT_CHERRY_PICK_HELP");
236+
va_list params;
238237

239-
if (msg)
240-
return msg;
238+
va_start(params, advice);
239+
vreportf("hint: ", advice, params);
240+
va_end(params);
241+
}
241242

242-
strbuf_addstr(&helpbuf, " After resolving the conflicts,\n"
243-
"mark the corrected paths with 'git add <paths>' or 'git rm <paths>'\n"
244-
"and commit the result");
243+
static void print_advice(void)
244+
{
245+
char *msg = getenv("GIT_CHERRY_PICK_HELP");
245246

246-
if (action == CHERRY_PICK) {
247-
strbuf_addf(&helpbuf, " with: \n"
248-
"\n"
249-
" git commit -c %s\n",
250-
sha1_to_hex(commit->object.sha1));
247+
if (msg) {
248+
fprintf(stderr, "%s\n", msg);
249+
return;
251250
}
252-
else
253-
strbuf_addch(&helpbuf, '.');
254-
return strbuf_detach(&helpbuf, NULL);
251+
252+
advise("after resolving the conflicts, mark the corrected paths");
253+
advise("with 'git add <paths>' or 'git rm <paths>'");
254+
255+
if (action == CHERRY_PICK)
256+
advise("and commit the result with 'git commit -c %s'",
257+
find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV));
255258
}
256259

257260
static void write_message(struct strbuf *msgbuf, const char *filename)
@@ -301,10 +304,9 @@ static int fast_forward_to(const unsigned char *to, const unsigned char *from)
301304
return write_ref_sha1(ref_lock, to, "cherry-pick");
302305
}
303306

304-
static void do_recursive_merge(struct commit *base, struct commit *next,
305-
const char *base_label, const char *next_label,
306-
unsigned char *head, struct strbuf *msgbuf,
307-
char *defmsg)
307+
static int do_recursive_merge(struct commit *base, struct commit *next,
308+
const char *base_label, const char *next_label,
309+
unsigned char *head, struct strbuf *msgbuf)
308310
{
309311
struct merge_options o;
310312
struct tree *result, *next_tree, *base_tree, *head_tree;
@@ -347,14 +349,35 @@ static void do_recursive_merge(struct commit *base, struct commit *next,
347349
i++;
348350
}
349351
}
350-
write_message(msgbuf, defmsg);
351-
fprintf(stderr, "Automatic %s failed.%s\n",
352-
me, help_msg());
353-
rerere(allow_rerere_auto);
354-
exit(1);
355352
}
356-
write_message(msgbuf, defmsg);
357-
fprintf(stderr, "Finished one %s.\n", me);
353+
354+
return !clean;
355+
}
356+
357+
/*
358+
* If we are cherry-pick, and if the merge did not result in
359+
* hand-editing, we will hit this commit and inherit the original
360+
* author date and name.
361+
* If we are revert, or if our cherry-pick results in a hand merge,
362+
* we had better say that the current user is responsible for that.
363+
*/
364+
static int run_git_commit(const char *defmsg)
365+
{
366+
/* 6 is max possible length of our args array including NULL */
367+
const char *args[6];
368+
int i = 0;
369+
370+
args[i++] = "commit";
371+
args[i++] = "-n";
372+
if (signoff)
373+
args[i++] = "-s";
374+
if (!edit) {
375+
args[i++] = "-F";
376+
args[i++] = defmsg;
377+
}
378+
args[i] = NULL;
379+
380+
return run_command_v_opt(args, RUN_GIT_CMD);
358381
}
359382

360383
static int do_pick_commit(void)
@@ -365,6 +388,7 @@ static int do_pick_commit(void)
365388
struct commit_message msg = { NULL, NULL, NULL, NULL, NULL };
366389
char *defmsg = NULL;
367390
struct strbuf msgbuf = STRBUF_INIT;
391+
int res;
368392

369393
if (no_commit) {
370394
/*
@@ -460,63 +484,40 @@ static int do_pick_commit(void)
460484
}
461485
}
462486

463-
if (!strategy || !strcmp(strategy, "recursive") || action == REVERT)
464-
do_recursive_merge(base, next, base_label, next_label,
465-
head, &msgbuf, defmsg);
466-
else {
467-
int res;
487+
if (!strategy || !strcmp(strategy, "recursive") || action == REVERT) {
488+
res = do_recursive_merge(base, next, base_label, next_label,
489+
head, &msgbuf);
490+
write_message(&msgbuf, defmsg);
491+
} else {
468492
struct commit_list *common = NULL;
469493
struct commit_list *remotes = NULL;
494+
470495
write_message(&msgbuf, defmsg);
496+
471497
commit_list_insert(base, &common);
472498
commit_list_insert(next, &remotes);
473499
res = try_merge_command(strategy, common,
474500
sha1_to_hex(head), remotes);
475501
free_commit_list(common);
476502
free_commit_list(remotes);
477-
if (res) {
478-
fprintf(stderr, "Automatic %s with strategy %s failed.%s\n",
479-
me, strategy, help_msg());
480-
rerere(allow_rerere_auto);
481-
exit(1);
482-
}
483503
}
484504

485-
free_message(&msg);
486-
487-
/*
488-
*
489-
* If we are cherry-pick, and if the merge did not result in
490-
* hand-editing, we will hit this commit and inherit the original
491-
* author date and name.
492-
* If we are revert, or if our cherry-pick results in a hand merge,
493-
* we had better say that the current user is responsible for that.
494-
*/
495-
496-
if (!no_commit) {
497-
/* 6 is max possible length of our args array including NULL */
498-
const char *args[6];
499-
int res;
500-
int i = 0;
501-
502-
args[i++] = "commit";
503-
args[i++] = "-n";
504-
if (signoff)
505-
args[i++] = "-s";
506-
if (!edit) {
507-
args[i++] = "-F";
508-
args[i++] = defmsg;
509-
}
510-
args[i] = NULL;
511-
res = run_command_v_opt(args, RUN_GIT_CMD);
512-
free(defmsg);
513-
514-
return res;
505+
if (res) {
506+
error("could not %s %s... %s",
507+
action == REVERT ? "revert" : "apply",
508+
find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),
509+
msg.subject);
510+
print_advice();
511+
rerere(allow_rerere_auto);
512+
} else {
513+
if (!no_commit)
514+
res = run_git_commit(defmsg);
515515
}
516516

517+
free_message(&msg);
517518
free(defmsg);
518519

519-
return 0;
520+
return res;
520521
}
521522

522523
static void prepare_revs(struct rev_info *revs)

contrib/examples/git-revert.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@ Conflicts:
181181
esac
182182
exit 1
183183
}
184-
echo >&2 "Finished one $me."
185184

186185
# If we are cherry-pick, and if the merge did not result in
187186
# hand-editing, we will hit this commit and inherit the original

git-rebase--interactive.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,9 @@ AUTOSQUASH=
114114
test "$(git config --bool rebase.autosquash)" = "true" && AUTOSQUASH=t
115115
NEVER_FF=
116116

117-
GIT_CHERRY_PICK_HELP=" After resolving the conflicts,
118-
mark the corrected paths with 'git add <paths>', and
119-
run 'git rebase --continue'"
117+
GIT_CHERRY_PICK_HELP="\
118+
hint: after resolving the conflicts, mark the corrected paths
119+
hint: with 'git add <paths>' and run 'git rebase --continue'"
120120
export GIT_CHERRY_PICK_HELP
121121

122122
warn () {

t/t3507-cherry-pick-conflict.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,26 @@ test_expect_success 'failed cherry-pick does not advance HEAD' '
3838
test "$head" = "$newhead"
3939
'
4040

41+
test_expect_success 'advice from failed cherry-pick' "
42+
git checkout -f initial^0 &&
43+
git read-tree -u --reset HEAD &&
44+
git clean -d -f -f -q -x &&
45+
46+
git update-index --refresh &&
47+
git diff-index --exit-code HEAD &&
48+
49+
picked=\$(git rev-parse --short picked) &&
50+
cat <<-EOF >expected &&
51+
error: could not apply \$picked... picked
52+
hint: after resolving the conflicts, mark the corrected paths
53+
hint: with 'git add <paths>' or 'git rm <paths>'
54+
hint: and commit the result with 'git commit -c \$picked'
55+
EOF
56+
test_must_fail git cherry-pick picked 2>actual &&
57+
58+
test_cmp expected actual
59+
"
60+
4161
test_expect_success 'failed cherry-pick produces dirty index' '
4262
4363
git checkout -f initial^0 &&

t/t3508-cherry-pick-many-commits.sh

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,18 @@ test_description='test cherry-picking many commits'
44

55
. ./test-lib.sh
66

7+
check_head_differs_from() {
8+
head=$(git rev-parse --verify HEAD) &&
9+
arg=$(git rev-parse --verify "$1") &&
10+
test "$head" != "$arg"
11+
}
12+
13+
check_head_equals() {
14+
head=$(git rev-parse --verify HEAD) &&
15+
arg=$(git rev-parse --verify "$1") &&
16+
test "$head" = "$arg"
17+
}
18+
719
test_expect_success setup '
820
echo first > file1 &&
921
git add file1 &&
@@ -23,13 +35,55 @@ test_expect_success setup '
2335
'
2436

2537
test_expect_success 'cherry-pick first..fourth works' '
38+
cat <<-\EOF >expected &&
39+
[master OBJID] second
40+
Author: A U Thor <author@example.com>
41+
1 files changed, 1 insertions(+), 0 deletions(-)
42+
[master OBJID] third
43+
Author: A U Thor <author@example.com>
44+
1 files changed, 1 insertions(+), 0 deletions(-)
45+
[master OBJID] fourth
46+
Author: A U Thor <author@example.com>
47+
1 files changed, 1 insertions(+), 0 deletions(-)
48+
EOF
49+
50+
git checkout -f master &&
51+
git reset --hard first &&
52+
test_tick &&
53+
git cherry-pick first..fourth >actual &&
54+
git diff --quiet other &&
55+
git diff --quiet HEAD other &&
56+
57+
sed -e "s/$_x05[0-9a-f][0-9a-f]/OBJID/" <actual >actual.fuzzy &&
58+
test_cmp expected actual.fuzzy &&
59+
check_head_differs_from fourth
60+
'
61+
62+
test_expect_success 'cherry-pick --strategy resolve first..fourth works' '
63+
cat <<-\EOF >expected &&
64+
Trying simple merge.
65+
[master OBJID] second
66+
Author: A U Thor <author@example.com>
67+
1 files changed, 1 insertions(+), 0 deletions(-)
68+
Trying simple merge.
69+
[master OBJID] third
70+
Author: A U Thor <author@example.com>
71+
1 files changed, 1 insertions(+), 0 deletions(-)
72+
Trying simple merge.
73+
[master OBJID] fourth
74+
Author: A U Thor <author@example.com>
75+
1 files changed, 1 insertions(+), 0 deletions(-)
76+
EOF
77+
2678
git checkout -f master &&
2779
git reset --hard first &&
2880
test_tick &&
29-
git cherry-pick first..fourth &&
81+
git cherry-pick --strategy resolve first..fourth >actual &&
3082
git diff --quiet other &&
3183
git diff --quiet HEAD other &&
32-
test "$(git rev-parse --verify HEAD)" != "$(git rev-parse --verify fourth)"
84+
sed -e "s/$_x05[0-9a-f][0-9a-f]/OBJID/" <actual >actual.fuzzy &&
85+
test_cmp expected actual.fuzzy &&
86+
check_head_differs_from fourth
3387
'
3488

3589
test_expect_success 'cherry-pick --ff first..fourth works' '
@@ -39,7 +93,7 @@ test_expect_success 'cherry-pick --ff first..fourth works' '
3993
git cherry-pick --ff first..fourth &&
4094
git diff --quiet other &&
4195
git diff --quiet HEAD other &&
42-
test "$(git rev-parse --verify HEAD)" = "$(git rev-parse --verify fourth)"
96+
check_head_equals fourth
4397
'
4498

4599
test_expect_success 'cherry-pick -n first..fourth works' '
@@ -89,7 +143,7 @@ test_expect_success 'cherry-pick -3 fourth works' '
89143
git cherry-pick -3 fourth &&
90144
git diff --quiet other &&
91145
git diff --quiet HEAD other &&
92-
test "$(git rev-parse --verify HEAD)" != "$(git rev-parse --verify fourth)"
146+
check_head_differs_from fourth
93147
'
94148

95149
test_expect_success 'cherry-pick --stdin works' '
@@ -99,7 +153,7 @@ test_expect_success 'cherry-pick --stdin works' '
99153
git rev-list --reverse first..fourth | git cherry-pick --stdin &&
100154
git diff --quiet other &&
101155
git diff --quiet HEAD other &&
102-
test "$(git rev-parse --verify HEAD)" != "$(git rev-parse --verify fourth)"
156+
check_head_differs_from fourth
103157
'
104158

105159
test_done

0 commit comments

Comments
 (0)