{"thread":{"id":"23976","subject":"[PATCH v2 0/8] implement cherry-picking many commits","startedAt":"2010-06-02T05:58:33Z","lastAt":"2010-06-02T05:58:41Z","messageCount":9,"participants":["Christian Couder"],"isPatch":true,"patchVersion":2,"patchTotal":8},"messages":[{"id":"142775","messageId":"20100602055131.21504.71923.chriscool@tuxfamily.org","threadId":"23976","inReplyTo":null,"subject":"[PATCH v2 0/8] implement cherry-picking many commits","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2010-06-02T05:58:33Z","receivedAt":"2010-06-02T05:58:33Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This a patch series to implement cherry-picking and reverting\nmany commits instead of just one.\n\nThere is still no way to continue or abort the process when\ncherry-picking or reverting fails, but this can be implemented\nlater.\n\nChanges since the previous series are the following:\n- fixed some memory leaks, thanks to Jonathan Nieder\n- improved documentation, thanks to Jonathan, Ram and Antriksh\n- small fixup to use (void) instead of (), thanks to Junio\n\nChristian Couder (8):\n  revert: cleanup code for -x option\n  revert: use run_command_v_opt() instead of execv_git_cmd()\n  revert: refactor code into a do_pick_commit() function\n  revert: change help_msg() to take no argument\n  revert: allow cherry-picking more than one commit\n  revert: add tests to check cherry-picking many commits\n  Documentation/cherry-pick: describe passing more than one commit\n  Documentation/revert: describe passing more than one commit\n\n Documentation/git-cherry-pick.txt   |   64 +++++++++++++++---\n Documentation/git-revert.txt        |   51 +++++++++++----\n builtin/revert.c                    |  120 +++++++++++++++++++++++------------\n t/t3508-cherry-pick-many-commits.sh |   95 +++++++++++++++++++++++++++\n 4 files changed, 264 insertions(+), 66 deletions(-)\n create mode 100755 t/t3508-cherry-pick-many-commits.sh\n"},{"id":"142776","messageId":"20100602055842.21504.54618.chriscool@tuxfamily.org","threadId":"23976","inReplyTo":"20100602055131.21504.71923.chriscool@tuxfamily.org","subject":"[PATCH v2 1/8] revert: cleanup code for -x option","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2010-06-02T05:58:34Z","receivedAt":"2010-06-02T05:58:34Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"There was some dead code and option -x appeared in the short\nhelp message of git revert (when running \"git revert -h\")\nwhich was wrong.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/revert.c |    8 +-------\n 1 files changed, 1 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex 7976b5a..5df0d69 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -58,7 +58,6 @@ static void parse_args(int argc, const char **argv)\n \tstruct option options[] = {\n \t\tOPT_BOOLEAN('n', \"no-commit\", &no_commit, \"don't automatically commit\"),\n \t\tOPT_BOOLEAN('e', \"edit\", &edit, \"edit the commit message\"),\n-\t\tOPT_BOOLEAN('x', NULL, &no_replay, \"append commit name when cherry-picking\"),\n \t\tOPT_BOOLEAN('r', NULL, &noop, \"no-op (backward compatibility)\"),\n \t\tOPT_BOOLEAN('s', \"signoff\", &signoff, \"add Signed-off-by:\"),\n \t\tOPT_INTEGER('m', \"mainline\", &mainline, \"parent number\"),\n@@ -71,6 +70,7 @@ static void parse_args(int argc, const char **argv)\n \n \tif (action == CHERRY_PICK) {\n \t\tstruct option cp_extra[] = {\n+\t\t\tOPT_BOOLEAN('x', NULL, &no_replay, \"append commit name\"),\n \t\t\tOPT_BOOLEAN(0, \"ff\", &allow_ff, \"allow fast-forward\"),\n \t\t\tOPT_END(),\n \t\t};\n@@ -379,10 +379,6 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n \tsetenv(GIT_REFLOG_ACTION, me, 0);\n \tparse_args(argc, argv);\n \n-\t/* this is copied from the shell script, but it's never triggered... */\n-\tif (action == REVERT && !no_replay)\n-\t\tdie(\"revert is incompatible with replay\");\n-\n \tif (allow_ff) {\n \t\tif (signoff)\n \t\t\tdie(\"cherry-pick --ff cannot be used with --signoff\");\n@@ -546,14 +542,12 @@ int cmd_revert(int argc, const char **argv, const char *prefix)\n {\n \tif (isatty(0))\n \t\tedit = 1;\n-\tno_replay = 1;\n \taction = REVERT;\n \treturn revert_or_cherry_pick(argc, argv);\n }\n \n int cmd_cherry_pick(int argc, const char **argv, const char *prefix)\n {\n-\tno_replay = 0;\n \taction = CHERRY_PICK;\n \treturn revert_or_cherry_pick(argc, argv);\n }\n-- \n1.7.1.362.g8d752\n"},{"id":"142777","messageId":"20100602055842.21504.65497.chriscool@tuxfamily.org","threadId":"23976","inReplyTo":"20100602055131.21504.71923.chriscool@tuxfamily.org","subject":"[PATCH v2 2/8] revert: use run_command_v_opt() instead of execv_git_cmd()","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2010-06-02T05:58:35Z","receivedAt":"2010-06-02T05:58:35Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This is needed by the following commits, because we are going\nto cherry pick many commits instead of just one.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/revert.c |   11 +++++++++--\n 1 files changed, 9 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex 5df0d69..02f18c2 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -508,6 +508,8 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n \t\t}\n \t}\n \n+\tfree_message(&msg);\n+\n \t/*\n \t *\n \t * If we are cherry-pick, and if the merge did not result in\n@@ -520,7 +522,9 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n \tif (!no_commit) {\n \t\t/* 6 is max possible length of our args array including NULL */\n \t\tconst char *args[6];\n+\t\tint res;\n \t\tint i = 0;\n+\n \t\targs[i++] = \"commit\";\n \t\targs[i++] = \"-n\";\n \t\tif (signoff)\n@@ -530,9 +534,12 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n \t\t\targs[i++] = defmsg;\n \t\t}\n \t\targs[i] = NULL;\n-\t\treturn execv_git_cmd(args);\n+\t\tres = run_command_v_opt(args, RUN_GIT_CMD);\n+\t\tfree(defmsg);\n+\n+\t\treturn res;\n \t}\n-\tfree_message(&msg);\n+\n \tfree(defmsg);\n \n \treturn 0;\n-- \n1.7.1.362.g8d752\n"},{"id":"142778","messageId":"20100602055842.21504.23768.chriscool@tuxfamily.org","threadId":"23976","inReplyTo":"20100602055131.21504.71923.chriscool@tuxfamily.org","subject":"[PATCH v2 3/8] revert: refactor code into a do_pick_commit() function","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2010-06-02T05:58:36Z","receivedAt":"2010-06-02T05:58:36Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This is needed because we are going to make it possible\nto cherry-pick many commits instead of just one in the following\ncommits. And we will be able to do that by just calling\ndo_pick_commit() once for each commit to cherry-pick.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/revert.c |   44 +++++++++++++++++++++++++-------------------\n 1 files changed, 25 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex 02f18c2..c2aee86 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -365,7 +365,7 @@ static void do_recursive_merge(struct commit *base, struct commit *next,\n \tfprintf(stderr, \"Finished one %s.\\n\", me);\n }\n \n-static int revert_or_cherry_pick(int argc, const char **argv)\n+static int do_pick_commit(void)\n {\n \tunsigned char head[20];\n \tstruct commit *base, *next, *parent;\n@@ -374,24 +374,6 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n \tchar *defmsg = NULL;\n \tstruct strbuf msgbuf = STRBUF_INIT;\n \n-\tgit_config(git_default_config, NULL);\n-\tme = action == REVERT ? \"revert\" : \"cherry-pick\";\n-\tsetenv(GIT_REFLOG_ACTION, me, 0);\n-\tparse_args(argc, argv);\n-\n-\tif (allow_ff) {\n-\t\tif (signoff)\n-\t\t\tdie(\"cherry-pick --ff cannot be used with --signoff\");\n-\t\tif (no_commit)\n-\t\t\tdie(\"cherry-pick --ff cannot be used with --no-commit\");\n-\t\tif (no_replay)\n-\t\t\tdie(\"cherry-pick --ff cannot be used with -x\");\n-\t\tif (edit)\n-\t\t\tdie(\"cherry-pick --ff cannot be used with --edit\");\n-\t}\n-\n-\tif (read_cache() < 0)\n-\t\tdie(\"git %s: failed to read the index\", me);\n \tif (no_commit) {\n \t\t/*\n \t\t * We do not intend to commit immediately.  We just want to\n@@ -545,6 +527,30 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n \treturn 0;\n }\n \n+static int revert_or_cherry_pick(int argc, const char **argv)\n+{\n+\tgit_config(git_default_config, NULL);\n+\tme = action == REVERT ? \"revert\" : \"cherry-pick\";\n+\tsetenv(GIT_REFLOG_ACTION, me, 0);\n+\tparse_args(argc, argv);\n+\n+\tif (allow_ff) {\n+\t\tif (signoff)\n+\t\t\tdie(\"cherry-pick --ff cannot be used with --signoff\");\n+\t\tif (no_commit)\n+\t\t\tdie(\"cherry-pick --ff cannot be used with --no-commit\");\n+\t\tif (no_replay)\n+\t\t\tdie(\"cherry-pick --ff cannot be used with -x\");\n+\t\tif (edit)\n+\t\t\tdie(\"cherry-pick --ff cannot be used with --edit\");\n+\t}\n+\n+\tif (read_cache() < 0)\n+\t\tdie(\"git %s: failed to read the index\", me);\n+\n+\treturn do_pick_commit();\n+}\n+\n int cmd_revert(int argc, const char **argv, const char *prefix)\n {\n \tif (isatty(0))\n-- \n1.7.1.362.g8d752\n"},{"id":"142779","messageId":"20100602055842.21504.19150.chriscool@tuxfamily.org","threadId":"23976","inReplyTo":"20100602055131.21504.71923.chriscool@tuxfamily.org","subject":"[PATCH v2 4/8] revert: change help_msg() to take no argument","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2010-06-02T05:58:37Z","receivedAt":"2010-06-02T05:58:37Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This is needed because the following commits will make it\npossible to cherry-pick many commits instead of just one.\n\nSo it will be possible to pass for example ranges of commits\nto \"git cherry-pick\" and this means that it will not be\npossible to use the arguments passed to \"git cherry-pick\" in\nthe help message.\n\nThe help message will have to use the sha1 of the currently\nprocessed commit.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/revert.c |    8 ++++----\n 1 files changed, 4 insertions(+), 4 deletions(-)\n\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex c2aee86..aee1069 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -239,7 +239,7 @@ static void set_author_ident_env(const char *message)\n \t\t\tsha1_to_hex(commit->object.sha1));\n }\n \n-static char *help_msg(const char *name)\n+static char *help_msg(void)\n {\n \tstruct strbuf helpbuf = STRBUF_INIT;\n \tchar *msg = getenv(\"GIT_CHERRY_PICK_HELP\");\n@@ -255,7 +255,7 @@ static char *help_msg(const char *name)\n \t\tstrbuf_addf(&helpbuf, \" with: \\n\"\n \t\t\t\"\\n\"\n \t\t\t\"        git commit -c %s\\n\",\n-\t\t\tname);\n+\t\t\t    sha1_to_hex(commit->object.sha1));\n \t}\n \telse\n \t\tstrbuf_addch(&helpbuf, '.');\n@@ -357,7 +357,7 @@ static void do_recursive_merge(struct commit *base, struct commit *next,\n \t\t}\n \t\twrite_message(msgbuf, defmsg);\n \t\tfprintf(stderr, \"Automatic %s failed.%s\\n\",\n-\t\t\tme, help_msg(commit_name));\n+\t\t\tme, help_msg());\n \t\trerere(allow_rerere_auto);\n \t\texit(1);\n \t}\n@@ -484,7 +484,7 @@ static int do_pick_commit(void)\n \t\tfree_commit_list(remotes);\n \t\tif (res) {\n \t\t\tfprintf(stderr, \"Automatic %s with strategy %s failed.%s\\n\",\n-\t\t\t\tme, strategy, help_msg(commit_name));\n+\t\t\t\tme, strategy, help_msg());\n \t\t\trerere(allow_rerere_auto);\n \t\t\texit(1);\n \t\t}\n-- \n1.7.1.362.g8d752\n"},{"id":"142780","messageId":"20100602055842.21504.24197.chriscool@tuxfamily.org","threadId":"23976","inReplyTo":"20100602055131.21504.71923.chriscool@tuxfamily.org","subject":"[PATCH v2 5/8] revert: allow cherry-picking more than one commit","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2010-06-02T05:58:38Z","receivedAt":"2010-06-02T05:58:38Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"This makes it possible to pass many commits or ranges of\ncommits to \"git cherry-pick\" and to \"git revert\" to process\nmany commits instead of just one.\n\nIn fact commits are now enumerated with an equivalent of\n\n\tgit rev-list --no-walk \"$@\"\n\nso all the following are now possible:\n\n\tgit cherry-pick master~2..master\n\tgit cherry-pick ^master~2 master\n\tgit cherry-pick master^ master\n\nThe following should be possible but does not work:\n\n\tgit cherry-pick -2 master\n\nbecause \"git rev-list --no-walk -2 master\" only outputs\none commit as \"--no-walk\" seems to take over \"-2\".\n\nAnd there is currently no way to continue cherry-picking or\nreverting if there is a problem with one commit. It's also\nnot possible to abort the whole process. Some future work\nshould provide the --continue and --abort options to do\njust that.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n builtin/revert.c |   51 +++++++++++++++++++++++++++++++++++++++++----------\n 1 files changed, 41 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/revert.c b/builtin/revert.c\nindex aee1069..853e9e4 100644\n--- a/builtin/revert.c\n+++ b/builtin/revert.c\n@@ -39,7 +39,8 @@ static const char * const cherry_pick_usage[] = {\n static int edit, no_replay, no_commit, mainline, signoff, allow_ff;\n static enum { REVERT, CHERRY_PICK } action;\n static struct commit *commit;\n-static const char *commit_name;\n+static int commit_argc;\n+static const char **commit_argv;\n static int allow_rerere_auto;\n \n static const char *me;\n@@ -53,7 +54,6 @@ static void parse_args(int argc, const char **argv)\n {\n \tconst char * const * usage_str =\n \t\taction == REVERT ?  revert_usage : cherry_pick_usage;\n-\tunsigned char sha1[20];\n \tint noop;\n \tstruct option options[] = {\n \t\tOPT_BOOLEAN('n', \"no-commit\", &no_commit, \"don't automatically commit\"),\n@@ -78,15 +78,11 @@ static void parse_args(int argc, const char **argv)\n \t\t\tdie(\"program error\");\n \t}\n \n-\tif (parse_options(argc, argv, NULL, options, usage_str, 0) != 1)\n+\tcommit_argc = parse_options(argc, argv, NULL, options, usage_str, 0);\n+\tif (commit_argc < 1)\n \t\tusage_with_options(usage_str, options);\n \n-\tcommit_name = argv[0];\n-\tif (get_sha1(commit_name, sha1))\n-\t\tdie (\"Cannot find '%s'\", commit_name);\n-\tcommit = lookup_commit_reference(sha1);\n-\tif (!commit)\n-\t\texit(1);\n+\tcommit_argv = argv;\n }\n \n struct commit_message {\n@@ -527,8 +523,35 @@ static int do_pick_commit(void)\n \treturn 0;\n }\n \n+static void prepare_revs(struct rev_info *revs)\n+{\n+\tint argc = 0;\n+\tint i;\n+\tconst char **argv = xmalloc((commit_argc + 4) * sizeof(*argv));\n+\n+\targv[argc++] = NULL;\n+\targv[argc++] = \"--no-walk\";\n+\tif (action != REVERT)\n+\t\targv[argc++] = \"--reverse\";\n+\tfor (i = 0; i < commit_argc; i++)\n+\t\targv[argc++] = commit_argv[i];\n+\targv[argc++] = NULL;\n+\n+\tinit_revisions(revs, NULL);\n+\tsetup_revisions(argc - 1, argv, revs, NULL);\n+\tif (prepare_revision_walk(revs))\n+\t\tdie(\"revision walk setup failed\");\n+\n+\tif (!revs->commits)\n+\t\tdie(\"empty commit set passed\");\n+\n+\tfree(argv);\n+}\n+\n static int revert_or_cherry_pick(int argc, const char **argv)\n {\n+\tstruct rev_info revs;\n+\n \tgit_config(git_default_config, NULL);\n \tme = action == REVERT ? \"revert\" : \"cherry-pick\";\n \tsetenv(GIT_REFLOG_ACTION, me, 0);\n@@ -548,7 +571,15 @@ static int revert_or_cherry_pick(int argc, const char **argv)\n \tif (read_cache() < 0)\n \t\tdie(\"git %s: failed to read the index\", me);\n \n-\treturn do_pick_commit();\n+\tprepare_revs(&revs);\n+\n+\twhile ((commit = get_revision(&revs))) {\n+\t\tint res = do_pick_commit();\n+\t\tif (res)\n+\t\t\treturn res;\n+\t}\n+\n+\treturn 0;\n }\n \n int cmd_revert(int argc, const char **argv, const char *prefix)\n-- \n1.7.1.362.g8d752\n"},{"id":"142781","messageId":"20100602055842.21504.76127.chriscool@tuxfamily.org","threadId":"23976","inReplyTo":"20100602055131.21504.71923.chriscool@tuxfamily.org","subject":"[PATCH v2 6/8] revert: add tests to check cherry-picking many commits","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2010-06-02T05:58:39Z","receivedAt":"2010-06-02T05:58:39Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Note that there is an expected failure when running:\n\n\tgit cherry-pick -3 fourth\n\nthat's because:\n\n\tgit rev-list --no-walk -3 fourth\n\nproduce only one commit and not 3 as \"--no-walk\" seems to\ntake over \"-3\".\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n t/t3508-cherry-pick-many-commits.sh |   95 +++++++++++++++++++++++++++++++++++\n 1 files changed, 95 insertions(+), 0 deletions(-)\n create mode 100755 t/t3508-cherry-pick-many-commits.sh\n\ndiff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh\nnew file mode 100755\nindex 0000000..3b87efe\n--- /dev/null\n+++ b/t/t3508-cherry-pick-many-commits.sh\n@@ -0,0 +1,95 @@\n+#!/bin/sh\n+\n+test_description='test cherry-picking many commits'\n+\n+. ./test-lib.sh\n+\n+test_expect_success setup '\n+\techo first > file1 &&\n+\tgit add file1 &&\n+\ttest_tick &&\n+\tgit commit -m \"first\" &&\n+\tgit tag first &&\n+\n+\tgit checkout -b other &&\n+\tfor val in second third fourth\n+\tdo\n+\t\techo $val >> file1 &&\n+\t\tgit add file1 &&\n+\t\ttest_tick &&\n+\t\tgit commit -m \"$val\" &&\n+\t\tgit tag $val\n+\tdone\n+'\n+\n+test_expect_success 'cherry-pick first..fourth works' '\n+\tgit checkout master &&\n+\tgit reset --hard first &&\n+\ttest_tick &&\n+\tgit cherry-pick first..fourth &&\n+\tgit diff --quiet other &&\n+\tgit diff --quiet HEAD other &&\n+\ttest \"$(git rev-parse --verify HEAD)\" != \"$(git rev-parse --verify fourth)\"\n+'\n+\n+test_expect_success 'cherry-pick --ff first..fourth works' '\n+\tgit checkout master &&\n+\tgit reset --hard first &&\n+\ttest_tick &&\n+\tgit cherry-pick --ff first..fourth &&\n+\tgit diff --quiet other &&\n+\tgit diff --quiet HEAD other &&\n+\ttest \"$(git rev-parse --verify HEAD)\" = \"$(git rev-parse --verify fourth)\"\n+'\n+\n+test_expect_success 'cherry-pick -n first..fourth works' '\n+\tgit checkout master &&\n+\tgit reset --hard first &&\n+\ttest_tick &&\n+\tgit cherry-pick -n first..fourth &&\n+\tgit diff --quiet other &&\n+\tgit diff --cached --quiet other &&\n+\tgit diff --quiet HEAD first\n+'\n+\n+test_expect_success 'revert first..fourth works' '\n+\tgit checkout master &&\n+\tgit reset --hard fourth &&\n+\ttest_tick &&\n+\tgit revert first..fourth &&\n+\tgit diff --quiet first &&\n+\tgit diff --cached --quiet first &&\n+\tgit diff --quiet HEAD first\n+'\n+\n+test_expect_success 'revert ^first fourth works' '\n+\tgit checkout master &&\n+\tgit reset --hard fourth &&\n+\ttest_tick &&\n+\tgit revert ^first fourth &&\n+\tgit diff --quiet first &&\n+\tgit diff --cached --quiet first &&\n+\tgit diff --quiet HEAD first\n+'\n+\n+test_expect_success 'revert fourth fourth~1 fourth~2 works' '\n+\tgit checkout master &&\n+\tgit reset --hard fourth &&\n+\ttest_tick &&\n+\tgit revert fourth fourth~1 fourth~2 &&\n+\tgit diff --quiet first &&\n+\tgit diff --cached --quiet first &&\n+\tgit diff --quiet HEAD first\n+'\n+\n+test_expect_failure 'cherry-pick -3 fourth works' '\n+\tgit checkout master &&\n+\tgit reset --hard first &&\n+\ttest_tick &&\n+\tgit cherry-pick -3 fourth &&\n+\tgit diff --quiet other &&\n+\tgit diff --quiet HEAD other &&\n+\ttest \"$(git rev-parse --verify HEAD)\" != \"$(git rev-parse --verify fourth)\"\n+'\n+\n+test_done\n-- \n1.7.1.362.g8d752\n"},{"id":"142782","messageId":"20100602055842.21504.3914.chriscool@tuxfamily.org","threadId":"23976","inReplyTo":"20100602055131.21504.71923.chriscool@tuxfamily.org","subject":"[PATCH v2 7/8] Documentation/cherry-pick: describe passing more than one commit","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2010-06-02T05:58:40Z","receivedAt":"2010-06-02T05:58:40Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"And while at it, add an \"EXAMPLES\" section.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n Documentation/git-cherry-pick.txt |   64 ++++++++++++++++++++++++++++++------\n 1 files changed, 53 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt\nindex d71607a..bcb4c75 100644\n--- a/Documentation/git-cherry-pick.txt\n+++ b/Documentation/git-cherry-pick.txt\n@@ -3,24 +3,28 @@ git-cherry-pick(1)\n \n NAME\n ----\n-git-cherry-pick - Apply the change introduced by an existing commit\n+git-cherry-pick - Apply the changes introduced by some existing commits\n \n SYNOPSIS\n --------\n-'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>\n+'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...\n \n DESCRIPTION\n -----------\n-Given one existing commit, apply the change the patch introduces, and record a\n-new commit that records it.  This requires your working tree to be clean (no\n-modifications from the HEAD commit).\n+\n+Given one or more existing commits, apply the change each one\n+introduces, recording a new commit for each.  This requires your\n+working tree to be clean (no modifications from the HEAD commit).\n \n OPTIONS\n -------\n-<commit>::\n-\tCommit to cherry-pick.\n+<commit>...::\n+\tCommits to cherry-pick.\n \tFor a more complete list of ways to spell commits, see the\n \t\"SPECIFYING REVISIONS\" section in linkgit:git-rev-parse[1].\n+\tSets of commits can be passed but no traversal is done by\n+\tdefault, as if the '--no-walk' option was specified, see\n+\tlinkgit:git-rev-list[1].\n \n -e::\n --edit::\n@@ -55,10 +59,10 @@ OPTIONS\n \n -n::\n --no-commit::\n-\tUsually the command automatically creates a commit.\n-\tThis flag applies the change necessary to cherry-pick\n-\tthe named commit to your working tree and the index,\n-\tbut does not make the commit.  In addition, when this\n+\tUsually the command automatically creates a sequence of commits.\n+\tThis flag applies the changes necessary to cherry-pick\n+\teach named commit to your working tree and the index,\n+\twithout making any commit.  In addition, when this\n \toption is used, your index does not have to match the\n \tHEAD commit.  The cherry-pick is done against the\n \tbeginning state of your index.\n@@ -75,6 +79,40 @@ effect to your index in a row.\n \tcherry-pick'ed commit, then a fast forward to this commit will\n \tbe performed.\n \n+EXAMPLES\n+--------\n+git cherry-pick master::\n+\n+\tApply the change introduced by the commit at the tip of the\n+\tmaster branch and create a new commit with this change.\n+\n+git cherry-pick ..master::\n+git cherry-pick ^HEAD master::\n+\n+\tApply the changes introduced by all commits that are ancestors\n+\tof master but not of HEAD to produce new commits.\n+\n+git cherry-pick master\\~4 master~2::\n+\n+\tApply the changes introduced by the fifth and third last\n+\tcommits pointed to by master and create 2 new commits with\n+\tthese changes.\n+\n+git cherry-pick -n master~1 next::\n+\n+\tApply to the working tree and the index the changes introduced\n+\tby the second last commit pointed to by master and by the last\n+\tcommit pointed to by next, but do not create any commit with\n+\tthese changes.\n+\n+git cherry-pick --ff ..next::\n+\n+\tIf history is linear and HEAD is an ancestor of next, update\n+\tthe working tree and advance the HEAD pointer to match next.\n+\tOtherwise, apply the changes introduced by those commits that\n+\tare in next but not HEAD to the current branch, creating a new\n+\tcommit for each new change.\n+\n Author\n ------\n Written by Junio C Hamano <gitster@pobox.com>\n@@ -83,6 +121,10 @@ Documentation\n --------------\n Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.\n \n+SEE ALSO\n+--------\n+linkgit:git-revert[1]\n+\n GIT\n ---\n Part of the linkgit:git[1] suite\n-- \n1.7.1.362.g8d752\n"},{"id":"142783","messageId":"20100602055842.21504.85441.chriscool@tuxfamily.org","threadId":"23976","inReplyTo":"20100602055131.21504.71923.chriscool@tuxfamily.org","subject":"[PATCH v2 8/8] Documentation/revert: describe passing more than one commit","fromName":"Christian Couder","fromEmail":"chriscool@tuxfamily.org","sentAt":"2010-06-02T05:58:41Z","receivedAt":"2010-06-02T05:58:41Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"And while at it, add an \"EXAMPLES\" section.\n\nSigned-off-by: Christian Couder <chriscool@tuxfamily.org>\n---\n Documentation/git-revert.txt |   51 ++++++++++++++++++++++++++++++-----------\n 1 files changed, 37 insertions(+), 14 deletions(-)\n\ndiff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt\nindex c66bf80..dea4f53 100644\n--- a/Documentation/git-revert.txt\n+++ b/Documentation/git-revert.txt\n@@ -3,20 +3,22 @@ git-revert(1)\n \n NAME\n ----\n-git-revert - Revert an existing commit\n+git-revert - Revert some existing commits\n \n SYNOPSIS\n --------\n-'git revert' [--edit | --no-edit] [-n] [-m parent-number] [-s] <commit>\n+'git revert' [--edit | --no-edit] [-n] [-m parent-number] [-s] <commit>...\n \n DESCRIPTION\n -----------\n-Given one existing commit, revert the change the patch introduces, and record a\n-new commit that records it.  This requires your working tree to be clean (no\n-modifications from the HEAD commit).\n \n-Note: 'git revert' is used to record a new commit to reverse the\n-effect of an earlier commit (often a faulty one).  If you want to\n+Given one or more existing commits, revert the changes that the\n+related patches introduce, and record some new commits that record\n+them.  This requires your working tree to be clean (no modifications\n+from the HEAD commit).\n+\n+Note: 'git revert' is used to record some new commits to reverse the\n+effect of some earlier commits (often only a faulty one).  If you want to\n throw away all uncommitted changes in your working directory, you\n should see linkgit:git-reset[1], particularly the '--hard' option.  If\n you want to extract specific files as they were in another commit, you\n@@ -26,10 +28,13 @@ both will discard uncommitted changes in your working directory.\n \n OPTIONS\n -------\n-<commit>::\n-\tCommit to revert.\n+<commit>...::\n+\tCommits to revert.\n \tFor a more complete list of ways to spell commit names, see\n \t\"SPECIFYING REVISIONS\" section in linkgit:git-rev-parse[1].\n+\tSets of commits can also be given but no traversal is done by\n+\tdefault, see linkgit:git-rev-list[1] and its '--no-walk'\n+\toption.\n \n -e::\n --edit::\n@@ -59,11 +64,11 @@ more details.\n \n -n::\n --no-commit::\n-\tUsually the command automatically creates a commit with\n-\ta commit log message stating which commit was\n-\treverted.  This flag applies the change necessary\n-\tto revert the named commit to your working tree\n-\tand the index, but does not make the commit.  In addition,\n+\tUsually the command automatically creates some commits with\n+\tcommit log messages stating which commits were\n+\treverted.  This flag applies the changes necessary\n+\tto revert the named commits to your working tree\n+\tand the index, but does not make the commits.  In addition,\n \twhen this option is used, your index does not have to match\n \tthe HEAD commit.  The revert is done against the\n \tbeginning state of your index.\n@@ -75,6 +80,20 @@ effect to your index in a row.\n --signoff::\n \tAdd Signed-off-by line at the end of the commit message.\n \n+EXAMPLES\n+--------\n+git revert HEAD~3::\n+\n+\tRevert the changes specified by the fourth last commit in HEAD\n+\tand create a new commit with the reverted changes.\n+\n+git revert -n master\\~5..master~2::\n+\n+\tRevert the changes done by commits from the fifth last commit\n+\tin master (included) to the third last commit in master\n+\t(included), but do not create any commit with the reverted\n+\tchanges. The revert only modifies the working tree and the\n+\tindex.\n \n Author\n ------\n@@ -84,6 +103,10 @@ Documentation\n --------------\n Documentation by Junio C Hamano and the git-list <git@vger.kernel.org>.\n \n+SEE ALSO\n+--------\n+linkgit:git-cherry-pick[1]\n+\n GIT\n ---\n Part of the linkgit:git[1] suite\n-- \n1.7.1.362.g8d752\n"}]}