As "git merge" fast forwards if possible, it seems sensible to
have such a feature for "git cherry-pick" too, especially as it
could be used in git-rebase--interactive.sh.
Maybe this option could be made the default in the long run, with
another --no-ff option to disable this default behavior, but that
could make some scripts backward incompatible and/or that would
require testing if some GIT_AUTHOR_* environment variables are
set. So we don't do that for now.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin-revert.c | 35 +++++++++++++++++++++++++++++++----
1 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/builtin-revert.c b/builtin-revert.c
index 7488d4c..b78926f 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -9,6 +9,7 @@
#include "revision.h"
#include "rerere.h"
#include "pick.h"
+#include "reset.h"
/*
* This implements the builtins revert and cherry-pick.
@@ -31,13 +32,19 @@ static const char * const cherry_pick_usage[] = {
NULL
};
-static int edit, no_commit, mainline, signoff;
+static int edit, no_commit, mainline, signoff, ff_ok;
static int flags;
static struct commit *commit;
static int allow_rerere_auto;
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
+static void die_if_ff_incompatible(int opt_set, const char *opt_name)
+{
+ if (opt_set)
+ die ("options --ff and %s are incompatible", opt_name);
+}
+
static void parse_args(int argc, const char **argv)
{
const char * const * usage_str =
@@ -51,6 +58,7 @@ static void parse_args(int argc, const char **argv)
OPT_BIT('x', NULL, &flags, "append commit name when cherry-picking", PICK_ADD_NOTE),
OPT_BOOLEAN('r', NULL, &noop, "no-op (backward compatibility)"),
OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
+ OPT_BOOLEAN(0, "ff", &ff_ok, "allow fast forward"),
OPT_INTEGER('m', "mainline", &mainline, "parent number"),
OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
OPT_END(),
@@ -71,6 +79,12 @@ static void parse_args(int argc, const char **argv)
}
if (commit->object.type != OBJ_COMMIT)
die ("'%s' does not point to a commit", arg);
+ if (ff_ok) {
+ die_if_ff_incompatible(edit, "--edit");
+ die_if_ff_incompatible(flags & PICK_ADD_NOTE, "-x");
+ die_if_ff_incompatible(no_commit, "--no-commit");
+ die_if_ff_incompatible(signoff, "--signoff");
+ }
}
static char *get_encoding(const char *message)
@@ -191,7 +205,7 @@ static NORETURN void die_dirty_index(const char *me)
}
}
-static int revert_or_cherry_pick(int argc, const char **argv)
+static int revert_or_cherry_pick(int argc, const char **argv, const char *prefix)
{
const char *me;
struct strbuf msgbuf;
@@ -209,6 +223,19 @@ static int revert_or_cherry_pick(int argc, const char **argv)
if (!no_commit && index_differs_from("HEAD", 0))
die_dirty_index(me);
+ if (!(flags & PICK_REVERSE) && ff_ok && commit->parents) {
+ unsigned char head_sha1[20];
+ if (get_sha1("HEAD", head_sha1))
+ die("You do not have a valid HEAD.");
+ if (!hashcmp(commit->parents->item->object.sha1, head_sha1)) {
+ char *hex = sha1_to_hex(commit->object.sha1);
+ int res = reset(hex, prefix, HARD, 0, 0, 0, NULL);
+ if (!res)
+ fprintf(stderr, "Fast-forward to %s\n", hex);
+ return res;
+ }
+ }
+
if (!commit->buffer)
return error("Cannot get commit message for %s",
sha1_to_hex(commit->object.sha1));
@@ -270,11 +297,11 @@ int cmd_revert(int argc, const char **argv, const char *prefix)
if (isatty(0))
edit = 1;
flags = PICK_REVERSE | PICK_ADD_NOTE;
- return revert_or_cherry_pick(argc, argv);
+ return revert_or_cherry_pick(argc, argv, prefix);
}
int cmd_cherry_pick(int argc, const char **argv, const char *prefix)
{
flags = 0;
- return revert_or_cherry_pick(argc, argv);
+ return revert_or_cherry_pick(argc, argv, prefix);
}
--
1.6.6.1.557.g77031
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html