All of lore.kernel.org
 help / color / mirror / Atom feed
From: "ZheNing Hu via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Junio C Hamano" <gitster@pobox.com>,
	"Christian Couder" <christian.couder@gmail.com>,
	"Hariom Verma" <hariom18599@gmail.com>,
	"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
	"Han-Wen Nienhuys" <hanwen@google.com>,
	"Ramkumar Ramachandra" <artagnon@gmail.com>,
	"Felipe Contreras" <felipe.contreras@gmail.com>,
	"Phillip Wood" <phillip.wood123@gmail.com>,
	"ZheNing Hu" <adlternative@gmail.com>,
	"ZheNing Hu" <adlternative@gmail.com>
Subject: [PATCH v4] [GSOC] cherry-pick: use better advice message
Date: Sat, 14 Aug 2021 10:27:43 +0000	[thread overview]
Message-ID: <pull.1010.v4.git.1628936863733.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1010.v3.git.1628142482640.gitgitgadget@gmail.com>

From: ZheNing Hu <adlternative@gmail.com>

In the past, git cherry-pick would print such advice when
there was a conflict:

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'

But in fact, when we want to cherry-pick multiple commits,
we should not use "git commit" after resolving conflicts, which
will make Git generate some errors. We should recommend users to
use `git cherry-pick --continue`, `git cherry-pick --abort`, just
like git rebase does.

This is the improved advice:

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".

Similarly, this optimization can be applied to git revert:

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".

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>
Hepled-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: ZheNing Hu <adlternative@gmail.com>
---
    [GSOC] cherry-pick: use better advice message
    
    Because git cherry-pick's past advice message is not good enough, it
    often misleads new users of Git, so this patch makes git chery-pick
    advice message better.
    
    v6:
    https://lore.kernel.org/git/pull.1010.v3.git.1628142482640.gitgitgadget@gmail.com/
    
    v6-->v7:
    
     1. Modify the advice order, respect git cherry-pick --no-commit advice.
     2. Let git revert also use better message.
     3. Use double quotes instead of single quotes for the test body.

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

Range-diff vs v3:

 1:  701645dde17 ! 1:  dc51c0b8c2b [GSOC] cherry-pick: use better advice message
     @@ Commit message
          hint: To abort and get back to the state before "git cherry-pick",
          hint: run "git cherry-pick --abort".
      
     +    Similarly, this optimization can be applied to git revert:
     +
     +    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".
     +
          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: ".
     @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,
       		 * A conflict has occurred but the porcelain
       		 * (typically rebase --interactive) wants to take care
      @@ sequencer.c: static void print_advice(struct repository *r, int show_hint,
     - 	}
     - 
     - 	if (show_hint) {
     --		if (opts->no_commit)
     -+		if (opts->action == REPLAY_PICK) {
     + 		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->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_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"
     +
     + ## t/t3501-revert-cherry-pick.sh ##
     +@@ t/t3501-revert-cherry-pick.sh: test_expect_success 'cherry-pick works with dirty renamed file' '
     + 	grep -q "^modified$" renamed
     + '
     + 
     ++test_expect_success 'advice from failed revert' '
     ++	echo dream >dream &&
     ++	git add dream &&
     ++	git commit -m "add 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
     ++	echo dream >>dream &&
     ++	git add dream &&
     ++	git commit -m "double-add dream" &&
     ++	test_must_fail git revert HEAD^ 2>actual &&
     ++	test_cmp expected actual
     ++'
     + test_done
      
       ## t/t3507-cherry-pick-conflict.sh ##
     -@@ t/t3507-cherry-pick-conflict.sh: test_expect_success 'advice from failed cherry-pick' "
     - 	picked=\$(git rev-parse --short picked) &&
     +@@ t/t3507-cherry-pick-conflict.sh: 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
     +-	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\".
     ++	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 &&
       
     -@@ t/t3507-cherry-pick-conflict.sh: test_expect_success 'advice from failed cherry-pick --no-commit' "
     - 	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: 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 --no-commit picked 2>actual &&
     + 	test_cmp expected actual
     +-"
     ++'
       
     + test_expect_success 'advice from failed cherry-pick --no-commit' "
     + 	pristine_detach initial &&


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

diff --git a/sequencer.c b/sequencer.c
index 0bec01cf38e..2dd73d24a87 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,6 +418,20 @@ 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"
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index 9d100cd1884..6766aed7282 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -158,4 +158,24 @@ test_expect_success 'cherry-pick works with dirty renamed file' '
 	grep -q "^modified$" renamed
 '
 
+test_expect_success 'advice from failed revert' '
+	echo dream >dream &&
+	git add dream &&
+	git commit -m "add 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
+	echo dream >>dream &&
+	git add dream &&
+	git commit -m "double-add 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 &&

base-commit: daab8a564f8bbac55f70f8bf86c070e001a9b006
-- 
gitgitgadget

  parent reply	other threads:[~2021-08-14 10:27 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-31  7:01 [PATCH 0/2] [GSOC] cherry-pick: fix bug when used with GIT_CHERRY_PICK_HELP ZheNing Hu via GitGitGadget
2021-07-31  7:01 ` [PATCH 1/2] " ZheNing Hu via GitGitGadget
2021-08-01 10:09   ` Phillip Wood
2021-08-02 13:34     ` ZheNing Hu
2021-07-31  7:01 ` [PATCH 2/2] [GSOC] cherry-pick: use better advice message ZheNing Hu via GitGitGadget
2021-08-01 10:14   ` Phillip Wood
2021-08-02 13:35     ` ZheNing Hu
2021-08-03  1:16 ` [PATCH v2 0/2] [GSOC] cherry-pick: fix bug when used with GIT_CHERRY_PICK_HELP ZheNing Hu via GitGitGadget
2021-08-03  1:16   ` [PATCH v2 1/2] " ZheNing Hu via GitGitGadget
2021-08-03 22:36     ` Junio C Hamano
2021-08-04  8:35       ` ZheNing Hu
2021-08-04 10:10         ` Phillip Wood
2021-08-04 17:31           ` Junio C Hamano
2021-08-05  5:36             ` ZheNing Hu
2021-08-03  1:16   ` [PATCH v2 2/2] [GSOC] cherry-pick: use better advice message ZheNing Hu via GitGitGadget
2021-08-05  5:48   ` [PATCH v3] " ZheNing Hu via GitGitGadget
2021-08-11 10:00     ` Phillip Wood
2021-08-13  8:08       ` ZheNing Hu
2021-08-13 20:14       ` Junio C Hamano
2021-08-14  2:07         ` ZheNing Hu
2021-08-17 10:09         ` Phillip Wood
2021-08-14 10:27     ` ZheNing Hu via GitGitGadget [this message]
2021-08-14 20:32       ` [PATCH v4] " Junio C Hamano
2021-08-15 12:48         ` ZheNing Hu
2021-08-16  0:55       ` [PATCH v5] " ZheNing Hu via GitGitGadget
2021-08-18  9:51         ` Phillip Wood
2021-08-19  1:55           ` ZheNing Hu
2021-08-19  2:07             ` ZheNing Hu
2021-08-19  5:51         ` [PATCH v6] " ZheNing Hu via GitGitGadget
2021-08-19 17:10           ` Junio C Hamano
2021-08-21  1:40             ` ZheNing Hu
2021-08-22 13:08           ` [PATCH v7] " ZheNing Hu via GitGitGadget

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=pull.1010.v4.git.1628936863733.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=adlternative@gmail.com \
    --cc=artagnon@gmail.com \
    --cc=avarab@gmail.com \
    --cc=christian.couder@gmail.com \
    --cc=felipe.contreras@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=hanwen@google.com \
    --cc=hariom18599@gmail.com \
    --cc=phillip.wood123@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.