{"thread":{"id":"34039","subject":"[PATCH v3 2/9] sequencer: trivial fix","startedAt":"2013-06-06T08:58:55Z","lastAt":"2013-06-09T15:19:03Z","messageCount":18,"participants":["Felipe Contreras","Junio C Hamano"],"isPatch":true,"patchVersion":3,"patchTotal":9},"messages":[{"id":"219500","messageId":"1370509144-31974-1-git-send-email-felipe.contreras@gmail.com","threadId":"34039","inReplyTo":null,"subject":"[PATCH v3 0/9] cherry-pick: improvements","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T08:58:55Z","receivedAt":"2013-06-06T08:58:55Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Hi,\n\nSames as v2, plus a few changes from the feedback, and cleanups.\n\nFelipe Contreras (9):\n  sequencer: remove useless indentation\n  sequencer: trivial fix\n  cherry-pick: add --skip-empty option\n  cherry-pick: store rewritten commits\n  sequencer: run post-rewrite hook\n  cherry-pick: add support to copy notes\n  revert/cherry-pick: add --quiet option\n  revert/cherry-pick: add --skip option\n  cherry-pick: don't barf when there's nothing to do\n\n Documentation/git-cherry-pick.txt   |  10 +-\n Documentation/git-revert.txt        |   7 +-\n Documentation/sequencer.txt         |   3 +\n builtin/revert.c                    |  15 +++\n sequencer.c                         | 230 ++++++++++++++++++++++++++++++++++--\n sequencer.h                         |   6 +-\n t/t3508-cherry-pick-many-commits.sh |  13 ++\n t/t3510-cherry-pick-sequence.sh     |  12 ++\n 8 files changed, 280 insertions(+), 16 deletions(-)\n\n-- \n1.8.3.698.g079b096\n"},{"id":"219499","messageId":"1370509144-31974-2-git-send-email-felipe.contreras@gmail.com","threadId":"34039","inReplyTo":"1370509144-31974-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 1/9] sequencer: remove useless indentation","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T08:58:56Z","receivedAt":"2013-06-06T08:58:56Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"By using good ol' goto.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n sequencer.c | 16 +++++++++-------\n 1 file changed, 9 insertions(+), 7 deletions(-)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex ab6f8a7..b4989ba 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -474,7 +474,7 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)\n \tstruct commit_message msg = { NULL, NULL, NULL, NULL, NULL };\n \tchar *defmsg = NULL;\n \tstruct strbuf msgbuf = STRBUF_INIT;\n-\tint res, unborn = 0;\n+\tint res, unborn = 0, allow;\n \n \tif (opts->no_commit) {\n \t\t/*\n@@ -624,14 +624,16 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)\n \t\t      msg.subject);\n \t\tprint_advice(res == 1, opts);\n \t\trerere(opts->allow_rerere_auto);\n-\t} else {\n-\t\tint allow = allow_empty(opts, commit);\n-\t\tif (allow < 0)\n-\t\t\treturn allow;\n-\t\tif (!opts->no_commit)\n-\t\t\tres = run_git_commit(defmsg, opts, allow);\n+\t\tgoto leave;\n \t}\n \n+\tallow = allow_empty(opts, commit);\n+\tif (allow < 0)\n+\t\treturn allow;\n+\tif (!opts->no_commit)\n+\t\tres = run_git_commit(defmsg, opts, allow);\n+\n+leave:\n \tfree_message(&msg);\n \tfree(defmsg);\n \n-- \n1.8.3.698.g079b096\n"},{"id":"219491","messageId":"1370509144-31974-3-git-send-email-felipe.contreras@gmail.com","threadId":"34039","inReplyTo":"1370509144-31974-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 2/9] sequencer: trivial fix","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T08:58:57Z","receivedAt":"2013-06-06T08:58:57Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"We should free objects before leaving.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n sequencer.c | 6 ++++--\n 1 file changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex b4989ba..f7be7d8 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -628,8 +628,10 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)\n \t}\n \n \tallow = allow_empty(opts, commit);\n-\tif (allow < 0)\n-\t\treturn allow;\n+\tif (allow < 0) {\n+\t\tres = allow;\n+\t\tgoto leave;\n+\t}\n \tif (!opts->no_commit)\n \t\tres = run_git_commit(defmsg, opts, allow);\n \n-- \n1.8.3.698.g079b096\n"},{"id":"219492","messageId":"1370509144-31974-4-git-send-email-felipe.contreras@gmail.com","threadId":"34039","inReplyTo":"1370509144-31974-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 3/9] cherry-pick: add --skip-empty option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T08:58:58Z","receivedAt":"2013-06-06T08:58:58Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Pretty much what it says on the tin.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/git-cherry-pick.txt   |  3 +++\n builtin/revert.c                    |  8 ++++++++\n sequencer.c                         |  6 ++++++\n sequencer.h                         |  1 +\n t/t3508-cherry-pick-many-commits.sh | 13 +++++++++++++\n 5 files changed, 31 insertions(+)\n\ndiff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt\nindex c205d23..fccd936 100644\n--- a/Documentation/git-cherry-pick.txt\n+++ b/Documentation/git-cherry-pick.txt\n@@ -129,6 +129,9 @@ effect to your index in a row.\n \tredundant commits are ignored.  This option overrides that behavior and\n \tcreates an empty commit object.  Implies `--allow-empty`.\n \n+--skip-empty::\n+\tInstead of failing, skip commits that are or become empty.\n+\n --strategy=<strategy>::\n \tUse the given merge strategy.  Should only be used once.\n \tSee the MERGE STRATEGIES section in linkgit:git-merge[1]\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex 0401fdb..5a8453d 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -118,6 +118,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)\n \t\tOPT_END(),\n \t\tOPT_END(),\n \t\tOPT_END(),\n+\t\tOPT_END(),\n \t};\n \n \tif (opts->action == REPLAY_PICK) {\n@@ -127,6 +128,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)\n \t\t\tOPT_BOOLEAN(0, \"allow-empty\", &opts->allow_empty, N_(\"preserve initially empty commits\")),\n \t\t\tOPT_BOOLEAN(0, \"allow-empty-message\", &opts->allow_empty_message, N_(\"allow commits with empty messages\")),\n \t\t\tOPT_BOOLEAN(0, \"keep-redundant-commits\", &opts->keep_redundant_commits, N_(\"keep redundant, empty commits\")),\n+\t\t\tOPT_BOOLEAN(0, \"skip-empty\", &opts->skip_empty, N_(\"skip empty commits\")),\n \t\t\tOPT_END(),\n \t\t};\n \t\tif (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))\n@@ -144,6 +146,12 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)\n \t\t\t\t\"--abort\", rollback,\n \t\t\t\tNULL);\n \n+\tverify_opt_mutually_compatible(me,\n+\t\t\t\t\"--allow-empty\", opts->allow_empty,\n+\t\t\t\t\"--skip-empty\", opts->skip_empty,\n+\t\t\t\t\"--keep-redundant-commits\", opts->keep_redundant_commits,\n+\t\t\t\tNULL);\n+\n \t/* implies allow_empty */\n \tif (opts->keep_redundant_commits)\n \t\topts->allow_empty = 1;\ndiff --git a/sequencer.c b/sequencer.c\nindex f7be7d8..d3c7d72 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -627,6 +627,12 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)\n \t\tgoto leave;\n \t}\n \n+\tif (opts->skip_empty && is_index_unchanged() == 1) {\n+\t\twarning(_(\"skipping %s... %s\"),\n+\t\t\tfind_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),\n+\t\t\tmsg.subject);\n+\t\tgoto leave;\n+\t}\n \tallow = allow_empty(opts, commit);\n \tif (allow < 0) {\n \t\tres = allow;\ndiff --git a/sequencer.h b/sequencer.h\nindex 1fc22dc..3b04844 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -34,6 +34,7 @@ struct replay_opts {\n \tint allow_empty;\n \tint allow_empty_message;\n \tint keep_redundant_commits;\n+\tint skip_empty;\n \n \tint mainline;\n \ndiff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh\nindex 19c99d7..3dc19c6 100755\n--- a/t/t3508-cherry-pick-many-commits.sh\n+++ b/t/t3508-cherry-pick-many-commits.sh\n@@ -187,4 +187,17 @@ test_expect_success 'cherry-pick --stdin works' '\n \tcheck_head_differs_from fourth\n '\n \n+test_expect_success 'cherry-pick skip empty' '\n+\tgit clean -fxd &&\n+\tgit checkout -b empty fourth &&\n+\tgit commit --allow-empty -m empty &&\n+\ttest_commit ontop &&\n+\tgit checkout -f master &&\n+\tgit reset --hard fourth &&\n+\tgit cherry-pick --skip-empty fourth..empty &&\n+\techo ontop > expected &&\n+\tgit log --format=%s fourth..HEAD > actual\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n1.8.3.698.g079b096\n"},{"id":"219493","messageId":"1370509144-31974-5-git-send-email-felipe.contreras@gmail.com","threadId":"34039","inReplyTo":"1370509144-31974-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 4/9] cherry-pick: store rewritten commits","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T08:58:59Z","receivedAt":"2013-06-06T08:58:59Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Will be useful for the next commits.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n sequencer.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n sequencer.h |   1 +\n 2 files changed, 102 insertions(+), 1 deletion(-)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex d3c7d72..76ff2ff 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -20,6 +20,18 @@\n const char sign_off_header[] = \"Signed-off-by: \";\n static const char cherry_picked_prefix[] = \"(cherry picked from commit \";\n \n+struct rewritten_list_item {\n+\tunsigned char from[20];\n+\tunsigned char to[20];\n+};\n+\n+struct rewritten_list {\n+\tstruct rewritten_list_item *items;\n+\tunsigned int nr, alloc;\n+};\n+\n+static struct rewritten_list rewritten;\n+\n static int is_rfc2822_line(const char *buf, int len)\n {\n \tint i;\n@@ -102,6 +114,19 @@ static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob,\n \treturn 1;\n }\n \n+static void add_rewritten(unsigned char *from, unsigned char *to)\n+{\n+\tstruct rewritten_list_item *item;\n+\tif (rewritten.nr + 1 >= rewritten.alloc) {\n+\t\trewritten.alloc += 32;\n+\t\trewritten.items = xrealloc(rewritten.items, rewritten.alloc * sizeof(*rewritten.items));\n+\t}\n+\titem = &rewritten.items[rewritten.nr];\n+\thashcpy(item->from, from);\n+\thashcpy(item->to, to);\n+\trewritten.nr++;\n+}\n+\n static void remove_sequencer_state(void)\n {\n \tstruct strbuf seq_dir = STRBUF_INIT;\n@@ -641,6 +666,14 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)\n \tif (!opts->no_commit)\n \t\tres = run_git_commit(defmsg, opts, allow);\n \n+\tif (!res && opts->action == REPLAY_PICK) {\n+\t\tunsigned char to[20];\n+\n+\t\tif (read_ref(\"HEAD\", to))\n+\t\t\tgoto leave;\n+\n+\t\tadd_rewritten(commit->object.sha1, to);\n+\t}\n leave:\n \tfree_message(&msg);\n \tfree(defmsg);\n@@ -786,6 +819,40 @@ static void read_populate_todo(struct commit_list **todo_list,\n \t\tdie(_(\"Unusable instruction sheet: %s\"), todo_file);\n }\n \n+static void read_populate_rewritten(void)\n+{\n+\tconst char *rewritten_file = git_path(SEQ_REWR_FILE);\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tchar *p;\n+\tint fd;\n+\n+\tfd = open(rewritten_file, O_RDONLY);\n+\tif (fd < 0)\n+\t\treturn;\n+\tif (strbuf_read(&buf, fd, 0) < 0) {\n+\t\tclose(fd);\n+\t\tstrbuf_release(&buf);\n+\t\treturn;\n+\t}\n+\tclose(fd);\n+\n+\tfor (p = buf.buf; *p;) {\n+\t\tunsigned char from[20];\n+\t\tunsigned char to[20];\n+\t\tchar *eol = strchrnul(p, '\\n');\n+\t\tif (eol - p != 81)\n+\t\t\t/* wrong size */\n+\t\t\tbreak;\n+\t\tif (get_sha1_hex(p, from))\n+\t\t\tbreak;\n+\t\tif (get_sha1_hex(p + 41, to))\n+\t\t\tbreak;\n+\t\tadd_rewritten(from, to);\n+\t\tp = *eol ? eol + 1 : eol;\n+\t}\n+\tstrbuf_release(&buf);\n+}\n+\n static int populate_opts_cb(const char *key, const char *value, void *data)\n {\n \tstruct replay_opts *opts = data;\n@@ -958,6 +1025,29 @@ static void save_todo(struct commit_list *todo_list, struct replay_opts *opts)\n \tstrbuf_release(&buf);\n }\n \n+static void save_rewritten(void)\n+{\n+\tconst char *todo_file = git_path(SEQ_REWR_FILE);\n+\tstatic struct lock_file rewritten_lock;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tint fd, i;\n+\n+\tfd = hold_lock_file_for_update(&rewritten_lock, todo_file, LOCK_DIE_ON_ERROR);\n+\tfor (i = 0; i < rewritten.nr; i++) {\n+\t\tstruct rewritten_list_item *item = &rewritten.items[i];\n+\t\tstrbuf_addf(&buf, \"%s %s\\n\", sha1_to_hex(item->from), sha1_to_hex(item->to));\n+\t}\n+\tif (write_in_full(fd, buf.buf, buf.len) < 0) {\n+\t\tstrbuf_release(&buf);\n+\t\tdie_errno(_(\"Could not write to %s\"), todo_file);\n+\t}\n+\tif (commit_lock_file(&rewritten_lock) < 0) {\n+\t\tstrbuf_release(&buf);\n+\t\tdie(_(\"Error wrapping up %s.\"), todo_file);\n+\t}\n+\tstrbuf_release(&buf);\n+}\n+\n static void save_opts(struct replay_opts *opts)\n {\n \tconst char *opts_file = git_path(SEQ_OPTS_FILE);\n@@ -1003,8 +1093,11 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)\n \tfor (cur = todo_list; cur; cur = cur->next) {\n \t\tsave_todo(cur, opts);\n \t\tres = do_pick_commit(cur->item, opts);\n-\t\tif (res)\n+\t\tif (res) {\n+\t\t\tif (opts->action == REPLAY_PICK)\n+\t\t\t\tsave_rewritten();\n \t\t\treturn res;\n+\t\t}\n \t}\n \n \t/*\n@@ -1033,6 +1126,8 @@ static int sequencer_continue(struct replay_opts *opts)\n \t\treturn continue_single_pick();\n \tread_populate_opts(&opts);\n \tread_populate_todo(&todo_list, opts);\n+\tif (opts->action == REPLAY_PICK)\n+\t\tread_populate_rewritten();\n \n \t/* Verify that the conflict has been resolved */\n \tif (file_exists(git_path(\"CHERRY_PICK_HEAD\")) ||\n@@ -1043,6 +1138,11 @@ static int sequencer_continue(struct replay_opts *opts)\n \t}\n \tif (index_differs_from(\"HEAD\", 0))\n \t\treturn error_dirty_index(opts);\n+\tif (opts->action == REPLAY_PICK) {\n+\t\tunsigned char to[20];\n+\t\tif (!read_ref(\"HEAD\", to))\n+\t\t\tadd_rewritten(todo_list->item->object.sha1, to);\n+\t}\n \ttodo_list = todo_list->next;\n \treturn pick_commits(todo_list, opts);\n }\ndiff --git a/sequencer.h b/sequencer.h\nindex 3b04844..84b9957 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -5,6 +5,7 @@\n #define SEQ_HEAD_FILE\t\"sequencer/head\"\n #define SEQ_TODO_FILE\t\"sequencer/todo\"\n #define SEQ_OPTS_FILE\t\"sequencer/opts\"\n+#define SEQ_REWR_FILE\t\"sequencer/rewritten\"\n \n #define APPEND_SIGNOFF_DEDUP (1u << 0)\n \n-- \n1.8.3.698.g079b096\n"},{"id":"219498","messageId":"1370509144-31974-6-git-send-email-felipe.contreras@gmail.com","threadId":"34039","inReplyTo":"1370509144-31974-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 5/9] sequencer: run post-rewrite hook","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T08:59:00Z","receivedAt":"2013-06-06T08:59:00Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"As we should.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n sequencer.c | 42 +++++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 41 insertions(+), 1 deletion(-)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex 76ff2ff..74480d7 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -127,6 +127,37 @@ static void add_rewritten(unsigned char *from, unsigned char *to)\n \trewritten.nr++;\n }\n \n+static void run_rewrite_hook(const char *name)\n+{\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tstruct child_process proc;\n+\tconst char *argv[3];\n+\tint code, i;\n+\n+\targv[0] = find_hook(\"post-rewrite\");\n+\tif (!argv[0])\n+\t\treturn;\n+\n+\targv[1] = name;\n+\targv[2] = NULL;\n+\n+\tmemset(&proc, 0, sizeof(proc));\n+\tproc.argv = argv;\n+\tproc.in = -1;\n+\tproc.stdout_to_stderr = 1;\n+\n+\tcode = start_command(&proc);\n+\tif (code)\n+\t\treturn;\n+\tfor (i = 0; i < rewritten.nr; i++) {\n+\t\tstruct rewritten_list_item *item = &rewritten.items[i];\n+\t\tstrbuf_addf(&buf, \"%s %s\\n\", sha1_to_hex(item->from), sha1_to_hex(item->to));\n+\t}\n+\twrite_in_full(proc.in, buf.buf, buf.len);\n+\tclose(proc.in);\n+\tfinish_command(&proc);\n+}\n+\n static void remove_sequencer_state(void)\n {\n \tstruct strbuf seq_dir = STRBUF_INIT;\n@@ -1100,6 +1131,9 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)\n \t\t}\n \t}\n \n+\tif (opts->action == REPLAY_PICK)\n+\t\trun_rewrite_hook(\"cherry-pick\");\n+\n \t/*\n \t * Sequence of picks finished successfully; cleanup by\n \t * removing the .git/sequencer directory\n@@ -1149,8 +1183,14 @@ static int sequencer_continue(struct replay_opts *opts)\n \n static int single_pick(struct commit *cmit, struct replay_opts *opts)\n {\n+\tint ret;\n \tsetenv(GIT_REFLOG_ACTION, action_name(opts), 0);\n-\treturn do_pick_commit(cmit, opts);\n+\tret = do_pick_commit(cmit, opts);\n+\tif (ret)\n+\t\treturn ret;\n+\tif (opts->action == REPLAY_PICK)\n+\t\trun_rewrite_hook(\"cherry-pick\");\n+\treturn 0;\n }\n \n int sequencer_pick_revisions(struct replay_opts *opts)\n-- \n1.8.3.698.g079b096\n"},{"id":"219494","messageId":"1370509144-31974-7-git-send-email-felipe.contreras@gmail.com","threadId":"34039","inReplyTo":"1370509144-31974-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 6/9] cherry-pick: add support to copy notes","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T08:59:01Z","receivedAt":"2013-06-06T08:59:01Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n sequencer.c | 33 +++++++++++++++++++++++++++++----\n 1 file changed, 29 insertions(+), 4 deletions(-)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex 74480d7..6d13e63 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -14,6 +14,7 @@\n #include \"merge-recursive.h\"\n #include \"refs.h\"\n #include \"argv-array.h\"\n+#include \"builtin.h\"\n \n #define GIT_REFLOG_ACTION \"GIT_REFLOG_ACTION\"\n \n@@ -158,6 +159,32 @@ static void run_rewrite_hook(const char *name)\n \tfinish_command(&proc);\n }\n \n+static void copy_notes(const char *name)\n+{\n+\tstruct notes_rewrite_cfg *cfg;\n+\tint i;\n+\n+\tcfg = init_copy_notes_for_rewrite(name);\n+\tif (!cfg)\n+\t\treturn;\n+\n+\tfor (i = 0; i < rewritten.nr; i++) {\n+\t\tstruct rewritten_list_item *item = &rewritten.items[i];\n+\t\tcopy_note_for_rewrite(cfg, item->from, item->to);\n+\t}\n+\n+\tfinish_copy_notes_for_rewrite(cfg);\n+}\n+\n+static void finish(struct replay_opts *opts)\n+{\n+\tif (opts->action != REPLAY_PICK)\n+\t\treturn;\n+\n+\trun_rewrite_hook(\"cherry-pick\");\n+\tcopy_notes(\"cherry-pick\");\n+}\n+\n static void remove_sequencer_state(void)\n {\n \tstruct strbuf seq_dir = STRBUF_INIT;\n@@ -1131,8 +1158,7 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)\n \t\t}\n \t}\n \n-\tif (opts->action == REPLAY_PICK)\n-\t\trun_rewrite_hook(\"cherry-pick\");\n+\tfinish(opts);\n \n \t/*\n \t * Sequence of picks finished successfully; cleanup by\n@@ -1188,8 +1214,7 @@ static int single_pick(struct commit *cmit, struct replay_opts *opts)\n \tret = do_pick_commit(cmit, opts);\n \tif (ret)\n \t\treturn ret;\n-\tif (opts->action == REPLAY_PICK)\n-\t\trun_rewrite_hook(\"cherry-pick\");\n+\tfinish(opts);\n \treturn 0;\n }\n \n-- \n1.8.3.698.g079b096\n"},{"id":"219495","messageId":"1370509144-31974-8-git-send-email-felipe.contreras@gmail.com","threadId":"34039","inReplyTo":"1370509144-31974-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 7/9] revert/cherry-pick: add --quiet option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T08:59:02Z","receivedAt":"2013-06-06T08:59:02Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/git-cherry-pick.txt | 6 +++++-\n Documentation/git-revert.txt      | 6 +++++-\n builtin/revert.c                  | 1 +\n sequencer.c                       | 9 ++++++---\n sequencer.h                       | 1 +\n 5 files changed, 18 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt\nindex fccd936..da0bd81 100644\n--- a/Documentation/git-cherry-pick.txt\n+++ b/Documentation/git-cherry-pick.txt\n@@ -8,7 +8,7 @@ git-cherry-pick - Apply the changes introduced by some existing commits\n SYNOPSIS\n --------\n [verse]\n-'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...\n+'git cherry-pick' [-q] [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...\n 'git cherry-pick' --continue\n 'git cherry-pick' --quit\n 'git cherry-pick' --abort\n@@ -51,6 +51,10 @@ OPTIONS\n \tfeed all <commit>... arguments to a single revision walk\n \t(see a later example that uses 'maint master..next').\n \n+-q::\n+--quiet::\n+\tQuiet, suppress feedback messages.\n+\n -e::\n --edit::\n \tWith this option, 'git cherry-pick' will let you edit the commit\ndiff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt\nindex f79c9d8..98a8e7a 100644\n--- a/Documentation/git-revert.txt\n+++ b/Documentation/git-revert.txt\n@@ -8,7 +8,7 @@ git-revert - Revert some existing commits\n SYNOPSIS\n --------\n [verse]\n-'git revert' [--[no-]edit] [-n] [-m parent-number] [-s] <commit>...\n+'git revert' [-q] [--[no-]edit] [-n] [-m parent-number] [-s] <commit>...\n 'git revert' --continue\n 'git revert' --quit\n 'git revert' --abort\n@@ -40,6 +40,10 @@ OPTIONS\n \tdefault, see linkgit:git-rev-list[1] and its '--no-walk'\n \toption.\n \n+-q::\n+--quiet::\n+\tQuiet, suppress feedback messages.\n+\n -e::\n --edit::\n \tWith this option, 'git revert' will let you edit the commit\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex 5a8453d..ec83748 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -100,6 +100,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)\n \tint contin = 0;\n \tint rollback = 0;\n \tstruct option options[] = {\n+\t\tOPT__QUIET(&opts->quiet, N_(\"suppress progress reporting\")),\n \t\tOPT_BOOLEAN(0, \"quit\", &remove_state, N_(\"end revert or cherry-pick sequence\")),\n \t\tOPT_BOOLEAN(0, \"continue\", &contin, N_(\"resume revert or cherry-pick sequence\")),\n \t\tOPT_BOOLEAN(0, \"abort\", &rollback, N_(\"cancel revert or cherry-pick sequence\")),\ndiff --git a/sequencer.c b/sequencer.c\nindex 6d13e63..4b91bd4 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -472,6 +472,8 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,\n \targv_array_init(&array);\n \targv_array_push(&array, \"commit\");\n \targv_array_push(&array, \"-n\");\n+\tif (opts->quiet)\n+\t\targv_array_push(&array, \"-q\");\n \n \tif (opts->signoff)\n \t\targv_array_push(&array, \"-s\");\n@@ -711,9 +713,10 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)\n \t}\n \n \tif (opts->skip_empty && is_index_unchanged() == 1) {\n-\t\twarning(_(\"skipping %s... %s\"),\n-\t\t\tfind_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),\n-\t\t\tmsg.subject);\n+\t\tif (!opts->quiet)\n+\t\t\twarning(_(\"skipping %s... %s\"),\n+\t\t\t\tfind_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),\n+\t\t\t\tmsg.subject);\n \t\tgoto leave;\n \t}\n \tallow = allow_empty(opts, commit);\ndiff --git a/sequencer.h b/sequencer.h\nindex 84b9957..6fc416d 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -36,6 +36,7 @@ struct replay_opts {\n \tint allow_empty_message;\n \tint keep_redundant_commits;\n \tint skip_empty;\n+\tint quiet;\n \n \tint mainline;\n \n-- \n1.8.3.698.g079b096\n"},{"id":"219497","messageId":"1370509144-31974-9-git-send-email-felipe.contreras@gmail.com","threadId":"34039","inReplyTo":"1370509144-31974-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 8/9] revert/cherry-pick: add --skip option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T08:59:03Z","receivedAt":"2013-06-06T08:59:03Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Akin to 'am --skip' and 'rebase --skip'.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/git-cherry-pick.txt |  1 +\n Documentation/git-revert.txt      |  1 +\n Documentation/sequencer.txt       |  3 +++\n builtin/revert.c                  |  6 ++++++\n sequencer.c                       | 32 +++++++++++++++++++++++++++++---\n sequencer.h                       |  3 ++-\n t/t3510-cherry-pick-sequence.sh   | 12 ++++++++++++\n 7 files changed, 54 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt\nindex da0bd81..d95c63c 100644\n--- a/Documentation/git-cherry-pick.txt\n+++ b/Documentation/git-cherry-pick.txt\n@@ -10,6 +10,7 @@ SYNOPSIS\n [verse]\n 'git cherry-pick' [-q] [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...\n 'git cherry-pick' --continue\n+'git cherry-pick' --skip\n 'git cherry-pick' --quit\n 'git cherry-pick' --abort\n \ndiff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt\nindex 98a8e7a..52e146e 100644\n--- a/Documentation/git-revert.txt\n+++ b/Documentation/git-revert.txt\n@@ -10,6 +10,7 @@ SYNOPSIS\n [verse]\n 'git revert' [-q] [--[no-]edit] [-n] [-m parent-number] [-s] <commit>...\n 'git revert' --continue\n+'git revert' --skip\n 'git revert' --quit\n 'git revert' --abort\n \ndiff --git a/Documentation/sequencer.txt b/Documentation/sequencer.txt\nindex 5747f44..df2d355 100644\n--- a/Documentation/sequencer.txt\n+++ b/Documentation/sequencer.txt\n@@ -3,6 +3,9 @@\n \t'.git/sequencer'.  Can be used to continue after resolving\n \tconflicts in a failed cherry-pick or revert.\n \n+--skip::\n+\tSkip the current commit, and then continue.\n+\n --quit::\n \tForget about the current operation in progress.  Can be used\n \tto clear the sequencer state after a failed cherry-pick or\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex ec83748..d3d5600 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -99,11 +99,13 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)\n \tint remove_state = 0;\n \tint contin = 0;\n \tint rollback = 0;\n+\tint skip = 0;\n \tstruct option options[] = {\n \t\tOPT__QUIET(&opts->quiet, N_(\"suppress progress reporting\")),\n \t\tOPT_BOOLEAN(0, \"quit\", &remove_state, N_(\"end revert or cherry-pick sequence\")),\n \t\tOPT_BOOLEAN(0, \"continue\", &contin, N_(\"resume revert or cherry-pick sequence\")),\n \t\tOPT_BOOLEAN(0, \"abort\", &rollback, N_(\"cancel revert or cherry-pick sequence\")),\n+\t\tOPT_BOOLEAN(0, \"skip\", &skip, N_(\"skip current commit in the sequence\")),\n \t\tOPT_BOOLEAN('n', \"no-commit\", &opts->no_commit, N_(\"don't automatically commit\")),\n \t\tOPT_BOOLEAN('e', \"edit\", &opts->edit, N_(\"edit the commit message\")),\n \t\tOPT_NOOP_NOARG('r', NULL),\n@@ -164,6 +166,8 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)\n \t\topts->subcommand = REPLAY_CONTINUE;\n \telse if (rollback)\n \t\topts->subcommand = REPLAY_ROLLBACK;\n+\telse if (skip)\n+\t\topts->subcommand = REPLAY_SKIP;\n \telse\n \t\topts->subcommand = REPLAY_NONE;\n \n@@ -174,6 +178,8 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)\n \t\t\tthis_operation = \"--quit\";\n \t\telse if (opts->subcommand == REPLAY_CONTINUE)\n \t\t\tthis_operation = \"--continue\";\n+\t\telse if (opts->subcommand == REPLAY_SKIP)\n+\t\t\tthis_operation = \"--skip\";\n \t\telse {\n \t\t\tassert(opts->subcommand == REPLAY_ROLLBACK);\n \t\t\tthis_operation = \"--abort\";\ndiff --git a/sequencer.c b/sequencer.c\nindex 4b91bd4..dd9de49 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -1181,7 +1181,9 @@ static int continue_single_pick(void)\n \treturn run_command_v_opt(argv, RUN_GIT_CMD);\n }\n \n-static int sequencer_continue(struct replay_opts *opts)\n+static void add_rewritten(unsigned char *from, unsigned char *to);\n+\n+static int sequencer_continue(struct replay_opts *opts, int skip)\n {\n \tstruct commit_list *todo_list = NULL;\n \n@@ -1201,7 +1203,7 @@ static int sequencer_continue(struct replay_opts *opts)\n \t}\n \tif (index_differs_from(\"HEAD\", 0))\n \t\treturn error_dirty_index(opts);\n-\tif (opts->action == REPLAY_PICK) {\n+\tif (opts->action == REPLAY_PICK && !skip) {\n \t\tunsigned char to[20];\n \t\tif (!read_ref(\"HEAD\", to))\n \t\t\tadd_rewritten(todo_list->item->object.sha1, to);\n@@ -1210,6 +1212,28 @@ static int sequencer_continue(struct replay_opts *opts)\n \treturn pick_commits(todo_list, opts);\n }\n \n+static int sequencer_skip(struct replay_opts *opts)\n+{\n+\tconst char *argv[4]; /* reset --hard HEAD + NULL */\n+\tstruct string_list merge_rr = STRING_LIST_INIT_DUP;\n+\tint ret;\n+\n+\tif (setup_rerere(&merge_rr, 0) >= 0) {\n+\t\trerere_clear(&merge_rr);\n+\t\tstring_list_clear(&merge_rr, 1);\n+\t}\n+\n+\targv[0] = \"reset\";\n+\targv[1] = \"--hard\";\n+\targv[2] = \"HEAD\";\n+\targv[3] = NULL;\n+\tret = run_command_v_opt(argv, RUN_GIT_CMD);\n+\tif (ret)\n+\t\treturn ret;\n+\n+\treturn sequencer_continue(opts, 1);\n+}\n+\n static int single_pick(struct commit *cmit, struct replay_opts *opts)\n {\n \tint ret;\n@@ -1244,7 +1268,9 @@ int sequencer_pick_revisions(struct replay_opts *opts)\n \tif (opts->subcommand == REPLAY_ROLLBACK)\n \t\treturn sequencer_rollback(opts);\n \tif (opts->subcommand == REPLAY_CONTINUE)\n-\t\treturn sequencer_continue(opts);\n+\t\treturn sequencer_continue(opts, 0);\n+\tif (opts->subcommand == REPLAY_SKIP)\n+\t\treturn sequencer_skip(opts);\n \n \tfor (i = 0; i < opts->revs->pending.nr; i++) {\n \t\tunsigned char sha1[20];\ndiff --git a/sequencer.h b/sequencer.h\nindex 6fc416d..efec1b5 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -18,7 +18,8 @@ enum replay_subcommand {\n \tREPLAY_NONE,\n \tREPLAY_REMOVE_STATE,\n \tREPLAY_CONTINUE,\n-\tREPLAY_ROLLBACK\n+\tREPLAY_ROLLBACK,\n+\tREPLAY_SKIP\n };\n \n struct replay_opts {\ndiff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh\nindex 7b7a89d..f58a83d 100755\n--- a/t/t3510-cherry-pick-sequence.sh\n+++ b/t/t3510-cherry-pick-sequence.sh\n@@ -511,4 +511,16 @@ test_expect_success 'commit descriptions in insn sheet are optional' '\n \ttest_line_count = 4 commits\n '\n \n+test_expect_success 'skip' '\n+\tpristine_detach conflicting &&\n+\ttest_must_fail git cherry-pick initial..picked &&\n+\n+\tgit checkout HEAD -- unrelated &&\n+\ttest_must_fail git cherry-pick --continue &&\n+\tgit cherry-pick --skip &&\n+\n+\tgit rev-list initial..HEAD >commits &&\n+\ttest_line_count = 3 commits\n+'\n+\n test_done\n-- \n1.8.3.698.g079b096\n"},{"id":"219496","messageId":"1370509144-31974-10-git-send-email-felipe.contreras@gmail.com","threadId":"34039","inReplyTo":"1370509144-31974-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v3 9/9] cherry-pick: don't barf when there's nothing to do","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T08:59:04Z","receivedAt":"2013-06-06T08:59:04Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n sequencer.c | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex dd9de49..c3a17f8 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -754,8 +754,8 @@ static void prepare_revs(struct replay_opts *opts)\n \tif (prepare_revision_walk(opts->revs))\n \t\tdie(_(\"revision walk setup failed\"));\n \n-\tif (!opts->revs->commits)\n-\t\tdie(_(\"empty commit set passed\"));\n+\tif (!opts->revs->commits && !opts->quiet)\n+\t\terror(_(\"empty commit set passed\"));\n }\n \n static void read_and_refresh_cache(struct replay_opts *opts)\n-- \n1.8.3.698.g079b096\n"},{"id":"219502","messageId":"CAMP44s2Jo9A-Dr3S-Pcj6WQ8W4Wg9dLn_f-WGyVZ2Bp4JysBCw@mail.gmail.com","threadId":"34039","inReplyTo":"1370509144-31974-7-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v3 6/9] cherry-pick: add support to copy notes","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T12:17:56Z","receivedAt":"2013-06-06T12:17:56Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, Jun 6, 2013 at 3:59 AM, Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  sequencer.c | 33 +++++++++++++++++++++++++++++----\n>  1 file changed, 29 insertions(+), 4 deletions(-)\n>\n> diff --git a/sequencer.c b/sequencer.c\n> index 74480d7..6d13e63 100644\n> --- a/sequencer.c\n> +++ b/sequencer.c\n> @@ -14,6 +14,7 @@\n>  #include \"merge-recursive.h\"\n>  #include \"refs.h\"\n>  #include \"argv-array.h\"\n> +#include \"builtin.h\"\n>\n>  #define GIT_REFLOG_ACTION \"GIT_REFLOG_ACTION\"\n>\n> @@ -158,6 +159,32 @@ static void run_rewrite_hook(const char *name)\n>         finish_command(&proc);\n>  }\n>\n> +static void copy_notes(const char *name)\n> +{\n> +       struct notes_rewrite_cfg *cfg;\n> +       int i;\n> +\n> +       cfg = init_copy_notes_for_rewrite(name);\n> +       if (!cfg)\n> +               return;\n> +\n> +       for (i = 0; i < rewritten.nr; i++) {\n> +               struct rewritten_list_item *item = &rewritten.items[i];\n> +               copy_note_for_rewrite(cfg, item->from, item->to);\n> +       }\n> +\n> +       finish_copy_notes_for_rewrite(cfg);\n> +}\n\nUnfortunately this doesn't work, because all these functions are part\nof the builtins, not git lib.\n\n-- \nFelipe Contreras\n"},{"id":"219526","messageId":"7vbo7jytv5.fsf@alter.siamese.dyndns.org","threadId":"34039","inReplyTo":"1370509144-31974-4-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v3 3/9] cherry-pick: add --skip-empty option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-06-06T18:30:38Z","receivedAt":"2013-06-06T18:30:38Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> Pretty much what it says on the tin.\n\nAnd a bit more, isn't it?\n\nThe --keep-redundant-commits option implies the --allow-empty option\nand it was perfectly acceptable to give both.  By making sure that\nonly at most one of -k-r-d, -a-e or -s-e is given, this forbids that\nusage.\n\n\"It is implied so there is no *need* to give it redundantly\" is\ndifferent from \"It is implied so you shouldn't give it redundantly\".\n\nLike 7 and 8 that adds --quiet/--skip, don't we want this also for\nrevert?\n\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  Documentation/git-cherry-pick.txt   |  3 +++\n>  builtin/revert.c                    |  8 ++++++++\n>  sequencer.c                         |  6 ++++++\n>  sequencer.h                         |  1 +\n>  t/t3508-cherry-pick-many-commits.sh | 13 +++++++++++++\n>  5 files changed, 31 insertions(+)\n>\n> diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt\n> index c205d23..fccd936 100644\n> --- a/Documentation/git-cherry-pick.txt\n> +++ b/Documentation/git-cherry-pick.txt\n> @@ -129,6 +129,9 @@ effect to your index in a row.\n>  \tredundant commits are ignored.  This option overrides that behavior and\n>  \tcreates an empty commit object.  Implies `--allow-empty`.\n>  \n> +--skip-empty::\n> +\tInstead of failing, skip commits that are or become empty.\n> +\n>  --strategy=<strategy>::\n>  \tUse the given merge strategy.  Should only be used once.\n>  \tSee the MERGE STRATEGIES section in linkgit:git-merge[1]\n> diff --git a/builtin/revert.c b/builtin/revert.c\n> index 0401fdb..5a8453d 100644\n> --- a/builtin/revert.c\n> +++ b/builtin/revert.c\n> @@ -118,6 +118,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)\n>  \t\tOPT_END(),\n>  \t\tOPT_END(),\n>  \t\tOPT_END(),\n> +\t\tOPT_END(),\n>  \t};\n>  \n>  \tif (opts->action == REPLAY_PICK) {\n> @@ -127,6 +128,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)\n>  \t\t\tOPT_BOOLEAN(0, \"allow-empty\", &opts->allow_empty, N_(\"preserve initially empty commits\")),\n>  \t\t\tOPT_BOOLEAN(0, \"allow-empty-message\", &opts->allow_empty_message, N_(\"allow commits with empty messages\")),\n>  \t\t\tOPT_BOOLEAN(0, \"keep-redundant-commits\", &opts->keep_redundant_commits, N_(\"keep redundant, empty commits\")),\n> +\t\t\tOPT_BOOLEAN(0, \"skip-empty\", &opts->skip_empty, N_(\"skip empty commits\")),\n>  \t\t\tOPT_END(),\n>  \t\t};\n>  \t\tif (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))\n> @@ -144,6 +146,12 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)\n>  \t\t\t\t\"--abort\", rollback,\n>  \t\t\t\tNULL);\n>  \n> +\tverify_opt_mutually_compatible(me,\n> +\t\t\t\t\"--allow-empty\", opts->allow_empty,\n> +\t\t\t\t\"--skip-empty\", opts->skip_empty,\n> +\t\t\t\t\"--keep-redundant-commits\", opts->keep_redundant_commits,\n> +\t\t\t\tNULL);\n> +\n>  \t/* implies allow_empty */\n>  \tif (opts->keep_redundant_commits)\n>  \t\topts->allow_empty = 1;\n> diff --git a/sequencer.c b/sequencer.c\n> index f7be7d8..d3c7d72 100644\n> --- a/sequencer.c\n> +++ b/sequencer.c\n> @@ -627,6 +627,12 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)\n>  \t\tgoto leave;\n>  \t}\n>  \n> +\tif (opts->skip_empty && is_index_unchanged() == 1) {\n> +\t\twarning(_(\"skipping %s... %s\"),\n> +\t\t\tfind_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),\n> +\t\t\tmsg.subject);\n> +\t\tgoto leave;\n> +\t}\n>  \tallow = allow_empty(opts, commit);\n>  \tif (allow < 0) {\n>  \t\tres = allow;\n> diff --git a/sequencer.h b/sequencer.h\n> index 1fc22dc..3b04844 100644\n> --- a/sequencer.h\n> +++ b/sequencer.h\n> @@ -34,6 +34,7 @@ struct replay_opts {\n>  \tint allow_empty;\n>  \tint allow_empty_message;\n>  \tint keep_redundant_commits;\n> +\tint skip_empty;\n>  \n>  \tint mainline;\n>  \n> diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh\n> index 19c99d7..3dc19c6 100755\n> --- a/t/t3508-cherry-pick-many-commits.sh\n> +++ b/t/t3508-cherry-pick-many-commits.sh\n> @@ -187,4 +187,17 @@ test_expect_success 'cherry-pick --stdin works' '\n>  \tcheck_head_differs_from fourth\n>  '\n>  \n> +test_expect_success 'cherry-pick skip empty' '\n> +\tgit clean -fxd &&\n> +\tgit checkout -b empty fourth &&\n> +\tgit commit --allow-empty -m empty &&\n> +\ttest_commit ontop &&\n> +\tgit checkout -f master &&\n> +\tgit reset --hard fourth &&\n> +\tgit cherry-pick --skip-empty fourth..empty &&\n> +\techo ontop > expected &&\n> +\tgit log --format=%s fourth..HEAD > actual\n> +\ttest_cmp expected actual\n> +'\n> +\n>  test_done\n"},{"id":"219528","messageId":"CAMP44s3b2K0nbfuhNqB6FNevdPjVByQCpAie5nzAjx8bw5Y+RQ@mail.gmail.com","threadId":"34039","inReplyTo":"7vbo7jytv5.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 3/9] cherry-pick: add --skip-empty option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-06T18:34:55Z","receivedAt":"2013-06-06T18:34:55Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, Jun 6, 2013 at 1:30 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>> Pretty much what it says on the tin.\n>\n> And a bit more, isn't it?\n>\n> The --keep-redundant-commits option implies the --allow-empty option\n> and it was perfectly acceptable to give both.  By making sure that\n> only at most one of -k-r-d, -a-e or -s-e is given, this forbids that\n> usage.\n>\n> \"It is implied so there is no *need* to give it redundantly\" is\n> different from \"It is implied so you shouldn't give it redundantly\".\n\nRemove that line then.\n\n> Like 7 and 8 that adds --quiet/--skip, don't we want this also for\n> revert?\n\nIf we don't want --allow-empty in revert, we don't want --skip-empty\neither. That is a separate patch.\n\n-- \nFelipe Contreras\n"},{"id":"219529","messageId":"7v7gi7yteu.fsf@alter.siamese.dyndns.org","threadId":"34039","inReplyTo":"1370509144-31974-6-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v3 5/9] sequencer: run post-rewrite hook","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-06-06T18:40:25Z","receivedAt":"2013-06-06T18:40:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> As we should.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n>  sequencer.c | 42 +++++++++++++++++++++++++++++++++++++++++-\n>  1 file changed, 41 insertions(+), 1 deletion(-)\n>\n> diff --git a/sequencer.c b/sequencer.c\n> index 76ff2ff..74480d7 100644\n> --- a/sequencer.c\n> +++ b/sequencer.c\n> @@ -127,6 +127,37 @@ static void add_rewritten(unsigned char *from, unsigned char *to)\n>  \trewritten.nr++;\n>  }\n>  \n> +static void run_rewrite_hook(const char *name)\n> +{\n> +\tstruct strbuf buf = STRBUF_INIT;\n> +\tstruct child_process proc;\n> +\tconst char *argv[3];\n> +\tint code, i;\n> +\n> +\targv[0] = find_hook(\"post-rewrite\");\n> +\tif (!argv[0])\n> +\t\treturn;\n> +\n> +\targv[1] = name;\n> +\targv[2] = NULL;\n> +\n> +\tmemset(&proc, 0, sizeof(proc));\n> +\tproc.argv = argv;\n> +\tproc.in = -1;\n> +\tproc.stdout_to_stderr = 1;\n> +\n> +\tcode = start_command(&proc);\n> +\tif (code)\n> +\t\treturn;\n> +\tfor (i = 0; i < rewritten.nr; i++) {\n> +\t\tstruct rewritten_list_item *item = &rewritten.items[i];\n> +\t\tstrbuf_addf(&buf, \"%s %s\\n\", sha1_to_hex(item->from), sha1_to_hex(item->to));\n> +\t}\n> +\twrite_in_full(proc.in, buf.buf, buf.len);\n> +\tclose(proc.in);\n> +\tfinish_command(&proc);\n> +}\n\nIt probably is worth inserting a commit before 4/9 that adds\nrewrite.[ch], and\n\n - introduces \"struct rewritten_list[_item]\";\n\n - moves run_rewrite_hook() in builtin/commit.c to rewrite.c;\n\n - changes its function signature so that it takes \"char\n   *action_name\" and \"struct rewritten *\" as parameters; and\n\n - adjust its sole call site in cmd_commit() to feed a single-item\n   rewritten_list to it.\n\nThen 4/9 can teach cherry-pick to prepare the rewritten-list and\nprobably this commit can be part of that to call run_rewrite_hook().\n"},{"id":"219531","messageId":"7v38svyriv.fsf@alter.siamese.dyndns.org","threadId":"34039","inReplyTo":"CAMP44s3b2K0nbfuhNqB6FNevdPjVByQCpAie5nzAjx8bw5Y+RQ@mail.gmail.com","subject":"Re: [PATCH v3 3/9] cherry-pick: add --skip-empty option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-06-06T19:21:12Z","receivedAt":"2013-06-06T19:21:12Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> On Thu, Jun 6, 2013 at 1:30 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>>\n>>> Pretty much what it says on the tin.\n>>\n>> And a bit more, isn't it?\n>>\n>> The --keep-redundant-commits option implies the --allow-empty option\n>> and it was perfectly acceptable to give both.  By making sure that\n>> only at most one of -k-r-d, -a-e or -s-e is given, this forbids that\n>> usage.\n>>\n>> \"It is implied so there is no *need* to give it redundantly\" is\n>> different from \"It is implied so you shouldn't give it redundantly\".\n>\n> Remove that line then.\n>\n>> Like 7 and 8 that adds --quiet/--skip, don't we want this also for\n>> revert?\n>\n> If we don't want --allow-empty in revert, we don't want --skip-empty\n> either. That is a separate patch.\n\nOK.\n"},{"id":"219532","messageId":"7vy5anxcxt.fsf@alter.siamese.dyndns.org","threadId":"34039","inReplyTo":"CAMP44s3b2K0nbfuhNqB6FNevdPjVByQCpAie5nzAjx8bw5Y+RQ@mail.gmail.com","subject":"Re: [PATCH v3 3/9] cherry-pick: add --skip-empty option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-06-06T19:21:34Z","receivedAt":"2013-06-06T19:21:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> On Thu, Jun 6, 2013 at 1:30 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>>\n>>> Pretty much what it says on the tin.\n>>\n>> And a bit more, isn't it?\n>>\n>> The --keep-redundant-commits option implies the --allow-empty option\n>> and it was perfectly acceptable to give both.  By making sure that\n>> only at most one of -k-r-d, -a-e or -s-e is given, this forbids that\n>> usage.\n>>\n>> \"It is implied so there is no *need* to give it redundantly\" is\n>> different from \"It is implied so you shouldn't give it redundantly\".\n>\n> Remove that line then.\n\nThat's what the submitter does.\n\nThanks.\n"},{"id":"219697","messageId":"CAMP44s05QSfR8DqbYtujo5ODfFkm0XFicH33hVF9L_dyC5=ieQ@mail.gmail.com","threadId":"34039","inReplyTo":"7vy5anxcxt.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 3/9] cherry-pick: add --skip-empty option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-07T20:28:10Z","receivedAt":"2013-06-07T20:28:10Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, Jun 6, 2013 at 2:21 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>> On Thu, Jun 6, 2013 at 1:30 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>>>\n>>>> Pretty much what it says on the tin.\n>>>\n>>> And a bit more, isn't it?\n>>>\n>>> The --keep-redundant-commits option implies the --allow-empty option\n>>> and it was perfectly acceptable to give both.  By making sure that\n>>> only at most one of -k-r-d, -a-e or -s-e is given, this forbids that\n>>> usage.\n>>>\n>>> \"It is implied so there is no *need* to give it redundantly\" is\n>>> different from \"It is implied so you shouldn't give it redundantly\".\n>>\n>> Remove that line then.\n>\n> That's what the submitter does.\n\nApparently \"the submitter\" does everything. It seems sending 800\npatches in the past 3 months is not enough work for you.\n\nAnd what's the point? If nobody is interested in shifting from shell\nscripts to C, neither am I.\n\nConsider this series abandoned.\n\n-- \nFelipe Contreras\n"},{"id":"219964","messageId":"CAMP44s1-d4XrKjy7dcLq=6jDeOGaj=TL0MQa9FdEHgXmRVQr=Q@mail.gmail.com","threadId":"34039","inReplyTo":"7v7gi7yteu.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v3 5/9] sequencer: run post-rewrite hook","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-06-09T15:19:03Z","receivedAt":"2013-06-09T15:19:03Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Thu, Jun 6, 2013 at 1:40 PM, Junio C Hamano <gitster@pobox.com> wrote:\n\n> It probably is worth inserting a commit before 4/9 that adds\n> rewrite.[ch], and\n>\n>  - introduces \"struct rewritten_list[_item]\";\n>\n>  - moves run_rewrite_hook() in builtin/commit.c to rewrite.c;\n>\n>  - changes its function signature so that it takes \"char\n>    *action_name\" and \"struct rewritten *\" as parameters; and\n>\n>  - adjust its sole call site in cmd_commit() to feed a single-item\n>    rewritten_list to it.\n>\n> Then 4/9 can teach cherry-pick to prepare the rewritten-list and\n> probably this commit can be part of that to call run_rewrite_hook().\n\nDone. I'll send the patches in a moment.\n\n-- \nFelipe Contreras\n"}]}