From 831244bd0df6871c618fc8becbb5c0f1fb8f5459 Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Wed, 2 Jun 2010 07:58:34 +0200 Subject: revert: cleanup code for -x option There was some dead code and option -x appeared in the short help message of git revert (when running "git revert -h") which was wrong. Signed-off-by: Christian Couder Signed-off-by: Junio C Hamano --- builtin/revert.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'builtin') diff --git a/builtin/revert.c b/builtin/revert.c index 7976b5a329..5df0d690d9 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -58,7 +58,6 @@ static void parse_args(int argc, const char **argv) struct option options[] = { OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"), OPT_BOOLEAN('e', "edit", &edit, "edit the commit message"), - OPT_BOOLEAN('x', NULL, &no_replay, "append commit name when cherry-picking"), OPT_BOOLEAN('r', NULL, &noop, "no-op (backward compatibility)"), OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"), OPT_INTEGER('m', "mainline", &mainline, "parent number"), @@ -71,6 +70,7 @@ static void parse_args(int argc, const char **argv) if (action == CHERRY_PICK) { struct option cp_extra[] = { + OPT_BOOLEAN('x', NULL, &no_replay, "append commit name"), OPT_BOOLEAN(0, "ff", &allow_ff, "allow fast-forward"), OPT_END(), }; @@ -379,10 +379,6 @@ static int revert_or_cherry_pick(int argc, const char **argv) setenv(GIT_REFLOG_ACTION, me, 0); parse_args(argc, argv); - /* this is copied from the shell script, but it's never triggered... */ - if (action == REVERT && !no_replay) - die("revert is incompatible with replay"); - if (allow_ff) { if (signoff) die("cherry-pick --ff cannot be used with --signoff"); @@ -546,14 +542,12 @@ int cmd_revert(int argc, const char **argv, const char *prefix) { if (isatty(0)) edit = 1; - no_replay = 1; action = REVERT; return revert_or_cherry_pick(argc, argv); } int cmd_cherry_pick(int argc, const char **argv, const char *prefix) { - no_replay = 0; action = CHERRY_PICK; return revert_or_cherry_pick(argc, argv); } -- cgit v1.2.3 From 2fb0e14f4014a4f5027401bc7156929309449726 Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Wed, 2 Jun 2010 07:58:35 +0200 Subject: revert: use run_command_v_opt() instead of execv_git_cmd() This is needed by the following commits, because we are going to cherry pick many commits instead of just one. Signed-off-by: Christian Couder Signed-off-by: Junio C Hamano --- builtin/revert.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'builtin') diff --git a/builtin/revert.c b/builtin/revert.c index 5df0d690d9..02f18c2208 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -508,6 +508,8 @@ static int revert_or_cherry_pick(int argc, const char **argv) } } + free_message(&msg); + /* * * If we are cherry-pick, and if the merge did not result in @@ -520,7 +522,9 @@ static int revert_or_cherry_pick(int argc, const char **argv) if (!no_commit) { /* 6 is max possible length of our args array including NULL */ const char *args[6]; + int res; int i = 0; + args[i++] = "commit"; args[i++] = "-n"; if (signoff) @@ -530,9 +534,12 @@ static int revert_or_cherry_pick(int argc, const char **argv) args[i++] = defmsg; } args[i] = NULL; - return execv_git_cmd(args); + res = run_command_v_opt(args, RUN_GIT_CMD); + free(defmsg); + + return res; } - free_message(&msg); + free(defmsg); return 0; -- cgit v1.2.3 From 7af46595b2667214e98da55ed2f82ce1ac2b404a Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Wed, 2 Jun 2010 07:58:36 +0200 Subject: revert: refactor code into a do_pick_commit() function This is needed because we are going to make it possible to cherry-pick many commits instead of just one in the following commits. And we will be able to do that by just calling do_pick_commit() once for each commit to cherry-pick. Signed-off-by: Christian Couder Signed-off-by: Junio C Hamano --- builtin/revert.c | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'builtin') diff --git a/builtin/revert.c b/builtin/revert.c index 02f18c2208..c2aee86d1c 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -365,7 +365,7 @@ static void do_recursive_merge(struct commit *base, struct commit *next, fprintf(stderr, "Finished one %s.\n", me); } -static int revert_or_cherry_pick(int argc, const char **argv) +static int do_pick_commit(void) { unsigned char head[20]; struct commit *base, *next, *parent; @@ -374,24 +374,6 @@ static int revert_or_cherry_pick(int argc, const char **argv) char *defmsg = NULL; struct strbuf msgbuf = STRBUF_INIT; - git_config(git_default_config, NULL); - me = action == REVERT ? "revert" : "cherry-pick"; - setenv(GIT_REFLOG_ACTION, me, 0); - parse_args(argc, argv); - - if (allow_ff) { - if (signoff) - die("cherry-pick --ff cannot be used with --signoff"); - if (no_commit) - die("cherry-pick --ff cannot be used with --no-commit"); - if (no_replay) - die("cherry-pick --ff cannot be used with -x"); - if (edit) - die("cherry-pick --ff cannot be used with --edit"); - } - - if (read_cache() < 0) - die("git %s: failed to read the index", me); if (no_commit) { /* * We do not intend to commit immediately. We just want to @@ -545,6 +527,30 @@ static int revert_or_cherry_pick(int argc, const char **argv) return 0; } +static int revert_or_cherry_pick(int argc, const char **argv) +{ + git_config(git_default_config, NULL); + me = action == REVERT ? "revert" : "cherry-pick"; + setenv(GIT_REFLOG_ACTION, me, 0); + parse_args(argc, argv); + + if (allow_ff) { + if (signoff) + die("cherry-pick --ff cannot be used with --signoff"); + if (no_commit) + die("cherry-pick --ff cannot be used with --no-commit"); + if (no_replay) + die("cherry-pick --ff cannot be used with -x"); + if (edit) + die("cherry-pick --ff cannot be used with --edit"); + } + + if (read_cache() < 0) + die("git %s: failed to read the index", me); + + return do_pick_commit(); +} + int cmd_revert(int argc, const char **argv, const char *prefix) { if (isatty(0)) -- cgit v1.2.3 From 4b2095622f61e6ab51f03601e5c3c8d71ace5fc7 Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Wed, 2 Jun 2010 07:58:37 +0200 Subject: revert: change help_msg() to take no argument This is needed because the following commits will make it possible to cherry-pick many commits instead of just one. So it will be possible to pass for example ranges of commits to "git cherry-pick" and this means that it will not be possible to use the arguments passed to "git cherry-pick" in the help message. The help message will have to use the sha1 of the currently processed commit. Signed-off-by: Christian Couder Signed-off-by: Junio C Hamano --- builtin/revert.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'builtin') diff --git a/builtin/revert.c b/builtin/revert.c index c2aee86d1c..aee10692ba 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -239,7 +239,7 @@ static void set_author_ident_env(const char *message) sha1_to_hex(commit->object.sha1)); } -static char *help_msg(const char *name) +static char *help_msg(void) { struct strbuf helpbuf = STRBUF_INIT; char *msg = getenv("GIT_CHERRY_PICK_HELP"); @@ -255,7 +255,7 @@ static char *help_msg(const char *name) strbuf_addf(&helpbuf, " with: \n" "\n" " git commit -c %s\n", - name); + sha1_to_hex(commit->object.sha1)); } else strbuf_addch(&helpbuf, '.'); @@ -357,7 +357,7 @@ static void do_recursive_merge(struct commit *base, struct commit *next, } write_message(msgbuf, defmsg); fprintf(stderr, "Automatic %s failed.%s\n", - me, help_msg(commit_name)); + me, help_msg()); rerere(allow_rerere_auto); exit(1); } @@ -484,7 +484,7 @@ static int do_pick_commit(void) free_commit_list(remotes); if (res) { fprintf(stderr, "Automatic %s with strategy %s failed.%s\n", - me, strategy, help_msg(commit_name)); + me, strategy, help_msg()); rerere(allow_rerere_auto); exit(1); } -- cgit v1.2.3 From 7e2bfd3f99f8d6e89c7b855675919dd5404e47a2 Mon Sep 17 00:00:00 2001 From: Christian Couder Date: Wed, 2 Jun 2010 07:58:38 +0200 Subject: revert: allow cherry-picking more than one commit This makes it possible to pass many commits or ranges of commits to "git cherry-pick" and to "git revert" to process many commits instead of just one. In fact commits are now enumerated with an equivalent of git rev-list --no-walk "$@" so all the following are now possible: git cherry-pick master~2..master git cherry-pick ^master~2 master git cherry-pick master^ master The following should be possible but does not work: git cherry-pick -2 master because "git rev-list --no-walk -2 master" only outputs one commit as "--no-walk" seems to take over "-2". And there is currently no way to continue cherry-picking or reverting if there is a problem with one commit. It's also not possible to abort the whole process. Some future work should provide the --continue and --abort options to do just that. Signed-off-by: Christian Couder Signed-off-by: Junio C Hamano --- builtin/revert.c | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) (limited to 'builtin') diff --git a/builtin/revert.c b/builtin/revert.c index aee10692ba..853e9e406c 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -39,7 +39,8 @@ static const char * const cherry_pick_usage[] = { static int edit, no_replay, no_commit, mainline, signoff, allow_ff; static enum { REVERT, CHERRY_PICK } action; static struct commit *commit; -static const char *commit_name; +static int commit_argc; +static const char **commit_argv; static int allow_rerere_auto; static const char *me; @@ -53,7 +54,6 @@ static void parse_args(int argc, const char **argv) { const char * const * usage_str = action == REVERT ? revert_usage : cherry_pick_usage; - unsigned char sha1[20]; int noop; struct option options[] = { OPT_BOOLEAN('n', "no-commit", &no_commit, "don't automatically commit"), @@ -78,15 +78,11 @@ static void parse_args(int argc, const char **argv) die("program error"); } - if (parse_options(argc, argv, NULL, options, usage_str, 0) != 1) + commit_argc = parse_options(argc, argv, NULL, options, usage_str, 0); + if (commit_argc < 1) usage_with_options(usage_str, options); - commit_name = argv[0]; - if (get_sha1(commit_name, sha1)) - die ("Cannot find '%s'", commit_name); - commit = lookup_commit_reference(sha1); - if (!commit) - exit(1); + commit_argv = argv; } struct commit_message { @@ -527,8 +523,35 @@ static int do_pick_commit(void) return 0; } +static void prepare_revs(struct rev_info *revs) +{ + int argc = 0; + int i; + const char **argv = xmalloc((commit_argc + 4) * sizeof(*argv)); + + argv[argc++] = NULL; + argv[argc++] = "--no-walk"; + if (action != REVERT) + argv[argc++] = "--reverse"; + for (i = 0; i < commit_argc; i++) + argv[argc++] = commit_argv[i]; + argv[argc++] = NULL; + + init_revisions(revs, NULL); + setup_revisions(argc - 1, argv, revs, NULL); + if (prepare_revision_walk(revs)) + die("revision walk setup failed"); + + if (!revs->commits) + die("empty commit set passed"); + + free(argv); +} + static int revert_or_cherry_pick(int argc, const char **argv) { + struct rev_info revs; + git_config(git_default_config, NULL); me = action == REVERT ? "revert" : "cherry-pick"; setenv(GIT_REFLOG_ACTION, me, 0); @@ -548,7 +571,15 @@ static int revert_or_cherry_pick(int argc, const char **argv) if (read_cache() < 0) die("git %s: failed to read the index", me); - return do_pick_commit(); + prepare_revs(&revs); + + while ((commit = get_revision(&revs))) { + int res = do_pick_commit(); + if (res) + return res; + } + + return 0; } int cmd_revert(int argc, const char **argv, const char *prefix) -- cgit v1.2.3