# [PATCH v6 00/28] Massive improvents to rebase and cherry-pick

29 messages from 2013-08-30 to 2013-08-30. Participants: Felipe Contreras.
Thread: https://gitlist.dev/t/34806

## Felipe Contreras, 2013-08-30 05:55

Subject: [PATCH v6 00/28] Massive improvents to rebase and cherry-pick
Message-ID: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-1-git-send-email-felipe.contreras%40gmail.com

```
Hi,

These are improvements to 'git rebase' by using a much improved 'git
cherry-pick'.

A new rewrite.c helper is added, and builtin/commit updated to use
that.

A new git-rebase--cherypick mode is added, and it replaces git-rebase--am and
git-rebase--merge.

Felipe Contreras (28):
  cherry-pick: don't barf when there's nothing to do
  cherry-pick: add --skip-empty option
  revert/cherry-pick: add --quiet option
  revert/cherry-pick: add --skip option
  builtin: add rewrite helper
  cherry-pick: store rewritten commits
  cherry-pick: don't store skipped commit
  builtin: move run_rewrite_hook() to rewrite.c
  builtin: rewrite: add copy_rewrite_notes()
  cherry-pick: add --action-name option
  cherry-pick: copy notes and run hooks
  cherry-pick: remember rerere-autoupdate
  rebase: split the cherry-pick stuff
  rebase: cherry-pick: fix mode storage
  rebase: cherry-pick: fix sequence continuation
  rebase: cherry-pick: fix abort of cherry mode
  rebase: cherry-pick: fix command invocations
  rebase: cherry-pick: fix status messages
  rebase: cherry-pick: automatically commit stage
  rebase: cherry-pick: set correct action-name
  rebase: trivial cleanup
  t: rebase-autostash: fix setup
  sequencer: store progress information
  prompt: parse cherry-pick rebase mode
  rebase: use 'cherrypick' mode instead of 'am'
  rebase: cherry-pick: add merge options
  rebase: remove merge mode
  rebase: cherry-pick: add copyright

 .gitignore                             |   2 +-
 Documentation/config.txt               |   9 +-
 Documentation/git-cherry-pick.txt      |  10 ++-
 Documentation/git-revert.txt           |   7 +-
 Documentation/githooks.txt             |   8 +-
 Documentation/sequencer.txt            |   3 +
 Makefile                               |   4 +-
 builtin/commit.c                       |  46 ++--------
 builtin/revert.c                       |  17 ++++
 contrib/completion/git-prompt.sh       |  16 ++--
 git-rebase--am.sh                      |  12 +--
 git-rebase--cherrypick.sh              |  66 ++++++++++++++
 git-rebase--interactive.sh             |   6 +-
 git-rebase--merge.sh                   | 151 ---------------------------------
 git-rebase.sh                          |  16 ++--
 rewrite.c                              | 122 ++++++++++++++++++++++++++
 rewrite.h                              |  20 +++++
 sequencer.c                            | 124 +++++++++++++++++++++++++--
 sequencer.h                            |   8 +-
 t/t3406-rebase-message.sh              |  14 +--
 t/t3407-rebase-abort.sh                |   2 +-
 t/t3420-rebase-autostash.sh            | 107 ++++++++++++-----------
 t/t3425-rebase-topology-merges.sh      |  15 ++--
 t/t3508-cherry-pick-many-commits.sh    |  13 +++
 t/t3510-cherry-pick-sequence.sh        |  14 ++-
 t/t5520-pull.sh                        |   2 +-
 t/t9106-git-svn-commit-diff-clobber.sh |   2 +-
 t/t9903-bash-prompt.sh                 |   2 +-
 28 files changed, 496 insertions(+), 322 deletions(-)
 create mode 100644 git-rebase--cherrypick.sh
 delete mode 100644 git-rebase--merge.sh
 create mode 100644 rewrite.c
 create mode 100644 rewrite.h

-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:55

Subject: [PATCH v6 01/28] cherry-pick: don't barf when there's nothing to do
Message-ID: <1377842182-18724-2-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-2-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 sequencer.c                     | 2 +-
 t/t3510-cherry-pick-sequence.sh | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/sequencer.c b/sequencer.c
index 351548f..a962b33 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -661,7 +661,7 @@ static void prepare_revs(struct replay_opts *opts)
 		die(_("revision walk setup failed"));
 
 	if (!opts->revs->commits)
-		die(_("empty commit set passed"));
+		error(_("empty commit set passed"));
 }
 
 static void read_and_refresh_cache(struct replay_opts *opts)
diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh
index 7b7a89d..33c5512 100755
--- a/t/t3510-cherry-pick-sequence.sh
+++ b/t/t3510-cherry-pick-sequence.sh
@@ -472,7 +472,7 @@ test_expect_success 'malformed instruction sheet 2' '
 
 test_expect_success 'empty commit set' '
 	pristine_detach initial &&
-	test_expect_code 128 git cherry-pick base..base
+	git cherry-pick base..base
 '
 
 test_expect_success 'malformed instruction sheet 3' '
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:55

Subject: [PATCH v6 02/28] cherry-pick: add --skip-empty option
Message-ID: <1377842182-18724-3-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-3-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Pretty much what it says on the tin.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 Documentation/git-cherry-pick.txt   |  3 +++
 builtin/revert.c                    |  8 ++++++++
 sequencer.c                         |  6 ++++++
 sequencer.h                         |  1 +
 t/t3508-cherry-pick-many-commits.sh | 13 +++++++++++++
 5 files changed, 31 insertions(+)

diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index c205d23..fccd936 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt
@@ -129,6 +129,9 @@ effect to your index in a row.
 	redundant commits are ignored.  This option overrides that behavior and
 	creates an empty commit object.  Implies `--allow-empty`.
 
+--skip-empty::
+	Instead of failing, skip commits that are or become empty.
+
 --strategy=<strategy>::
 	Use the given merge strategy.  Should only be used once.
 	See the MERGE STRATEGIES section in linkgit:git-merge[1]
diff --git a/builtin/revert.c b/builtin/revert.c
index 1d2648b..6e7cb2a 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -120,6 +120,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 		OPT_END(),
 		OPT_END(),
 		OPT_END(),
+		OPT_END(),
 	};
 
 	if (opts->action == REPLAY_PICK) {
@@ -129,6 +130,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 			OPT_BOOLEAN(0, "allow-empty", &opts->allow_empty, N_("preserve initially empty commits")),
 			OPT_BOOLEAN(0, "allow-empty-message", &opts->allow_empty_message, N_("allow commits with empty messages")),
 			OPT_BOOLEAN(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")),
+			OPT_BOOLEAN(0, "skip-empty", &opts->skip_empty, N_("skip empty commits")),
 			OPT_END(),
 		};
 		if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))
@@ -146,6 +148,12 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 				"--abort", rollback,
 				NULL);
 
+	verify_opt_mutually_compatible(me,
+				"--allow-empty", opts->allow_empty,
+				"--skip-empty", opts->skip_empty,
+				"--keep-redundant-commits", opts->keep_redundant_commits,
+				NULL);
+
 	/* implies allow_empty */
 	if (opts->keep_redundant_commits)
 		opts->allow_empty = 1;
diff --git a/sequencer.c b/sequencer.c
index a962b33..c387828 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -633,6 +633,12 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
 		goto leave;
 	}
 
+	if (opts->skip_empty && is_index_unchanged() == 1) {
+		warning(_("skipping %s... %s"),
+			find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),
+			msg.subject);
+		goto leave;
+	}
 	allow = allow_empty(opts, commit);
 	if (allow < 0) {
 		res = allow;
diff --git a/sequencer.h b/sequencer.h
index 1fc22dc..3b04844 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -34,6 +34,7 @@ struct replay_opts {
 	int allow_empty;
 	int allow_empty_message;
 	int keep_redundant_commits;
+	int skip_empty;
 
 	int mainline;
 
diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh
index 19c99d7..3dc19c6 100755
--- a/t/t3508-cherry-pick-many-commits.sh
+++ b/t/t3508-cherry-pick-many-commits.sh
@@ -187,4 +187,17 @@ test_expect_success 'cherry-pick --stdin works' '
 	check_head_differs_from fourth
 '
 
+test_expect_success 'cherry-pick skip empty' '
+	git clean -fxd &&
+	git checkout -b empty fourth &&
+	git commit --allow-empty -m empty &&
+	test_commit ontop &&
+	git checkout -f master &&
+	git reset --hard fourth &&
+	git cherry-pick --skip-empty fourth..empty &&
+	echo ontop > expected &&
+	git log --format=%s fourth..HEAD > actual
+	test_cmp expected actual
+'
+
 test_done
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:55

Subject: [PATCH v6 03/28] revert/cherry-pick: add --quiet option
Message-ID: <1377842182-18724-4-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-4-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 Documentation/git-cherry-pick.txt |  6 +++++-
 Documentation/git-revert.txt      |  6 +++++-
 builtin/revert.c                  |  1 +
 sequencer.c                       | 11 +++++++----
 sequencer.h                       |  1 +
 5 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index fccd936..da0bd81 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt
@@ -8,7 +8,7 @@ git-cherry-pick - Apply the changes introduced by some existing commits
 SYNOPSIS
 --------
 [verse]
-'git cherry-pick' [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...
+'git cherry-pick' [-q] [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...
 'git cherry-pick' --continue
 'git cherry-pick' --quit
 'git cherry-pick' --abort
@@ -51,6 +51,10 @@ OPTIONS
 	feed all <commit>... arguments to a single revision walk
 	(see a later example that uses 'maint master..next').
 
+-q::
+--quiet::
+	Quiet, suppress feedback messages.
+
 -e::
 --edit::
 	With this option, 'git cherry-pick' will let you edit the commit
diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt
index f79c9d8..98a8e7a 100644
--- a/Documentation/git-revert.txt
+++ b/Documentation/git-revert.txt
@@ -8,7 +8,7 @@ git-revert - Revert some existing commits
 SYNOPSIS
 --------
 [verse]
-'git revert' [--[no-]edit] [-n] [-m parent-number] [-s] <commit>...
+'git revert' [-q] [--[no-]edit] [-n] [-m parent-number] [-s] <commit>...
 'git revert' --continue
 'git revert' --quit
 'git revert' --abort
@@ -40,6 +40,10 @@ OPTIONS
 	default, see linkgit:git-rev-list[1] and its '--no-walk'
 	option.
 
+-q::
+--quiet::
+	Quiet, suppress feedback messages.
+
 -e::
 --edit::
 	With this option, 'git revert' will let you edit the commit
diff --git a/builtin/revert.c b/builtin/revert.c
index 6e7cb2a..7a7fde6 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -102,6 +102,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 	int contin = 0;
 	int rollback = 0;
 	struct option options[] = {
+		OPT__QUIET(&opts->quiet, N_("suppress progress reporting")),
 		OPT_BOOLEAN(0, "quit", &remove_state, N_("end revert or cherry-pick sequence")),
 		OPT_BOOLEAN(0, "continue", &contin, N_("resume revert or cherry-pick sequence")),
 		OPT_BOOLEAN(0, "abort", &rollback, N_("cancel revert or cherry-pick sequence")),
diff --git a/sequencer.c b/sequencer.c
index c387828..d6199e4 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -395,6 +395,8 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
 	argv_array_init(&array);
 	argv_array_push(&array, "commit");
 	argv_array_push(&array, "-n");
+	if (opts->quiet)
+		argv_array_push(&array, "-q");
 
 	if (opts->signoff)
 		argv_array_push(&array, "-s");
@@ -634,9 +636,10 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
 	}
 
 	if (opts->skip_empty && is_index_unchanged() == 1) {
-		warning(_("skipping %s... %s"),
-			find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),
-			msg.subject);
+		if (!opts->quiet)
+			warning(_("skipping %s... %s"),
+				find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV),
+				msg.subject);
 		goto leave;
 	}
 	allow = allow_empty(opts, commit);
@@ -666,7 +669,7 @@ static void prepare_revs(struct replay_opts *opts)
 	if (prepare_revision_walk(opts->revs))
 		die(_("revision walk setup failed"));
 
-	if (!opts->revs->commits)
+	if (!opts->revs->commits && !opts->quiet)
 		error(_("empty commit set passed"));
 }
 
diff --git a/sequencer.h b/sequencer.h
index 3b04844..d37c003 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -35,6 +35,7 @@ struct replay_opts {
 	int allow_empty_message;
 	int keep_redundant_commits;
 	int skip_empty;
+	int quiet;
 
 	int mainline;
 
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:55

Subject: [PATCH v6 04/28] revert/cherry-pick: add --skip option
Message-ID: <1377842182-18724-5-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-5-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Akin to 'am --skip' and 'rebase --skip'.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 Documentation/git-cherry-pick.txt |  1 +
 Documentation/git-revert.txt      |  1 +
 Documentation/sequencer.txt       |  3 +++
 builtin/revert.c                  |  6 ++++++
 sequencer.c                       | 24 ++++++++++++++++++++++++
 sequencer.h                       |  3 ++-
 t/t3510-cherry-pick-sequence.sh   | 12 ++++++++++++
 7 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-cherry-pick.txt b/Documentation/git-cherry-pick.txt
index da0bd81..d95c63c 100644
--- a/Documentation/git-cherry-pick.txt
+++ b/Documentation/git-cherry-pick.txt
@@ -10,6 +10,7 @@ SYNOPSIS
 [verse]
 'git cherry-pick' [-q] [--edit] [-n] [-m parent-number] [-s] [-x] [--ff] <commit>...
 'git cherry-pick' --continue
+'git cherry-pick' --skip
 'git cherry-pick' --quit
 'git cherry-pick' --abort
 
diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt
index 98a8e7a..52e146e 100644
--- a/Documentation/git-revert.txt
+++ b/Documentation/git-revert.txt
@@ -10,6 +10,7 @@ SYNOPSIS
 [verse]
 'git revert' [-q] [--[no-]edit] [-n] [-m parent-number] [-s] <commit>...
 'git revert' --continue
+'git revert' --skip
 'git revert' --quit
 'git revert' --abort
 
diff --git a/Documentation/sequencer.txt b/Documentation/sequencer.txt
index 5747f44..df2d355 100644
--- a/Documentation/sequencer.txt
+++ b/Documentation/sequencer.txt
@@ -3,6 +3,9 @@
 	'.git/sequencer'.  Can be used to continue after resolving
 	conflicts in a failed cherry-pick or revert.
 
+--skip::
+	Skip the current commit, and then continue.
+
 --quit::
 	Forget about the current operation in progress.  Can be used
 	to clear the sequencer state after a failed cherry-pick or
diff --git a/builtin/revert.c b/builtin/revert.c
index 7a7fde6..d3ae2c4 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -101,11 +101,13 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 	int remove_state = 0;
 	int contin = 0;
 	int rollback = 0;
+	int skip = 0;
 	struct option options[] = {
 		OPT__QUIET(&opts->quiet, N_("suppress progress reporting")),
 		OPT_BOOLEAN(0, "quit", &remove_state, N_("end revert or cherry-pick sequence")),
 		OPT_BOOLEAN(0, "continue", &contin, N_("resume revert or cherry-pick sequence")),
 		OPT_BOOLEAN(0, "abort", &rollback, N_("cancel revert or cherry-pick sequence")),
+		OPT_BOOLEAN(0, "skip", &skip, N_("skip current commit in the sequence")),
 		OPT_BOOLEAN('n', "no-commit", &opts->no_commit, N_("don't automatically commit")),
 		OPT_BOOLEAN('e', "edit", &opts->edit, N_("edit the commit message")),
 		OPT_NOOP_NOARG('r', NULL),
@@ -166,6 +168,8 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 		opts->subcommand = REPLAY_CONTINUE;
 	else if (rollback)
 		opts->subcommand = REPLAY_ROLLBACK;
+	else if (skip)
+		opts->subcommand = REPLAY_SKIP;
 	else
 		opts->subcommand = REPLAY_NONE;
 
@@ -176,6 +180,8 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 			this_operation = "--quit";
 		else if (opts->subcommand == REPLAY_CONTINUE)
 			this_operation = "--continue";
+		else if (opts->subcommand == REPLAY_SKIP)
+			this_operation = "--skip";
 		else {
 			assert(opts->subcommand == REPLAY_ROLLBACK);
 			this_operation = "--abort";
diff --git a/sequencer.c b/sequencer.c
index d6199e4..d0e65de 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1056,6 +1056,28 @@ static int sequencer_continue(struct replay_opts *opts)
 	return pick_commits(todo_list, opts);
 }
 
+static int sequencer_skip(struct replay_opts *opts)
+{
+	const char *argv[4]; /* reset --hard HEAD + NULL */
+	struct string_list merge_rr = STRING_LIST_INIT_DUP;
+	int ret;
+
+	if (setup_rerere(&merge_rr, 0) >= 0) {
+		rerere_clear(&merge_rr);
+		string_list_clear(&merge_rr, 1);
+	}
+
+	argv[0] = "reset";
+	argv[1] = "--hard";
+	argv[2] = "HEAD";
+	argv[3] = NULL;
+	ret = run_command_v_opt(argv, RUN_GIT_CMD);
+	if (ret)
+		return ret;
+
+	return sequencer_continue(opts);
+}
+
 static int single_pick(struct commit *cmit, struct replay_opts *opts)
 {
 	setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
@@ -1086,6 +1108,8 @@ int sequencer_pick_revisions(struct replay_opts *opts)
 		return sequencer_rollback(opts);
 	if (opts->subcommand == REPLAY_CONTINUE)
 		return sequencer_continue(opts);
+	if (opts->subcommand == REPLAY_SKIP)
+		return sequencer_skip(opts);
 
 	for (i = 0; i < opts->revs->pending.nr; i++) {
 		unsigned char sha1[20];
diff --git a/sequencer.h b/sequencer.h
index d37c003..74d592a 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -17,7 +17,8 @@ enum replay_subcommand {
 	REPLAY_NONE,
 	REPLAY_REMOVE_STATE,
 	REPLAY_CONTINUE,
-	REPLAY_ROLLBACK
+	REPLAY_ROLLBACK,
+	REPLAY_SKIP
 };
 
 struct replay_opts {
diff --git a/t/t3510-cherry-pick-sequence.sh b/t/t3510-cherry-pick-sequence.sh
index 33c5512..c43c327 100755
--- a/t/t3510-cherry-pick-sequence.sh
+++ b/t/t3510-cherry-pick-sequence.sh
@@ -511,4 +511,16 @@ test_expect_success 'commit descriptions in insn sheet are optional' '
 	test_line_count = 4 commits
 '
 
+test_expect_success 'skip' '
+	pristine_detach conflicting &&
+	test_must_fail git cherry-pick initial..picked &&
+
+	git checkout HEAD -- unrelated &&
+	test_must_fail git cherry-pick --continue &&
+	git cherry-pick --skip &&
+
+	git rev-list initial..HEAD >commits &&
+	test_line_count = 3 commits
+'
+
 test_done
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:55

Subject: [PATCH v6 05/28] builtin: add rewrite helper
Message-ID: <1377842182-18724-6-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-6-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
So that we can load and store rewrites, as well as other operations on a
list of rewritten commits.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 Makefile  |  2 ++
 rewrite.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 rewrite.h | 18 ++++++++++++++++
 3 files changed, 91 insertions(+)
 create mode 100644 rewrite.c
 create mode 100644 rewrite.h

diff --git a/Makefile b/Makefile
index 3588ca1..9396d57 100644
--- a/Makefile
+++ b/Makefile
@@ -716,6 +716,7 @@ LIB_H += remote.h
 LIB_H += rerere.h
 LIB_H += resolve-undo.h
 LIB_H += revision.h
+LIB_H += rewrite.h
 LIB_H += run-command.h
 LIB_H += send-pack.h
 LIB_H += sequencer.h
@@ -860,6 +861,7 @@ LIB_OBJS += replace_object.o
 LIB_OBJS += rerere.o
 LIB_OBJS += resolve-undo.o
 LIB_OBJS += revision.o
+LIB_OBJS += rewrite.o
 LIB_OBJS += run-command.o
 LIB_OBJS += send-pack.o
 LIB_OBJS += sequencer.o
diff --git a/rewrite.c b/rewrite.c
new file mode 100644
index 0000000..2793688
--- /dev/null
+++ b/rewrite.c
@@ -0,0 +1,71 @@
+#include "cache.h"
+#include "rewrite.h"
+
+void add_rewritten(struct rewritten *list, unsigned char *from, unsigned char *to)
+{
+	struct rewritten_item *item;
+	ALLOC_GROW(list->items, list->nr, list->alloc);
+	item = &list->items[list->nr];
+	hashcpy(item->from, from);
+	hashcpy(item->to, to);
+	list->nr++;
+}
+
+int store_rewritten(struct rewritten *list, const char *file)
+{
+	static struct lock_file lock;
+	struct strbuf buf = STRBUF_INIT;
+	int fd, i, ret = 0;
+
+	fd = hold_lock_file_for_update(&lock, file, LOCK_DIE_ON_ERROR);
+	for (i = 0; i < list->nr; i++) {
+		struct rewritten_item *item = &list->items[i];
+		strbuf_addf(&buf, "%s %s\n", sha1_to_hex(item->from), sha1_to_hex(item->to));
+	}
+	if (write_in_full(fd, buf.buf, buf.len) < 0) {
+		error(_("Could not write to %s"), file);
+		ret = 1;
+		goto leave;
+	}
+	if (commit_lock_file(&lock) < 0) {
+		error(_("Error wrapping up %s."), file);
+		ret = 1;
+		goto leave;
+	}
+leave:
+	strbuf_release(&buf);
+	return ret;
+}
+
+void load_rewritten(struct rewritten *list, const char *file)
+{
+	struct strbuf buf = STRBUF_INIT;
+	char *p;
+	int fd;
+
+	fd = open(file, O_RDONLY);
+	if (fd < 0)
+		return;
+	if (strbuf_read(&buf, fd, 0) < 0) {
+		close(fd);
+		strbuf_release(&buf);
+		return;
+	}
+	close(fd);
+
+	for (p = buf.buf; *p;) {
+		unsigned char from[20];
+		unsigned char to[20];
+		char *eol = strchrnul(p, '\n');
+		if (eol - p != 81)
+			/* wrong size */
+			break;
+		if (get_sha1_hex(p, from))
+			break;
+		if (get_sha1_hex(p + 41, to))
+			break;
+		add_rewritten(list, from, to);
+		p = *eol ? eol + 1 : eol;
+	}
+	strbuf_release(&buf);
+}
diff --git a/rewrite.h b/rewrite.h
new file mode 100644
index 0000000..09e7222
--- /dev/null
+++ b/rewrite.h
@@ -0,0 +1,18 @@
+#ifndef REWRITE_H
+#define REWRITE_H
+
+struct rewritten_item {
+	unsigned char from[20];
+	unsigned char to[20];
+};
+
+struct rewritten {
+	struct rewritten_item *items;
+	unsigned int nr, alloc;
+};
+
+void add_rewritten(struct rewritten *list, unsigned char *from, unsigned char *to);
+int store_rewritten(struct rewritten *list, const char *file);
+void load_rewritten(struct rewritten *list, const char *file);
+
+#endif
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 06/28] cherry-pick: store rewritten commits
Message-ID: <1377842182-18724-7-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-7-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Will be useful for the next commits.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 sequencer.c | 22 +++++++++++++++++++++-
 sequencer.h |  1 +
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/sequencer.c b/sequencer.c
index d0e65de..468fa54 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -14,11 +14,13 @@
 #include "merge-recursive.h"
 #include "refs.h"
 #include "argv-array.h"
+#include "rewrite.h"
 
 #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
 
 const char sign_off_header[] = "Signed-off-by: ";
 static const char cherry_picked_prefix[] = "(cherry picked from commit ";
+static struct rewritten rewritten;
 
 static int is_rfc2822_line(const char *buf, int len)
 {
@@ -650,6 +652,14 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
 	if (!opts->no_commit)
 		res = run_git_commit(defmsg, opts, allow);
 
+	if (!res && opts->action == REPLAY_PICK) {
+		unsigned char to[20];
+
+		if (read_ref("HEAD", to))
+			goto leave;
+
+		add_rewritten(&rewritten, commit->object.sha1, to);
+	}
 leave:
 	free_message(&msg);
 	free(defmsg);
@@ -1012,8 +1022,11 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
 	for (cur = todo_list; cur; cur = cur->next) {
 		save_todo(cur, opts);
 		res = do_pick_commit(cur->item, opts);
-		if (res)
+		if (res) {
+			if (opts->action == REPLAY_PICK)
+				store_rewritten(&rewritten, git_path(SEQ_REWR_FILE));
 			return res;
+		}
 	}
 
 	/*
@@ -1042,6 +1055,8 @@ static int sequencer_continue(struct replay_opts *opts)
 		return continue_single_pick();
 	read_populate_opts(&opts);
 	read_populate_todo(&todo_list, opts);
+	if (opts->action == REPLAY_PICK)
+		load_rewritten(&rewritten, git_path(SEQ_REWR_FILE));
 
 	/* Verify that the conflict has been resolved */
 	if (file_exists(git_path("CHERRY_PICK_HEAD")) ||
@@ -1052,6 +1067,11 @@ static int sequencer_continue(struct replay_opts *opts)
 	}
 	if (index_differs_from("HEAD", 0))
 		return error_dirty_index(opts);
+	if (opts->action == REPLAY_PICK) {
+		unsigned char to[20];
+		if (!read_ref("HEAD", to))
+			add_rewritten(&rewritten, todo_list->item->object.sha1, to);
+	}
 	todo_list = todo_list->next;
 	return pick_commits(todo_list, opts);
 }
diff --git a/sequencer.h b/sequencer.h
index 74d592a..efec1b5 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -5,6 +5,7 @@
 #define SEQ_HEAD_FILE	"sequencer/head"
 #define SEQ_TODO_FILE	"sequencer/todo"
 #define SEQ_OPTS_FILE	"sequencer/opts"
+#define SEQ_REWR_FILE	"sequencer/rewritten"
 
 #define APPEND_SIGNOFF_DEDUP (1u << 0)
 
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 07/28] cherry-pick: don't store skipped commit
Message-ID: <1377842182-18724-8-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-8-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 sequencer.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sequencer.c b/sequencer.c
index 468fa54..56d791f 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1047,7 +1047,7 @@ static int continue_single_pick(void)
 	return run_command_v_opt(argv, RUN_GIT_CMD);
 }
 
-static int sequencer_continue(struct replay_opts *opts)
+static int sequencer_continue(struct replay_opts *opts, int skip)
 {
 	struct commit_list *todo_list = NULL;
 
@@ -1067,7 +1067,7 @@ static int sequencer_continue(struct replay_opts *opts)
 	}
 	if (index_differs_from("HEAD", 0))
 		return error_dirty_index(opts);
-	if (opts->action == REPLAY_PICK) {
+	if (opts->action == REPLAY_PICK && !skip) {
 		unsigned char to[20];
 		if (!read_ref("HEAD", to))
 			add_rewritten(&rewritten, todo_list->item->object.sha1, to);
@@ -1095,7 +1095,7 @@ static int sequencer_skip(struct replay_opts *opts)
 	if (ret)
 		return ret;
 
-	return sequencer_continue(opts);
+	return sequencer_continue(opts, 1);
 }
 
 static int single_pick(struct commit *cmit, struct replay_opts *opts)
@@ -1127,7 +1127,7 @@ int sequencer_pick_revisions(struct replay_opts *opts)
 	if (opts->subcommand == REPLAY_ROLLBACK)
 		return sequencer_rollback(opts);
 	if (opts->subcommand == REPLAY_CONTINUE)
-		return sequencer_continue(opts);
+		return sequencer_continue(opts, 0);
 	if (opts->subcommand == REPLAY_SKIP)
 		return sequencer_skip(opts);
 
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 08/28] builtin: move run_rewrite_hook() to rewrite.c
Message-ID: <1377842182-18724-9-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-9-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
And use struct rewrite.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/commit.c | 38 +++++---------------------------------
 rewrite.c        | 32 ++++++++++++++++++++++++++++++++
 rewrite.h        |  1 +
 3 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 10acc53..7bfe9d0 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -30,6 +30,7 @@
 #include "column.h"
 #include "sequencer.h"
 #include "notes-utils.h"
+#include "rewrite.h"
 
 static const char * const builtin_commit_usage[] = {
 	N_("git commit [options] [--] <pathspec>..."),
@@ -1386,38 +1387,6 @@ static int git_commit_config(const char *k, const char *v, void *cb)
 	return git_status_config(k, v, s);
 }
 
-static int run_rewrite_hook(const unsigned char *oldsha1,
-			    const unsigned char *newsha1)
-{
-	/* oldsha1 SP newsha1 LF NUL */
-	static char buf[2*40 + 3];
-	struct child_process proc;
-	const char *argv[3];
-	int code;
-	size_t n;
-
-	argv[0] = find_hook("post-rewrite");
-	if (!argv[0])
-		return 0;
-
-	argv[1] = "amend";
-	argv[2] = NULL;
-
-	memset(&proc, 0, sizeof(proc));
-	proc.argv = argv;
-	proc.in = -1;
-	proc.stdout_to_stderr = 1;
-
-	code = start_command(&proc);
-	if (code)
-		return code;
-	n = snprintf(buf, sizeof(buf), "%s %s\n",
-		     sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
-	write_in_full(proc.in, buf, n);
-	close(proc.in);
-	return finish_command(&proc);
-}
-
 int cmd_commit(int argc, const char **argv, const char *prefix)
 {
 	static struct wt_status s;
@@ -1653,13 +1622,16 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	run_hook(get_index_file(), "post-commit", NULL);
 	if (amend && !no_post_rewrite) {
 		struct notes_rewrite_cfg *cfg;
+		struct rewritten rewrite;
+		memset(&rewrite, 0, sizeof(rewrite));
 		cfg = init_copy_notes_for_rewrite("amend");
 		if (cfg) {
 			/* we are amending, so current_head is not NULL */
 			copy_note_for_rewrite(cfg, current_head->object.sha1, sha1);
 			finish_copy_notes_for_rewrite(cfg, "Notes added by 'git commit --amend'");
 		}
-		run_rewrite_hook(current_head->object.sha1, sha1);
+		add_rewritten(&rewrite, current_head->object.sha1, sha1);
+		run_rewrite_hook(&rewrite, "amend");
 	}
 	if (!quiet)
 		print_summary(prefix, sha1, !current_head);
diff --git a/rewrite.c b/rewrite.c
index 2793688..c8efaa8 100644
--- a/rewrite.c
+++ b/rewrite.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "rewrite.h"
+#include "run-command.h"
 
 void add_rewritten(struct rewritten *list, unsigned char *from, unsigned char *to)
 {
@@ -69,3 +70,34 @@ void load_rewritten(struct rewritten *list, const char *file)
 	}
 	strbuf_release(&buf);
 }
+
+int run_rewrite_hook(struct rewritten *list, const char *name)
+{
+	struct strbuf buf = STRBUF_INIT;
+	struct child_process proc;
+	const char *argv[3];
+	int code, i;
+
+	argv[0] = find_hook("post-rewrite");
+	if (!argv[0])
+		return 0;
+
+	argv[1] = name;
+	argv[2] = NULL;
+
+	memset(&proc, 0, sizeof(proc));
+	proc.argv = argv;
+	proc.in = -1;
+	proc.stdout_to_stderr = 1;
+
+	code = start_command(&proc);
+	if (code)
+		return code;
+	for (i = 0; i < list->nr; i++) {
+		struct rewritten_item *item = &list->items[i];
+		strbuf_addf(&buf, "%s %s\n", sha1_to_hex(item->from), sha1_to_hex(item->to));
+	}
+	write_in_full(proc.in, buf.buf, buf.len);
+	close(proc.in);
+	return finish_command(&proc);
+}
diff --git a/rewrite.h b/rewrite.h
index 09e7222..fd00e66 100644
--- a/rewrite.h
+++ b/rewrite.h
@@ -14,5 +14,6 @@ struct rewritten {
 void add_rewritten(struct rewritten *list, unsigned char *from, unsigned char *to);
 int store_rewritten(struct rewritten *list, const char *file);
 void load_rewritten(struct rewritten *list, const char *file);
+int run_rewrite_hook(struct rewritten *list, const char *name);
 
 #endif
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 09/28] builtin: rewrite: add copy_rewrite_notes()
Message-ID: <1377842182-18724-10-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-10-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
And use it on commit.c.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/commit.c |  8 +-------
 rewrite.c        | 18 ++++++++++++++++++
 rewrite.h        |  1 +
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 7bfe9d0..cc589d5 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1621,16 +1621,10 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	rerere(0);
 	run_hook(get_index_file(), "post-commit", NULL);
 	if (amend && !no_post_rewrite) {
-		struct notes_rewrite_cfg *cfg;
 		struct rewritten rewrite;
 		memset(&rewrite, 0, sizeof(rewrite));
-		cfg = init_copy_notes_for_rewrite("amend");
-		if (cfg) {
-			/* we are amending, so current_head is not NULL */
-			copy_note_for_rewrite(cfg, current_head->object.sha1, sha1);
-			finish_copy_notes_for_rewrite(cfg, "Notes added by 'git commit --amend'");
-		}
 		add_rewritten(&rewrite, current_head->object.sha1, sha1);
+		copy_rewrite_notes(&rewrite, "amend", "Notes added by 'git commit --amend'");
 		run_rewrite_hook(&rewrite, "amend");
 	}
 	if (!quiet)
diff --git a/rewrite.c b/rewrite.c
index c8efaa8..4dddcd9 100644
--- a/rewrite.c
+++ b/rewrite.c
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "rewrite.h"
 #include "run-command.h"
+#include "notes-utils.h"
 
 void add_rewritten(struct rewritten *list, unsigned char *from, unsigned char *to)
 {
@@ -101,3 +102,20 @@ int run_rewrite_hook(struct rewritten *list, const char *name)
 	close(proc.in);
 	return finish_command(&proc);
 }
+
+void copy_rewrite_notes(struct rewritten *list, const char *name, const char *msg)
+{
+	struct notes_rewrite_cfg *cfg;
+	int i;
+
+	cfg = init_copy_notes_for_rewrite(name);
+	if (!cfg)
+		return;
+
+	for (i = 0; i < list->nr; i++) {
+		struct rewritten_item *item = &list->items[i];
+		copy_note_for_rewrite(cfg, item->from, item->to);
+	}
+
+	finish_copy_notes_for_rewrite(cfg, msg);
+}
diff --git a/rewrite.h b/rewrite.h
index fd00e66..fdc7055 100644
--- a/rewrite.h
+++ b/rewrite.h
@@ -15,5 +15,6 @@ void add_rewritten(struct rewritten *list, unsigned char *from, unsigned char *t
 int store_rewritten(struct rewritten *list, const char *file);
 void load_rewritten(struct rewritten *list, const char *file);
 int run_rewrite_hook(struct rewritten *list, const char *name);
+void copy_rewrite_notes(struct rewritten *list, const char *name, const char *msg);
 
 #endif
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 10/28] cherry-pick: add --action-name option
Message-ID: <1377842182-18724-11-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-11-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
So it can be used by other tools (e.g. git rebase), and the right action
is passed to the hooks and notes rewrite stuff.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 builtin/revert.c           | 2 ++
 git-rebase--interactive.sh | 4 ++--
 sequencer.c                | 6 +++++-
 sequencer.h                | 2 ++
 4 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/builtin/revert.c b/builtin/revert.c
index d3ae2c4..ca28e52 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -124,6 +124,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 		OPT_END(),
 		OPT_END(),
 		OPT_END(),
+		OPT_END(),
 	};
 
 	if (opts->action == REPLAY_PICK) {
@@ -134,6 +135,7 @@ static void parse_args(int argc, const char **argv, struct replay_opts *opts)
 			OPT_BOOLEAN(0, "allow-empty-message", &opts->allow_empty_message, N_("allow commits with empty messages")),
 			OPT_BOOLEAN(0, "keep-redundant-commits", &opts->keep_redundant_commits, N_("keep redundant, empty commits")),
 			OPT_BOOLEAN(0, "skip-empty", &opts->skip_empty, N_("skip empty commits")),
+			OPT_STRING(0, "action-name", &opts->action_name, N_("name"), N_("action name")),
 			OPT_END(),
 		};
 		if (parse_options_concat(options, ARRAY_SIZE(options), cp_extra))
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 83d6d46..e8143ae 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -251,7 +251,7 @@ pick_one () {
 
 	test -d "$rewritten" &&
 		pick_one_preserving_merges "$@" && return
-	output eval git cherry-pick "$strategy_args" $empty_args $ff "$@"
+	output eval git cherry-pick "--action-name ''" "$strategy_args" $empty_args $ff "$@"
 }
 
 pick_one_preserving_merges () {
@@ -361,7 +361,7 @@ pick_one_preserving_merges () {
 			echo "$sha1 $(git rev-parse HEAD^0)" >> "$rewritten_list"
 			;;
 		*)
-			output eval git cherry-pick "$strategy_args" "$@" ||
+			output eval git cherry-pick "--action-name ''" "$strategy_args" "$@" ||
 				die_with_patch $sha1 "Could not pick $sha1"
 			;;
 		esac
diff --git a/sequencer.c b/sequencer.c
index 56d791f..46848c4 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -829,7 +829,9 @@ static int populate_opts_cb(const char *key, const char *value, void *data)
 	else if (!strcmp(key, "options.strategy-option")) {
 		ALLOC_GROW(opts->xopts, opts->xopts_nr + 1, opts->xopts_alloc);
 		opts->xopts[opts->xopts_nr++] = xstrdup(value);
-	} else
+	} else if (!strcmp(key, "options.action-name"))
+		git_config_string(&opts->action_name, key, value);
+	else
 		return error(_("Invalid key: %s"), key);
 
 	if (!error_flag)
@@ -1006,6 +1008,8 @@ static void save_opts(struct replay_opts *opts)
 							"options.strategy-option",
 							opts->xopts[i], "^$", 0);
 	}
+	if (opts->action_name)
+		git_config_set_in_file(opts_file, "options.action-name", opts->action_name);
 }
 
 static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
diff --git a/sequencer.h b/sequencer.h
index efec1b5..6dfffaa 100644
--- a/sequencer.h
+++ b/sequencer.h
@@ -48,6 +48,8 @@ struct replay_opts {
 
 	/* Only used by REPLAY_NONE */
 	struct rev_info *revs;
+
+	const char *action_name;
 };
 
 int sequencer_pick_revisions(struct replay_opts *opts);
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 11/28] cherry-pick: copy notes and run hooks
Message-ID: <1377842182-18724-12-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-12-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
If no action-name is specified, nothing is done.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 Documentation/config.txt   |  9 ++++-----
 Documentation/githooks.txt |  8 ++++----
 rewrite.c                  |  1 +
 sequencer.c                | 25 ++++++++++++++++++++++++-
 4 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index ec57a15..7e7f89f 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1691,11 +1691,10 @@ GIT_NOTES_REF) is also implicitly added to the list of refs to be
 displayed.
 
 notes.rewrite.<command>::
-	When rewriting commits with <command> (currently `amend` or
-	`rebase`) and this variable is set to `true`, Git
-	automatically copies your notes from the original to the
-	rewritten commit.  Defaults to `true`, but see
-	"notes.rewriteRef" below.
+	When rewriting commits with <command> (currently `amend`, `rebase`, or
+	`cherry-pick`) and this variable is set to `true`, Git automatically
+	copies your notes from the original to the rewritten commit.  Defaults
+	to `true`, but see "notes.rewriteRef" below.
 
 notes.rewriteMode::
 	When copying notes during a rewrite (see the
diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt
index d48bf4d..8cfa13b 100644
--- a/Documentation/githooks.txt
+++ b/Documentation/githooks.txt
@@ -352,10 +352,10 @@ post-rewrite
 ~~~~~~~~~~~~
 
 This hook is invoked by commands that rewrite commits (`git commit
---amend`, 'git-rebase'; currently 'git-filter-branch' does 'not' call
-it!).  Its first argument denotes the command it was invoked by:
-currently one of `amend` or `rebase`.  Further command-dependent
-arguments may be passed in the future.
+--amend`, `git rebase`, `git cherry-pick`; currently `git filter-branch` does
+'not' call it!).  Its first argument denotes the command it was invoked by
+(e.g. `rebase`).  Further command-dependent arguments may be passed in the
+future.
 
 The hook receives a list of the rewritten commits on stdin, in the
 format
diff --git a/rewrite.c b/rewrite.c
index 4dddcd9..4f95094 100644
--- a/rewrite.c
+++ b/rewrite.c
@@ -2,6 +2,7 @@
 #include "rewrite.h"
 #include "run-command.h"
 #include "notes-utils.h"
+#include "builtin.h"
 
 void add_rewritten(struct rewritten *list, unsigned char *from, unsigned char *to)
 {
diff --git a/sequencer.c b/sequencer.c
index 46848c4..076bb9d 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -22,6 +22,22 @@ const char sign_off_header[] = "Signed-off-by: ";
 static const char cherry_picked_prefix[] = "(cherry picked from commit ";
 static struct rewritten rewritten;
 
+static void finish(struct replay_opts *opts)
+{
+	const char *name;
+
+	if (opts->action != REPLAY_PICK)
+		return;
+
+	name = opts->action_name ? opts->action_name : "cherry-pick";
+
+	if (!*name)
+		return;
+
+	copy_rewrite_notes(&rewritten, name, "Notes added by 'git cherry-pick'");
+	run_rewrite_hook(&rewritten, name);
+}
+
 static int is_rfc2822_line(const char *buf, int len)
 {
 	int i;
@@ -1033,6 +1049,8 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
 		}
 	}
 
+	finish(opts);
+
 	/*
 	 * Sequence of picks finished successfully; cleanup by
 	 * removing the .git/sequencer directory
@@ -1104,8 +1122,13 @@ static int sequencer_skip(struct replay_opts *opts)
 
 static int single_pick(struct commit *cmit, struct replay_opts *opts)
 {
+	int ret;
 	setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
-	return do_pick_commit(cmit, opts);
+	ret = do_pick_commit(cmit, opts);
+	if (ret)
+		return ret;
+	finish(opts);
+	return 0;
 }
 
 int sequencer_pick_revisions(struct replay_opts *opts)
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 12/28] cherry-pick: remember rerere-autoupdate
Message-ID: <1377842182-18724-13-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-13-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 sequencer.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/sequencer.c b/sequencer.c
index 076bb9d..453e4a4 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -847,6 +847,8 @@ static int populate_opts_cb(const char *key, const char *value, void *data)
 		opts->xopts[opts->xopts_nr++] = xstrdup(value);
 	} else if (!strcmp(key, "options.action-name"))
 		git_config_string(&opts->action_name, key, value);
+	else if (!strcmp(key, "options.allow-rerere-auto"))
+		opts->allow_rerere_auto = git_config_int(key, value);
 	else
 		return error(_("Invalid key: %s"), key);
 
@@ -1026,6 +1028,12 @@ static void save_opts(struct replay_opts *opts)
 	}
 	if (opts->action_name)
 		git_config_set_in_file(opts_file, "options.action-name", opts->action_name);
+	if (opts->allow_rerere_auto) {
+		struct strbuf buf = STRBUF_INIT;
+		strbuf_addf(&buf, "%d", opts->allow_rerere_auto);
+		git_config_set_in_file(opts_file, "options.allow-rerere-auto", buf.buf);
+		strbuf_release(&buf);
+	}
 }
 
 static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 13/28] rebase: split the cherry-pick stuff
Message-ID: <1377842182-18724-14-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-14-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
They do something completely different from 'git am', it belongs in a
different file.

No functional changes.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 .gitignore                |  1 +
 Makefile                  |  1 +
 git-rebase--am.sh         | 11 +----------
 git-rebase--cherrypick.sh | 30 ++++++++++++++++++++++++++++++
 git-rebase.sh             |  4 ++++
 5 files changed, 37 insertions(+), 10 deletions(-)
 create mode 100644 git-rebase--cherrypick.sh

diff --git a/.gitignore b/.gitignore
index 6b1fd1b..3514737 100644
--- a/.gitignore
+++ b/.gitignore
@@ -114,6 +114,7 @@
 /git-read-tree
 /git-rebase
 /git-rebase--am
+/git-rebase--cherrypick
 /git-rebase--interactive
 /git-rebase--merge
 /git-receive-pack
diff --git a/Makefile b/Makefile
index 9396d57..2d6521e 100644
--- a/Makefile
+++ b/Makefile
@@ -473,6 +473,7 @@ SCRIPT_SH += git-web--browse.sh
 SCRIPT_LIB += git-mergetool--lib
 SCRIPT_LIB += git-parse-remote
 SCRIPT_LIB += git-rebase--am
+SCRIPT_LIB += git-rebase--cherrypick
 SCRIPT_LIB += git-rebase--interactive
 SCRIPT_LIB += git-rebase--merge
 SCRIPT_LIB += git-sh-setup
diff --git a/git-rebase--am.sh b/git-rebase--am.sh
index 34e3102..aae6a85 100644
--- a/git-rebase--am.sh
+++ b/git-rebase--am.sh
@@ -19,15 +19,7 @@ esac
 test -n "$rebase_root" && root_flag=--root
 
 ret=0
-if test -n "$keep_empty"
-then
-	# we have to do this the hard way.  git format-patch completely squashes
-	# empty commits and even if it didn't the format doesn't really lend
-	# itself well to recording empty patches.  fortunately, cherry-pick
-	# makes this easy
-	git cherry-pick --allow-empty "$revisions"
-	ret=$?
-else
+
 	rm -f "$GIT_DIR/rebased-patches"
 
 	git format-patch -k --stdout --full-index --ignore-if-in-upstream \
@@ -63,7 +55,6 @@ else
 	ret=$?
 
 	rm -f "$GIT_DIR/rebased-patches"
-fi
 
 if test 0 != $ret
 then
diff --git a/git-rebase--cherrypick.sh b/git-rebase--cherrypick.sh
new file mode 100644
index 0000000..2c16995
--- /dev/null
+++ b/git-rebase--cherrypick.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Junio C Hamano.
+#
+
+case "$action" in
+continue)
+	git am --resolved --resolvemsg="$resolvemsg" &&
+	move_to_original_branch
+	return
+	;;
+skip)
+	git am --skip --resolvemsg="$resolvemsg" &&
+	move_to_original_branch
+	return
+	;;
+esac
+
+test -n "$rebase_root" && root_flag=--root
+
+git cherry-pick --allow-empty "$revisions"
+ret=$?
+
+if test 0 != $ret
+then
+	test -d "$state_dir" && write_basic_state
+	return $ret
+fi
+
+move_to_original_branch
diff --git a/git-rebase.sh b/git-rebase.sh
index 8d7659a..2310638 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -412,6 +412,10 @@ elif test -n "$do_merge"
 then
 	type=merge
 	state_dir="$merge_dir"
+elif test -n "$keep_empty"
+then
+	type=cherrypick
+	state_dir="$apply_dir"
 else
 	type=am
 	state_dir="$apply_dir"
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 14/28] rebase: cherry-pick: fix mode storage
Message-ID: <1377842182-18724-15-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-15-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
We don't use the 'rebase-apply'.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 git-rebase--cherrypick.sh | 5 ++++-
 git-rebase.sh             | 5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/git-rebase--cherrypick.sh b/git-rebase--cherrypick.sh
index 2c16995..e142cfb 100644
--- a/git-rebase--cherrypick.sh
+++ b/git-rebase--cherrypick.sh
@@ -18,12 +18,15 @@ esac
 
 test -n "$rebase_root" && root_flag=--root
 
+mkdir -p "$state_dir" || die "Could not create temporary $state_dir"
+: > "$state_dir"/cherrypick || die "Could not mark as cherrypick"
+
 git cherry-pick --allow-empty "$revisions"
 ret=$?
 
 if test 0 != $ret
 then
-	test -d "$state_dir" && write_basic_state
+	write_basic_state
 	return $ret
 fi
 
diff --git a/git-rebase.sh b/git-rebase.sh
index 2310638..b28addc 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -204,6 +204,9 @@ then
 	then
 		type=interactive
 		interactive_rebase=explicit
+	elif test -f "$merge_dir"/cherrypick
+	then
+		type=cherrypick
 	else
 		type=merge
 	fi
@@ -415,7 +418,7 @@ then
 elif test -n "$keep_empty"
 then
 	type=cherrypick
-	state_dir="$apply_dir"
+	state_dir="$merge_dir"
 else
 	type=am
 	state_dir="$apply_dir"
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 15/28] rebase: cherry-pick: fix sequence continuation
Message-ID: <1377842182-18724-16-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-16-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
We are not in am mode.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 git-rebase--cherrypick.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/git-rebase--cherrypick.sh b/git-rebase--cherrypick.sh
index e142cfb..d8d32fe 100644
--- a/git-rebase--cherrypick.sh
+++ b/git-rebase--cherrypick.sh
@@ -5,12 +5,12 @@
 
 case "$action" in
 continue)
-	git am --resolved --resolvemsg="$resolvemsg" &&
+	git cherry-pick --continue &&
 	move_to_original_branch
 	return
 	;;
 skip)
-	git am --skip --resolvemsg="$resolvemsg" &&
+	git cherry-pick --skip &&
 	move_to_original_branch
 	return
 	;;
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 16/28] rebase: cherry-pick: fix abort of cherry mode
Message-ID: <1377842182-18724-17-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-17-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 git-rebase.sh | 1 +
 1 file changed, 1 insertion(+)

diff --git a/git-rebase.sh b/git-rebase.sh
index b28addc..db2ea8d 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -368,6 +368,7 @@ skip)
 	run_specific_rebase
 	;;
 abort)
+	test "$type" == "cherrypick" && git cherry-pick --abort
 	git rerere clear
 	read_basic_state
 	case "$head_name" in
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 17/28] rebase: cherry-pick: fix command invocations
Message-ID: <1377842182-18724-18-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-18-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
So that all the tests pass.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 git-rebase--cherrypick.sh | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/git-rebase--cherrypick.sh b/git-rebase--cherrypick.sh
index d8d32fe..e9ecccc 100644
--- a/git-rebase--cherrypick.sh
+++ b/git-rebase--cherrypick.sh
@@ -21,7 +21,22 @@ test -n "$rebase_root" && root_flag=--root
 mkdir -p "$state_dir" || die "Could not create temporary $state_dir"
 : > "$state_dir"/cherrypick || die "Could not mark as cherrypick"
 
-git cherry-pick --allow-empty "$revisions"
+if test -n "$rebase_root"
+then
+	revisions="$onto...$orig_head"
+else
+	revisions="$upstream...$orig_head"
+fi
+
+if test -n "$keep_empty"
+then
+	extra="--allow-empty"
+else
+	extra="--skip-empty --cherry-pick"
+fi
+test -n "$GIT_QUIET" && extra="$extra -q"
+test -z "$force_rebase" && extra="$extra --ff"
+git cherry-pick --no-merges --right-only --topo-order --do-walk $extra "$revisions"
 ret=$?
 
 if test 0 != $ret
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 18/28] rebase: cherry-pick: fix status messages
Message-ID: <1377842182-18724-19-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-19-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 git-rebase--cherrypick.sh | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/git-rebase--cherrypick.sh b/git-rebase--cherrypick.sh
index e9ecccc..be17ec4 100644
--- a/git-rebase--cherrypick.sh
+++ b/git-rebase--cherrypick.sh
@@ -3,6 +3,9 @@
 # Copyright (c) 2010 Junio C Hamano.
 #
 
+GIT_CHERRY_PICK_HELP="$resolvemsg"
+export GIT_CHERRY_PICK_HELP
+
 case "$action" in
 continue)
 	git cherry-pick --continue &&
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 19/28] rebase: cherry-pick: automatically commit stage
Message-ID: <1377842182-18724-20-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-20-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
When there's changes in the staging area. Just like the other rebase
modes.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 git-rebase--cherrypick.sh | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/git-rebase--cherrypick.sh b/git-rebase--cherrypick.sh
index be17ec4..241cda7 100644
--- a/git-rebase--cherrypick.sh
+++ b/git-rebase--cherrypick.sh
@@ -8,6 +8,12 @@ export GIT_CHERRY_PICK_HELP
 
 case "$action" in
 continue)
+	# do we have anything to commit?
+	if ! git diff-index --cached --quiet HEAD --
+	then
+		git commit --no-verify -e ||
+			die "Could not commit staged changes."
+	fi
 	git cherry-pick --continue &&
 	move_to_original_branch
 	return
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 20/28] rebase: cherry-pick: set correct action-name
Message-ID: <1377842182-18724-21-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-21-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 git-rebase--cherrypick.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/git-rebase--cherrypick.sh b/git-rebase--cherrypick.sh
index 241cda7..d36b0dc 100644
--- a/git-rebase--cherrypick.sh
+++ b/git-rebase--cherrypick.sh
@@ -45,7 +45,7 @@ else
 fi
 test -n "$GIT_QUIET" && extra="$extra -q"
 test -z "$force_rebase" && extra="$extra --ff"
-git cherry-pick --no-merges --right-only --topo-order --do-walk $extra "$revisions"
+git cherry-pick --no-merges --right-only --topo-order --do-walk --action-name rebase $extra "$revisions"
 ret=$?
 
 if test 0 != $ret
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 21/28] rebase: trivial cleanup
Message-ID: <1377842182-18724-22-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-22-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 git-rebase--am.sh | 1 +
 git-rebase.sh     | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/git-rebase--am.sh b/git-rebase--am.sh
index aae6a85..d6a434c 100644
--- a/git-rebase--am.sh
+++ b/git-rebase--am.sh
@@ -51,6 +51,7 @@ ret=0
 		return $?
 	fi
 
+	test -n "$GIT_QUIET" && git_am_opt="$git_am_opt -q"
 	git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" <"$GIT_DIR/rebased-patches"
 	ret=$?
 
diff --git a/git-rebase.sh b/git-rebase.sh
index db2ea8d..ebe87a3 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -284,7 +284,6 @@ do
 		;;
 	-q)
 		GIT_QUIET=t
-		git_am_opt="$git_am_opt -q"
 		verbose=
 		diffstat=
 		;;
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 22/28] t: rebase-autostash: fix setup
Message-ID: <1377842182-18724-23-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-23-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 t/t3420-rebase-autostash.sh | 105 ++++++++++++++++++++++----------------------
 1 file changed, 52 insertions(+), 53 deletions(-)

diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index 90eb264..c179262 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -33,54 +33,56 @@ test_expect_success setup '
 	git commit -m "related commit"
 '
 
+setup_tmp () {
+	git clone . tmp &&
+	cd tmp &&
+	git fetch -u origin "refs/heads/*:refs/heads/*" &&
+	test_config rebase.autostash true &&
+	git checkout -b rebased-feature-branch feature-branch
+}
+
 testrebase() {
 	type=$1
 	dotest=$2
 
 	test_expect_success "rebase$type: dirty worktree, non-conflicting rebase" '
-		test_config rebase.autostash true &&
-		git reset --hard &&
-		git checkout -b rebased-feature-branch feature-branch &&
-		test_when_finished git branch -D rebased-feature-branch &&
+		test_when_finished "rm -rf tmp" &&
+		(
+		setup_tmp &&
 		echo dirty >>file3 &&
 		git rebase$type unrelated-onto-branch &&
 		grep unrelated file4 &&
-		grep dirty file3 &&
-		git checkout feature-branch
+		grep dirty file3
+		)
 	'
 
 	test_expect_success "rebase$type: dirty index, non-conflicting rebase" '
-		test_config rebase.autostash true &&
-		git reset --hard &&
-		git checkout -b rebased-feature-branch feature-branch &&
-		test_when_finished git branch -D rebased-feature-branch &&
+		test_when_finished "rm -rf tmp" &&
+		(
+		setup_tmp &&
 		echo dirty >>file3 &&
 		git add file3 &&
 		git rebase$type unrelated-onto-branch &&
 		grep unrelated file4 &&
-		grep dirty file3 &&
-		git checkout feature-branch
+		grep dirty file3
+		)
 	'
 
 	test_expect_success "rebase$type: conflicting rebase" '
-		test_config rebase.autostash true &&
-		git reset --hard &&
-		git checkout -b rebased-feature-branch feature-branch &&
-		test_when_finished git branch -D rebased-feature-branch &&
+		test_when_finished "rm -rf tmp" &&
+		(
+		setup_tmp &&
 		echo dirty >>file3 &&
 		test_must_fail git rebase$type related-onto-branch &&
 		test_path_is_file $dotest/autostash &&
-		! grep dirty file3 &&
-		rm -rf $dotest &&
-		git reset --hard &&
-		git checkout feature-branch
+		! grep dirty file3
+		)
 	'
 
 	test_expect_success "rebase$type: --continue" '
-		test_config rebase.autostash true &&
-		git reset --hard &&
-		git checkout -b rebased-feature-branch feature-branch &&
-		test_when_finished git branch -D rebased-feature-branch &&
+		test_when_finished "rm -rf tmp" &&
+		(
+		setup_tmp &&
 		echo dirty >>file3 &&
 		test_must_fail git rebase$type related-onto-branch &&
 		test_path_is_file $dotest/autostash &&
@@ -89,45 +91,43 @@ testrebase() {
 		git add file2 &&
 		git rebase --continue &&
 		test_path_is_missing $dotest/autostash &&
-		grep dirty file3 &&
-		git checkout feature-branch
+		grep dirty file3
+		)
 	'
 
 	test_expect_success "rebase$type: --skip" '
-		test_config rebase.autostash true &&
+		test_when_finished "rm -rf tmp" &&
+		(
+		setup_tmp &&
 		git reset --hard &&
-		git checkout -b rebased-feature-branch feature-branch &&
-		test_when_finished git branch -D rebased-feature-branch &&
 		echo dirty >>file3 &&
 		test_must_fail git rebase$type related-onto-branch &&
 		test_path_is_file $dotest/autostash &&
 		! grep dirty file3 &&
 		git rebase --skip &&
 		test_path_is_missing $dotest/autostash &&
-		grep dirty file3 &&
-		git checkout feature-branch
+		grep dirty file3
+		)
 	'
 
 	test_expect_success "rebase$type: --abort" '
-		test_config rebase.autostash true &&
-		git reset --hard &&
-		git checkout -b rebased-feature-branch feature-branch &&
-		test_when_finished git branch -D rebased-feature-branch &&
+		test_when_finished "rm -rf tmp" &&
+		(
+		setup_tmp &&
 		echo dirty >>file3 &&
 		test_must_fail git rebase$type related-onto-branch &&
 		test_path_is_file $dotest/autostash &&
 		! grep dirty file3 &&
 		git rebase --abort &&
 		test_path_is_missing $dotest/autostash &&
-		grep dirty file3 &&
-		git checkout feature-branch
+		grep dirty file3
+		)
 	'
 
 	test_expect_success "rebase$type: non-conflicting rebase, conflicting stash" '
-		test_config rebase.autostash true &&
-		git reset --hard &&
-		git checkout -b rebased-feature-branch feature-branch &&
-		test_when_finished git branch -D rebased-feature-branch &&
+		test_when_finished "rm -rf tmp" &&
+		(
+		setup_tmp &&
 		echo dirty >file4 &&
 		git add file4 &&
 		git rebase$type unrelated-onto-branch &&
@@ -138,29 +138,28 @@ testrebase() {
 		git checkout feature-branch &&
 		git stash pop &&
 		grep dirty file4
+		)
 	'
 }
 
 test_expect_success "rebase: fast-forward rebase" '
-	test_config rebase.autostash true &&
-	git reset --hard &&
-	git checkout -b behind-feature-branch feature-branch~1 &&
-	test_when_finished git branch -D behind-feature-branch &&
+	test_when_finished "rm -rf tmp" &&
+	(
+	setup_tmp &&
 	echo dirty >>file1 &&
 	git rebase feature-branch &&
-	grep dirty file1 &&
-	git checkout feature-branch
+	grep dirty file1
+	)
 '
 
 test_expect_success "rebase: noop rebase" '
-	test_config rebase.autostash true &&
-	git reset --hard &&
-	git checkout -b same-feature-branch feature-branch &&
-	test_when_finished git branch -D same-feature-branch &&
+	test_when_finished "rm -rf tmp" &&
+	(
+	setup_tmp &&
 	echo dirty >>file1 &&
 	git rebase feature-branch &&
-	grep dirty file1 &&
-	git checkout feature-branch
+	grep dirty file1
+	)
 '
 
 testrebase "" .git/rebase-apply
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 23/28] sequencer: store progress information
Message-ID: <1377842182-18724-24-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-24-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
So that it can be used by shell prompts.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 sequencer.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/sequencer.c b/sequencer.c
index 453e4a4..c855dd4 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -21,6 +21,7 @@
 const char sign_off_header[] = "Signed-off-by: ";
 static const char cherry_picked_prefix[] = "(cherry picked from commit ";
 static struct rewritten rewritten;
+static int total;
 
 static void finish(struct replay_opts *opts)
 {
@@ -877,8 +878,10 @@ static void walk_revs_populate_todo(struct commit_list **todo_list,
 	prepare_revs(opts);
 
 	next = todo_list;
-	while ((commit = get_revision(opts->revs)))
+	while ((commit = get_revision(opts->revs))) {
 		next = commit_list_append(commit, next);
+		total++;
+	}
 }
 
 static int create_seq_dir(void)
@@ -1036,6 +1039,21 @@ static void save_opts(struct replay_opts *opts)
 	}
 }
 
+static void save_info(int total, int step)
+{
+	FILE *f;
+	f = fopen(git_path("sequencer/total"), "w");
+	if (f) {
+		fprintf(f, "%i\n", total);
+		fclose(f);
+	}
+	f = fopen(git_path("sequencer/step"), "w");
+	if (f) {
+		fprintf(f, "%i\n", step);
+		fclose(f);
+	}
+}
+
 static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
 {
 	struct commit_list *cur;
@@ -1051,8 +1069,10 @@ static int pick_commits(struct commit_list *todo_list, struct replay_opts *opts)
 		save_todo(cur, opts);
 		res = do_pick_commit(cur->item, opts);
 		if (res) {
-			if (opts->action == REPLAY_PICK)
+			if (opts->action == REPLAY_PICK) {
 				store_rewritten(&rewritten, git_path(SEQ_REWR_FILE));
+				save_info(total, rewritten.nr + 1);
+			}
 			return res;
 		}
 	}
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 24/28] prompt: parse cherry-pick rebase mode
Message-ID: <1377842182-18724-25-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-25-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 contrib/completion/git-prompt.sh | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index a81ef5a..a7bde16 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -313,12 +313,18 @@ __git_ps1 ()
 	local total=""
 	if [ -d "$g/rebase-merge" ]; then
 		read b 2>/dev/null <"$g/rebase-merge/head-name"
-		read step 2>/dev/null <"$g/rebase-merge/msgnum"
-		read total 2>/dev/null <"$g/rebase-merge/end"
-		if [ -f "$g/rebase-merge/interactive" ]; then
-			r="|REBASE-i"
+		if [ -f "$g/rebase-merge/cherrypick" ]; then
+			read total 2>/dev/null <"$g/sequencer/total"
+			read step 2>/dev/null <"$g/sequencer/step"
+			r="|REBASE"
 		else
-			r="|REBASE-m"
+			read step 2>/dev/null <"$g/rebase-merge/msgnum"
+			read total 2>/dev/null <"$g/rebase-merge/end"
+			if [ -f "$g/rebase-merge/interactive" ]; then
+				r="|REBASE-i"
+			else
+				r="|REBASE-m"
+			fi
 		fi
 	else
 		if [ -d "$g/rebase-apply" ]; then
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 25/28] rebase: use 'cherrypick' mode instead of 'am'
Message-ID: <1377842182-18724-26-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-26-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Unless any specific 'git am' options are used.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 git-rebase.sh                          | 8 ++++----
 t/t3407-rebase-abort.sh                | 2 +-
 t/t3420-rebase-autostash.sh            | 2 +-
 t/t3425-rebase-topology-merges.sh      | 6 +++---
 t/t5520-pull.sh                        | 2 +-
 t/t9106-git-svn-commit-diff-clobber.sh | 2 +-
 6 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/git-rebase.sh b/git-rebase.sh
index ebe87a3..f0291df 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -415,13 +415,13 @@ elif test -n "$do_merge"
 then
 	type=merge
 	state_dir="$merge_dir"
-elif test -n "$keep_empty"
+elif test -n "$git_am_opt"
 then
-	type=cherrypick
-	state_dir="$merge_dir"
-else
 	type=am
 	state_dir="$apply_dir"
+else
+	type=cherrypick
+	state_dir="$merge_dir"
 fi
 
 if test -z "$rebase_root"
diff --git a/t/t3407-rebase-abort.sh b/t/t3407-rebase-abort.sh
index a6a6c40..2699b08 100755
--- a/t/t3407-rebase-abort.sh
+++ b/t/t3407-rebase-abort.sh
@@ -96,7 +96,7 @@ testrebase() {
 	'
 }
 
-testrebase "" .git/rebase-apply
+testrebase "" .git/rebase-merge
 testrebase " --merge" .git/rebase-merge
 
 test_done
diff --git a/t/t3420-rebase-autostash.sh b/t/t3420-rebase-autostash.sh
index c179262..58bf705 100755
--- a/t/t3420-rebase-autostash.sh
+++ b/t/t3420-rebase-autostash.sh
@@ -162,7 +162,7 @@ test_expect_success "rebase: noop rebase" '
 	)
 '
 
-testrebase "" .git/rebase-apply
+testrebase "" .git/rebase-merge
 testrebase " --merge" .git/rebase-merge
 testrebase " --interactive" .git/rebase-merge
 
diff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh
index 1d195fb..99b4535 100755
--- a/t/t3425-rebase-topology-merges.sh
+++ b/t/t3425-rebase-topology-merges.sh
@@ -71,7 +71,7 @@ test_run_rebase () {
 	"
 }
 #TODO: make order consistent across all flavors of rebase
-test_run_rebase success 'e n o' ''
+test_run_rebase success 'n o e' ''
 test_run_rebase success 'e n o' -m
 test_run_rebase success 'n o e' -i
 
@@ -88,7 +88,7 @@ test_run_rebase () {
 	"
 }
 #TODO: make order consistent across all flavors of rebase
-test_run_rebase success 'd e n o' ''
+test_run_rebase success 'd n o e' ''
 test_run_rebase success 'd e n o' -m
 test_run_rebase success 'd n o e' -i
 
@@ -105,7 +105,7 @@ test_run_rebase () {
 	"
 }
 #TODO: make order consistent across all flavors of rebase
-test_run_rebase success 'd e n o' ''
+test_run_rebase success 'd n o e' ''
 test_run_rebase success 'd e n o' -m
 test_run_rebase success 'd n o e' -i
 
diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh
index ed4d9c8..751b50d 100755
--- a/t/t5520-pull.sh
+++ b/t/t5520-pull.sh
@@ -273,7 +273,7 @@ test_expect_success 'setup for avoiding reapplying old patches' '
 test_expect_success 'git pull --rebase does not reapply old patches' '
 	(cd dst &&
 	 test_must_fail git pull --rebase &&
-	 test 1 = $(find .git/rebase-apply -name "000*" | wc -l)
+	 test 1 = $(cat .git/sequencer/todo | wc -l)
 	)
 '
 
diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh
index f6d7ac7..b9cec33 100755
--- a/t/t9106-git-svn-commit-diff-clobber.sh
+++ b/t/t9106-git-svn-commit-diff-clobber.sh
@@ -92,7 +92,7 @@ test_expect_success 'multiple dcommit from git svn will not clobber svn' "
 
 
 test_expect_success 'check that rebase really failed' '
-	test -d .git/rebase-apply
+	test -d .git/rebase-merge
 '
 
 test_expect_success 'resolve, continue the rebase and dcommit' "
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 26/28] rebase: cherry-pick: add merge options
Message-ID: <1377842182-18724-27-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-27-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 git-rebase--cherrypick.sh | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/git-rebase--cherrypick.sh b/git-rebase--cherrypick.sh
index d36b0dc..bda7cfc 100644
--- a/git-rebase--cherrypick.sh
+++ b/git-rebase--cherrypick.sh
@@ -45,6 +45,15 @@ else
 fi
 test -n "$GIT_QUIET" && extra="$extra -q"
 test -z "$force_rebase" && extra="$extra --ff"
+test -n "$strategy" && extra="$extra --strategy=$strategy"
+for x in "$strategy_opts"
+do
+	test -z "$x" && continue
+	x=$(eval "echo $x")
+	extra="$extra -X${x#--}"
+done
+test -n "$allow_rerere_autoupdate" && extra="$extra $allow_rerere_autoupdate"
+
 git cherry-pick --no-merges --right-only --topo-order --do-walk --action-name rebase $extra "$revisions"
 ret=$?
 
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 27/28] rebase: remove merge mode
Message-ID: <1377842182-18724-28-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-28-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
The cherrypick mode does the job.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 .gitignore                        |   1 -
 Makefile                          |   1 -
 git-rebase--interactive.sh        |   2 +-
 git-rebase--merge.sh              | 151 --------------------------------------
 git-rebase.sh                     |  13 +---
 t/t3406-rebase-message.sh         |  14 +---
 t/t3425-rebase-topology-merges.sh |   9 +--
 t/t9903-bash-prompt.sh            |   2 +-
 8 files changed, 7 insertions(+), 186 deletions(-)
 delete mode 100644 git-rebase--merge.sh

diff --git a/.gitignore b/.gitignore
index 3514737..7b64376 100644
--- a/.gitignore
+++ b/.gitignore
@@ -116,7 +116,6 @@
 /git-rebase--am
 /git-rebase--cherrypick
 /git-rebase--interactive
-/git-rebase--merge
 /git-receive-pack
 /git-reflog
 /git-relink
diff --git a/Makefile b/Makefile
index 2d6521e..f73e060 100644
--- a/Makefile
+++ b/Makefile
@@ -475,7 +475,6 @@ SCRIPT_LIB += git-parse-remote
 SCRIPT_LIB += git-rebase--am
 SCRIPT_LIB += git-rebase--cherrypick
 SCRIPT_LIB += git-rebase--interactive
-SCRIPT_LIB += git-rebase--merge
 SCRIPT_LIB += git-sh-setup
 SCRIPT_LIB += git-sh-i18n
 
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index e8143ae..58aad45 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -81,7 +81,7 @@ rewritten_list="$state_dir"/rewritten-list
 rewritten_pending="$state_dir"/rewritten-pending
 
 strategy_args=
-if test -n "$do_merge"
+if test -n "$strategy"
 then
 	strategy_args=${strategy:+--strategy=$strategy}
 	eval '
diff --git a/git-rebase--merge.sh b/git-rebase--merge.sh
deleted file mode 100644
index 16d1817..0000000
--- a/git-rebase--merge.sh
+++ /dev/null
@@ -1,151 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2010 Junio C Hamano.
-#
-
-prec=4
-
-read_state () {
-	onto_name=$(cat "$state_dir"/onto_name) &&
-	end=$(cat "$state_dir"/end) &&
-	msgnum=$(cat "$state_dir"/msgnum)
-}
-
-continue_merge () {
-	test -d "$state_dir" || die "$state_dir directory does not exist"
-
-	unmerged=$(git ls-files -u)
-	if test -n "$unmerged"
-	then
-		echo "You still have unmerged paths in your index"
-		echo "did you forget to use git add?"
-		die "$resolvemsg"
-	fi
-
-	cmt=`cat "$state_dir/current"`
-	if ! git diff-index --quiet --ignore-submodules HEAD --
-	then
-		if ! git commit --no-verify -C "$cmt"
-		then
-			echo "Commit failed, please do not call \"git commit\""
-			echo "directly, but instead do one of the following: "
-			die "$resolvemsg"
-		fi
-		if test -z "$GIT_QUIET"
-		then
-			printf "Committed: %0${prec}d " $msgnum
-		fi
-		echo "$cmt $(git rev-parse HEAD^0)" >> "$state_dir/rewritten"
-	else
-		if test -z "$GIT_QUIET"
-		then
-			printf "Already applied: %0${prec}d " $msgnum
-		fi
-	fi
-	test -z "$GIT_QUIET" &&
-	GIT_PAGER='' git log --format=%s -1 "$cmt"
-
-	# onto the next patch:
-	msgnum=$(($msgnum + 1))
-	echo "$msgnum" >"$state_dir/msgnum"
-}
-
-call_merge () {
-	cmt="$(cat "$state_dir/cmt.$1")"
-	echo "$cmt" > "$state_dir/current"
-	hd=$(git rev-parse --verify HEAD)
-	cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
-	msgnum=$(cat "$state_dir/msgnum")
-	eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
-	eval GITHEAD_$hd='$onto_name'
-	export GITHEAD_$cmt GITHEAD_$hd
-	if test -n "$GIT_QUIET"
-	then
-		GIT_MERGE_VERBOSITY=1 && export GIT_MERGE_VERBOSITY
-	fi
-	test -z "$strategy" && strategy=recursive
-	eval 'git-merge-$strategy' $strategy_opts '"$cmt^" -- "$hd" "$cmt"'
-	rv=$?
-	case "$rv" in
-	0)
-		unset GITHEAD_$cmt GITHEAD_$hd
-		return
-		;;
-	1)
-		git rerere $allow_rerere_autoupdate
-		die "$resolvemsg"
-		;;
-	2)
-		echo "Strategy: $strategy failed, try another" 1>&2
-		die "$resolvemsg"
-		;;
-	*)
-		die "Unknown exit code ($rv) from command:" \
-			"git-merge-$strategy $cmt^ -- HEAD $cmt"
-		;;
-	esac
-}
-
-finish_rb_merge () {
-	move_to_original_branch
-	if test -s "$state_dir"/rewritten
-	then
-		git notes copy --for-rewrite=rebase <"$state_dir"/rewritten
-		if test -x "$GIT_DIR"/hooks/post-rewrite
-		then
-			"$GIT_DIR"/hooks/post-rewrite rebase <"$state_dir"/rewritten
-		fi
-	fi
-	say All done.
-}
-
-case "$action" in
-continue)
-	read_state
-	continue_merge
-	while test "$msgnum" -le "$end"
-	do
-		call_merge "$msgnum"
-		continue_merge
-	done
-	finish_rb_merge
-	return
-	;;
-skip)
-	read_state
-	git rerere clear
-	msgnum=$(($msgnum + 1))
-	while test "$msgnum" -le "$end"
-	do
-		call_merge "$msgnum"
-		continue_merge
-	done
-	finish_rb_merge
-	return
-	;;
-esac
-
-mkdir -p "$state_dir"
-echo "$onto_name" > "$state_dir/onto_name"
-write_basic_state
-
-msgnum=0
-for cmt in `git rev-list --reverse --no-merges "$revisions"`
-do
-	msgnum=$(($msgnum + 1))
-	echo "$cmt" > "$state_dir/cmt.$msgnum"
-done
-
-echo 1 >"$state_dir/msgnum"
-echo $msgnum >"$state_dir/end"
-
-end=$msgnum
-msgnum=1
-
-while test "$msgnum" -le "$end"
-do
-	call_merge "$msgnum"
-	continue_merge
-done
-
-finish_rb_merge
diff --git a/git-rebase.sh b/git-rebase.sh
index f0291df..7390c59 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -59,7 +59,6 @@ unset onto
 cmd=
 strategy=
 strategy_opts=
-do_merge=
 merge_dir="$GIT_DIR"/rebase-merge
 apply_dir="$GIT_DIR"/rebase-apply
 verbose=
@@ -204,11 +203,8 @@ then
 	then
 		type=interactive
 		interactive_rebase=explicit
-	elif test -f "$merge_dir"/cherrypick
-	then
-		type=cherrypick
 	else
-		type=merge
+		type=cherrypick
 	fi
 	state_dir="$merge_dir"
 fi
@@ -255,18 +251,15 @@ do
 		autosquash=
 		;;
 	-M|-m)
-		do_merge=t
 		;;
 	-X)
 		shift
 		strategy_opts="$strategy_opts $(git rev-parse --sq-quote "--$1")"
-		do_merge=t
 		test -z "$strategy" && strategy=recursive
 		;;
 	-s)
 		shift
 		strategy="$1"
-		do_merge=t
 		;;
 	-n)
 		diffstat=
@@ -411,10 +404,6 @@ if test -n "$interactive_rebase"
 then
 	type=interactive
 	state_dir="$merge_dir"
-elif test -n "$do_merge"
-then
-	type=merge
-	state_dir="$merge_dir"
 elif test -n "$git_am_opt"
 then
 	type=am
diff --git a/t/t3406-rebase-message.sh b/t/t3406-rebase-message.sh
index 0392e36..730e503 100755
--- a/t/t3406-rebase-message.sh
+++ b/t/t3406-rebase-message.sh
@@ -17,20 +17,8 @@ test_expect_success 'setup' '
 	git tag start
 '
 
-cat >expect <<\EOF
-Already applied: 0001 A
-Already applied: 0002 B
-Committed: 0003 Z
-EOF
-
-test_expect_success 'rebase -m' '
-	git rebase -m master >report &&
-	sed -n -e "/^Already applied: /p" \
-		-e "/^Committed: /p" report >actual &&
-	test_cmp expect actual
-'
-
 test_expect_success 'rebase against master twice' '
+	git rebase master &&
 	git rebase master >out &&
 	test_i18ngrep "Current branch topic is up to date" out
 '
diff --git a/t/t3425-rebase-topology-merges.sh b/t/t3425-rebase-topology-merges.sh
index 99b4535..9cd3480 100755
--- a/t/t3425-rebase-topology-merges.sh
+++ b/t/t3425-rebase-topology-merges.sh
@@ -70,9 +70,8 @@ test_run_rebase () {
 		test_linear_range "\'"$expected"\'" d..
 	"
 }
-#TODO: make order consistent across all flavors of rebase
 test_run_rebase success 'n o e' ''
-test_run_rebase success 'e n o' -m
+test_run_rebase success 'n o e' -m
 test_run_rebase success 'n o e' -i
 
 test_run_rebase () {
@@ -87,9 +86,8 @@ test_run_rebase () {
 		test_linear_range "\'"$expected"\'" c..
 	"
 }
-#TODO: make order consistent across all flavors of rebase
 test_run_rebase success 'd n o e' ''
-test_run_rebase success 'd e n o' -m
+test_run_rebase success 'd n o e' -m
 test_run_rebase success 'd n o e' -i
 
 test_run_rebase () {
@@ -104,9 +102,8 @@ test_run_rebase () {
 		test_linear_range "\'"$expected"\'" c..
 	"
 }
-#TODO: make order consistent across all flavors of rebase
 test_run_rebase success 'd n o e' ''
-test_run_rebase success 'd e n o' -m
+test_run_rebase success 'd n o e' -m
 test_run_rebase success 'd n o e' -i
 
 test_expect_success "rebase -p is no-op in non-linear history" "
diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh
index 3c3e4e8..32170bb 100755
--- a/t/t9903-bash-prompt.sh
+++ b/t/t9903-bash-prompt.sh
@@ -158,7 +158,7 @@ test_expect_success 'prompt - interactive rebase' '
 '
 
 test_expect_success 'prompt - rebase merge' '
-	printf " (b2|REBASE-m 1/3)" >expected &&
+	printf " (b2|REBASE 1/3)" > expected &&
 	git checkout b2 &&
 	test_when_finished "git checkout master" &&
 	test_must_fail git rebase --merge b1 b2 &&
-- 
1.8.4-fc

```

## Felipe Contreras, 2013-08-30 05:56

Subject: [PATCH v6 28/28] rebase: cherry-pick: add copyright
Message-ID: <1377842182-18724-29-git-send-email-felipe.contreras@gmail.com>
URL: https://gitlist.dev/e/1377842182-18724-29-git-send-email-felipe.contreras%40gmail.com
In-Reply-To: <1377842182-18724-1-git-send-email-felipe.contreras@gmail.com>

```
Probably enough changes to warrant that.

Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---
 git-rebase--cherrypick.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/git-rebase--cherrypick.sh b/git-rebase--cherrypick.sh
index bda7cfc..da949aa 100644
--- a/git-rebase--cherrypick.sh
+++ b/git-rebase--cherrypick.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# Copyright (c) 2010 Junio C Hamano.
+# Copyright (c) 2013 Felipe Contreras
 #
 
 GIT_CHERRY_PICK_HELP="$resolvemsg"
-- 
1.8.4-fc

```
