diff mbox series

[v6,GSOC] cherry-pick: use better advice message

Message ID pull.1010.v6.git.1629352277151.gitgitgadget@gmail.com (mailing list archive)
State Superseded
Headers show
Series [v6,GSOC] cherry-pick: use better advice message | expand

Commit Message

ZheNing Hu Aug. 19, 2021, 5:51 a.m. UTC
From: ZheNing Hu <adlternative@gmail.com>

"git cherry-pick", upon seeing a conflict, says:

hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

as if running "git commit" to conclude the resolution of
this single step were the end of the story.  This stems from
the fact that the command originally was to pick a single
commit and not a range of commits, and the message was
written back then and has not been adjusted.

When picking a range of commits and the command stops with a
conflict in the middle of the range, however, after
resolving the conflict and (optionally) recording the result
with "git commit", the user has to run "git cherry-pick
--continue" to have the rest of the range dealt with,
"--skip" to drop the current commit, or "--abort" to discard
the series.

Suggest use of "git cherry-pick --continue/--skip/--abort"
so that the message also covers the case where a range of
commits are being picked.

Similarly, this optimization can be applied to git revert,
suggest use of "git revert --continue/--skip/--abort" so
that the message also covers the case where a range of
commits are being reverted.

It is worth mentioning that now we use advice() to print
the content of GIT_CHERRY_PICK_HELP in print_advice(), each
line of output will start with "hint: ".

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by Hariom Verma <hariom18599@gmail.com>
Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: ZheNing Hu <adlternative@gmail.com>
---
    [GSOC] cherry-pick: use better advice message
    
    The cherry-pick and revert advice message are only suitable for picking
    one commit or reverting one commit, but not for multiple commits. So
    correct the advice message to have the rest of the range dealt with.
    
    v8:
    https://lore.kernel.org/git/pull.1010.v5.git.1629075306706.gitgitgadget@gmail.com/
    
    v8-->v9:
    
     1. Use the test_commit function in the test.
     2. Treat these commands which are not using cherry-pick or revert and
        without setting GIT_CHERRY_PICK_HELP as a BUG.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1010%2Fadlternative%2Fcherry-pick-help-fix-3-v6
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1010/adlternative/cherry-pick-help-fix-3-v6
Pull-Request: https://github.com/gitgitgadget/git/pull/1010

Range-diff vs v5:

 1:  6cf78ffd088 ! 1:  84676c475ee [GSOC] cherry-pick: use better advice message
     @@ Commit message
          line of output will start with "hint: ".
      
          Mentored-by: Christian Couder <christian.couder@gmail.com>
     -    Mentored-by Hariom Verma <hariom18599@gmail.com>:
     +    Mentored-by Hariom Verma <hariom18599@gmail.com>
          Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>
          Helped-by: Junio C Hamano <gitster@pobox.com>
          Signed-off-by: ZheNing Hu <adlternative@gmail.com>
     @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,
      +				 "To abort and get back to the state before \"git revert\",\n"
      +				 "run \"git revert --abort\"."));
       		else
     - 			advise(_("after resolving the conflicts, mark the corrected paths\n"
     - 				 "with 'git add <paths>' or 'git rm <paths>'\n"
     +-			advise(_("after resolving the conflicts, mark the corrected paths\n"
     +-				 "with 'git add <paths>' or 'git rm <paths>'\n"
     +-				 "and commit the result with 'git commit'"));
     ++			BUG("unexpected pick action in print_advice()");
     + 	}
     + }
     + 
      
       ## t/t3501-revert-cherry-pick.sh ##
      @@ t/t3501-revert-cherry-pick.sh: test_expect_success 'cherry-pick works with dirty renamed file' '
     @@ t/t3501-revert-cherry-pick.sh: test_expect_success 'cherry-pick works with dirty
       '
       
      +test_expect_success 'advice from failed revert' '
     -+	echo dream >dream &&
     -+	git add dream &&
     -+	git commit -m "add dream" &&
     ++	test_commit --no-tag "add dream" dream dream &&
      +	dream_oid=$(git rev-parse --short HEAD) &&
      +	cat <<-EOF >expected &&
      +	error: could not revert $dream_oid... add dream
     @@ t/t3501-revert-cherry-pick.sh: test_expect_success 'cherry-pick works with dirty
      +	hint: To abort and get back to the state before "git revert",
      +	hint: run "git revert --abort".
      +	EOF
     -+	echo dream >>dream &&
     -+	git add dream &&
     -+	git commit -m "double-add dream" &&
     ++	test_commit --append --no-tag "double-add dream" dream dream &&
      +	test_must_fail git revert HEAD^ 2>actual &&
      +	test_cmp expected actual
      +'


 sequencer.c                     | 20 ++++++++++++++++----
 t/t3501-revert-cherry-pick.sh   | 16 ++++++++++++++++
 t/t3507-cherry-pick-conflict.sh | 17 ++++++++++-------
 3 files changed, 42 insertions(+), 11 deletions(-)


base-commit: daab8a564f8bbac55f70f8bf86c070e001a9b006

Comments

Junio C Hamano Aug. 19, 2021, 5:10 p.m. UTC | #1
"ZheNing Hu via GitGitGadget" <gitgitgadget@gmail.com> writes:

>           Mentored-by: Christian Couder <christian.couder@gmail.com>
>      -    Mentored-by Hariom Verma <hariom18599@gmail.com>:
>      +    Mentored-by Hariom Verma <hariom18599@gmail.com>

I think you meant to move ':' not remove it.

> +		else if (opts->action == REPLAY_PICK)
> +			advise(_("Resolve all conflicts manually, mark them as resolved with\n"

Do we need to say "manually"?  Dropping the word would make the
message more concise.  Not repeating the word "resolve" by saying
something like "after resolving the conflicts, mark them with ..."
would probably be a much better phrasing, too.

> +				 "\"git add/rm <conflicted_files>\", then run\n"

<paths> (or <pathspec>) not <conflicted_files>; you can resolve many
files in a directory and give the pathspec to match the directory to
mark all the files in there as resolved.

> +				 "\"git cherry-pick --continue\".\n"
> +				 "You can instead skip this commit: run \"git cherry-pick --skip\".\n"

Inconsistent use of prose in the above and ": run" here.

        You can instead skip this commit with "git cherry-pick --skip"

> +		else if (opts->action == REPLAY_REVERT)

Likewise.

Thanks.
ZheNing Hu Aug. 21, 2021, 1:40 a.m. UTC | #2
Junio C Hamano <gitster@pobox.com> 于2021年8月20日周五 上午1:10写道:
>
> > +             else if (opts->action == REPLAY_PICK)
> > +                     advise(_("Resolve all conflicts manually, mark them as resolved with\n"
>
> Do we need to say "manually"?  Dropping the word would make the
> message more concise.  Not repeating the word "resolve" by saying
> something like "after resolving the conflicts, mark them with ..."
> would probably be a much better phrasing, too.
>

Yeah. Note the $reslovemsg in git-rebase--preserve-merges.sh, I copied
it from here. Perhaps it is also worth modifying?

> > +                              "\"git add/rm <conflicted_files>\", then run\n"
>
> <paths> (or <pathspec>) not <conflicted_files>; you can resolve many
> files in a directory and give the pathspec to match the directory to
> mark all the files in there as resolved.
>

Indeed so.

> > +                              "\"git cherry-pick --continue\".\n"
> > +                              "You can instead skip this commit: run \"git cherry-pick --skip\".\n"
>
> Inconsistent use of prose in the above and ": run" here.
>
>         You can instead skip this commit with "git cherry-pick --skip"
>
> > +             else if (opts->action == REPLAY_REVERT)
>
> Likewise.
>
> Thanks.

Thanks.
--
ZheNing Hu
diff mbox series

Patch

diff --git a/sequencer.c b/sequencer.c
index 0bec01cf38e..f114b4ba80e 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -403,7 +403,7 @@  static void print_advice(struct repository *r, int show_hint,
 	char *msg = getenv("GIT_CHERRY_PICK_HELP");
 
 	if (msg) {
-		fprintf(stderr, "%s\n", msg);
+		advise("%s\n", msg);
 		/*
 		 * A conflict has occurred but the porcelain
 		 * (typically rebase --interactive) wants to take care
@@ -418,10 +418,22 @@  static void print_advice(struct repository *r, int show_hint,
 		if (opts->no_commit)
 			advise(_("after resolving the conflicts, mark the corrected paths\n"
 				 "with 'git add <paths>' or 'git rm <paths>'"));
+		else if (opts->action == REPLAY_PICK)
+			advise(_("Resolve all conflicts manually, mark them as resolved with\n"
+				 "\"git add/rm <conflicted_files>\", then run\n"
+				 "\"git cherry-pick --continue\".\n"
+				 "You can instead skip this commit: run \"git cherry-pick --skip\".\n"
+				 "To abort and get back to the state before \"git cherry-pick\",\n"
+				 "run \"git cherry-pick --abort\"."));
+		else if (opts->action == REPLAY_REVERT)
+			advise(_("Resolve all conflicts manually, mark them as resolved with\n"
+				 "\"git add/rm <conflicted_files>\", then run\n"
+				 "\"git revert --continue\".\n"
+				 "You can instead skip this commit: run \"git revert --skip\".\n"
+				 "To abort and get back to the state before \"git revert\",\n"
+				 "run \"git revert --abort\"."));
 		else
-			advise(_("after resolving the conflicts, mark the corrected paths\n"
-				 "with 'git add <paths>' or 'git rm <paths>'\n"
-				 "and commit the result with 'git commit'"));
+			BUG("unexpected pick action in print_advice()");
 	}
 }
 
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index 9d100cd1884..e70a33f3e60 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -158,4 +158,20 @@  test_expect_success 'cherry-pick works with dirty renamed file' '
 	grep -q "^modified$" renamed
 '
 
+test_expect_success 'advice from failed revert' '
+	test_commit --no-tag "add dream" dream dream &&
+	dream_oid=$(git rev-parse --short HEAD) &&
+	cat <<-EOF >expected &&
+	error: could not revert $dream_oid... add dream
+	hint: Resolve all conflicts manually, mark them as resolved with
+	hint: "git add/rm <conflicted_files>", then run
+	hint: "git revert --continue".
+	hint: You can instead skip this commit: run "git revert --skip".
+	hint: To abort and get back to the state before "git revert",
+	hint: run "git revert --abort".
+	EOF
+	test_commit --append --no-tag "double-add dream" dream dream &&
+	test_must_fail git revert HEAD^ 2>actual &&
+	test_cmp expected actual
+'
 test_done
diff --git a/t/t3507-cherry-pick-conflict.sh b/t/t3507-cherry-pick-conflict.sh
index 014001b8f32..cb2ebea9ad3 100755
--- a/t/t3507-cherry-pick-conflict.sh
+++ b/t/t3507-cherry-pick-conflict.sh
@@ -47,20 +47,23 @@  test_expect_success 'failed cherry-pick does not advance HEAD' '
 	test "$head" = "$newhead"
 '
 
-test_expect_success 'advice from failed cherry-pick' "
+test_expect_success 'advice from failed cherry-pick' '
 	pristine_detach initial &&
 
-	picked=\$(git rev-parse --short picked) &&
+	picked=$(git rev-parse --short picked) &&
 	cat <<-EOF >expected &&
-	error: could not apply \$picked... picked
-	hint: after resolving the conflicts, mark the corrected paths
-	hint: with 'git add <paths>' or 'git rm <paths>'
-	hint: and commit the result with 'git commit'
+	error: could not apply $picked... picked
+	hint: Resolve all conflicts manually, mark them as resolved with
+	hint: "git add/rm <conflicted_files>", then run
+	hint: "git cherry-pick --continue".
+	hint: You can instead skip this commit: run "git cherry-pick --skip".
+	hint: To abort and get back to the state before "git cherry-pick",
+	hint: run "git cherry-pick --abort".
 	EOF
 	test_must_fail git cherry-pick picked 2>actual &&
 
 	test_cmp expected actual
-"
+'
 
 test_expect_success 'advice from failed cherry-pick --no-commit' "
 	pristine_detach initial &&