git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v7 12/12] cherry-pick: copy notes and run hooks

From
Felipe Contreras <felipe.contreras@gmail.com>
Date
Apr 24, 2014, 02:44 UTC
Message-ID
<1398307491-21314-13-git-send-email-felipe.contreras@gmail.com>
In-Reply-To
<1398307491-21314-1-git-send-email-felipe.contreras@gmail.com>
If no action-name is specified, nothing is done.
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 Documentation/config.txt       |  9 ++++-----
 Documentation/githooks.txt     |  8 ++++----
 git-rebase--interactive.sh     |  4 ++--
 sequencer.c                    | 28 +++++++++++++++++++++++++++-
 t/t3512-revert-cherry-notes.sh | 18 ++++++++++++++++++
 t/t5407-post-rewrite-hook.sh   | 16 ++++++++++++++++
 6 files changed, 71 insertions(+), 12 deletions(-)
 create mode 100755 t/t3512-revert-cherry-notes.sh
diff --git a/Documentation/config.txt b/Documentation/config.txt
index c26a7c8..c328d33 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1752,11 +1752,10 @@ GIT_NOTES_REF) is also implicitly added to the list of refs to be
 displayed.
 
 notes.rewrite.<command>::
-	When rewriting commits with <command> (currently `amend` or
-	`rebase`) and this variable is set to `true`, Git
-	automatically copies your notes from the original to the
-	rewritten commit.  Defaults to `true`, but see
-	"notes.rewriteRef" below.
+	When rewriting commits with <command> (currently `amend`, `rebase`, or
+	`cherry-pick`) and this variable is set to `true`, Git automatically
+	copies your notes from the original to the rewritten commit.  Defaults
+	to `true`, but see "notes.rewriteRef" below.
 
 notes.rewriteMode::
 	When copying notes during a rewrite (see the
diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt
index d954bf6..2402e7d 100644
--- a/Documentation/githooks.txt
+++ b/Documentation/githooks.txt
@@ -352,10 +352,10 @@ post-rewrite
 ~~~~~~~~~~~~
 
 This hook is invoked by commands that rewrite commits (`git commit
---amend`, 'git-rebase'; currently 'git-filter-branch' does 'not' call
-it!).  Its first argument denotes the command it was invoked by:
-currently one of `amend` or `rebase`.  Further command-dependent
-arguments may be passed in the future.
+--amend`, `git rebase`, `git cherry-pick`; currently `git filter-branch` does
+'not' call it!).  Its first argument denotes the command it was invoked by
+(e.g. `rebase`).  Further command-dependent arguments may be passed in the
+future.
 
 The hook receives a list of the rewritten commits on stdin, in the
 format
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 43631b4..fd085e1 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -248,7 +248,7 @@ pick_one () {
 
 	test -d "$rewritten" &&
 		pick_one_preserving_merges "$@" && return
-	output eval git cherry-pick "$strategy_args" $empty_args $ff "$@"
+	output eval git cherry-pick "--action-name ''" "$strategy_args" $empty_args $ff "$@"
 }
 
 pick_one_preserving_merges () {
@@ -359,7 +359,7 @@ pick_one_preserving_merges () {
 			echo "$sha1 $(git rev-parse HEAD^0)" >> "$rewritten_list"
 			;;
 		*)
-			output eval git cherry-pick "$strategy_args" "$@" ||
+			output eval git cherry-pick "--action-name ''" "$strategy_args" "$@" ||
 				die_with_patch $sha1 "Could not pick $sha1"
 			;;
 		esac
diff --git a/sequencer.c b/sequencer.c
index ed59d75..2eb6ce8 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -22,6 +22,25 @@ const char sign_off_header[] = "Signed-off-by: ";
 static const char cherry_picked_prefix[] = "(cherry picked from commit ";
 static struct rewritten rewritten;
 
+static void finish(struct replay_opts *opts)
+{
+	const char *name;
+	struct strbuf msg = STRBUF_INIT;
+
+	if (opts->action != REPLAY_PICK)
+		return;
+
+	name = opts->action_name ? opts->action_name : "cherry-pick";
+
+	if (!*name)
+		return;
+
+	strbuf_addf(&msg, "Notes added by 'git %s'", name);
+	copy_rewrite_notes(&rewritten, name, msg.buf);
+	run_rewrite_hook(&rewritten, name);
+	strbuf_release(&msg);
+}
+
 static int is_rfc2822_line(const char *buf, int len)
 {
 	int i;
@@ -1042,6 +1061,8 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
 		}
 	}
 
+	finish(opts);
+
 	/*
 	 * Sequence of picks finished successfully; cleanup by
 	 * removing the .git/sequencer directory
@@ -1113,8 +1134,13 @@ static int sequencer_skip(struct replay_opts *opts)
 
 static int single_pick(struct commit *cmit, struct replay_opts *opts)
 {
+	int ret;
 	setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
-	return do_pick_commit(cmit, opts);
+	ret = do_pick_commit(cmit, opts);
+	if (ret)
+		return ret;
+	finish(opts);
+	return 0;
 }
 
 int sequencer_pick_revisions(struct replay_opts *opts)
diff --git a/t/t3512-revert-cherry-notes.sh b/t/t3512-revert-cherry-notes.sh
new file mode 100755
index 0000000..9e9e611
--- /dev/null
+++ b/t/t3512-revert-cherry-notes.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+test_description='test cherry-pick and revert notes'
+
+. ./test-lib.sh
+
+test_expect_success 'notes are rewritten' '
+	test_config notes.rewrite.cherry-pick true &&
+	test_config notes.rewriteRef "refs/notes/*" &&
+	test_commit n1 &&
+	test_commit n2 &&
+	git notes add -m "a note" n2 &&
+	git checkout n1 &&
+	git cherry-pick n2 &&
+	git notes show HEAD
+'
+
+test_done
diff --git a/t/t5407-post-rewrite-hook.sh b/t/t5407-post-rewrite-hook.sh
index ea2e0d4..53d7ade 100755
--- a/t/t5407-post-rewrite-hook.sh
+++ b/t/t5407-post-rewrite-hook.sh
@@ -53,6 +53,22 @@ test_expect_success 'git commit --amend --no-post-rewrite' '
 	test ! -f post-rewrite.data
 '
 
+test_expect_success 'git cherry-pick' '
+	git reset --hard D &&
+	clear_hook_input &&
+	git checkout A &&
+	test_must_fail git cherry-pick B..D &&
+	echo C > foo &&
+	git add foo &&
+	git cherry-pick --continue &&
+	echo cherry-pick >expected.args &&
+	cat >expected.data <<EOF &&
+$(git rev-parse C) $(git rev-parse HEAD^)
+$(git rev-parse D) $(git rev-parse HEAD)
+EOF
+	verify_hook_input
+'
+
 test_expect_success 'git rebase' '
 	git reset --hard D &&
 	clear_hook_input &&
-- 
1.9.2+fc1.2.gfbaae8c
Previous: Felipe ContrerasNext: Ramkumar Ramachandra
Message 19 of 23 in “Improvements to cherry-pick”
  1. 00/12 Improvements to cherry-pickFelipe Contreras, Apr 24, 2014
  2. 01/12 cherry-pick: don't barf when there's nothing to doFelipe Contreras, Apr 24, 2014
  3. 02/12 cherry-pick: add --skip-empty optionFelipe Contreras, Apr 24, 2014
  4. 03/12 revert/cherry-pick: add --quiet optionFelipe Contreras, Apr 24, 2014
  5. Ramkumar RamachandraApr 24, 2014
  6. Felipe ContrerasApr 24, 2014
  7. 04/12 revert/cherry-pick: add --skip optionFelipe Contreras, Apr 24, 2014
  8. Ramkumar RamachandraApr 24, 2014
  9. 05/12 cherry-pick: remember rerere-autoupdateFelipe Contreras, Apr 24, 2014
  10. Eric SunshineApr 24, 2014
  11. 06/12 builtin: add rewrite helperFelipe Contreras, Apr 24, 2014
  12. Ramkumar RamachandraApr 24, 2014
  13. Felipe ContrerasApr 24, 2014
  14. 07/12 cherry-pick: store rewritten commitsFelipe Contreras, Apr 24, 2014
  15. 08/12 cherry-pick: don't store skipped commitFelipe Contreras, Apr 24, 2014
  16. 09/12 builtin: move run_rewrite_hook() to rewrite.cFelipe Contreras, Apr 24, 2014
  17. 10/12 builtin: rewrite: add copy_rewrite_notes()Felipe Contreras, Apr 24, 2014
  18. 11/12 cherry-pick: add --action-name optionFelipe Contreras, Apr 24, 2014
  19. 12/12 cherry-pick: copy notes and run hooksFelipe Contreras, Apr 24, 2014
  20. Ramkumar RamachandraApr 24, 2014
  21. Felipe ContrerasApr 24, 2014
  22. Ramkumar RamachandraApr 24, 2014
  23. Felipe ContrerasApr 24, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.