{"thread":{"id":"52013","subject":"[PATCH 0/3] sequencer: start running post-commit hook again","startedAt":"2019-10-10T18:36:53Z","lastAt":"2019-10-16T01:32:10Z","messageCount":20,"participants":["Phillip Wood via GitGitGadget","Johannes Schindelin","Junio C Hamano","Phillip Wood"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"383825","messageId":"pull.388.git.gitgitgadget@gmail.com","threadId":"52013","inReplyTo":null,"subject":"[PATCH 0/3] sequencer: start running post-commit hook again","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-10-10T18:36:49Z","receivedAt":"2019-10-10T18:36:53Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"When I converted the sequencer to avoid forking git commit i forgot about\nthe post-commit hook. These patches are based on\npw/rebase-i-show-HEAD-to-reword, otherwise the new test fails as that branch\nchanges the number of commits we make.\n\nPhillip Wood (3):\n  sequencer.h fix placement of #endif\n  sequencer: use run_commit_hook()\n  sequencer: run post-commit hook\n\n builtin/commit.c              | 24 +----------------\n commit.h                      |  3 ---\n sequencer.c                   | 50 +++++++++++++++++++++++++++--------\n sequencer.h                   |  6 +++--\n t/t3404-rebase-interactive.sh | 17 ++++++++++++\n 5 files changed, 61 insertions(+), 39 deletions(-)\n\n\nbase-commit: b0a3186140dbc7bd64cbc6ef733386a0f1eb6a4d\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-388%2Fphillipwood%2Fwip%2Frebase-commit-hooks-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-388/phillipwood/wip/rebase-commit-hooks-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/388\n-- \ngitgitgadget\n"},{"id":"383826","messageId":"420ecf442c729878da5219f3c718dd136e4fa2b4.1570732608.git.gitgitgadget@gmail.com","threadId":"52013","inReplyTo":"pull.388.git.gitgitgadget@gmail.com","subject":"[PATCH 2/3] sequencer: use run_commit_hook()","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-10-10T18:36:50Z","receivedAt":"2019-10-10T18:36:54Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThis simplifies the implementation of run_prepare_commit_msg_hook() and\nwill be used in the next commit.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/commit.c | 22 ----------------------\n commit.h         |  3 ---\n sequencer.c      | 45 ++++++++++++++++++++++++++++++++++-----------\n sequencer.h      |  2 ++\n 4 files changed, 36 insertions(+), 36 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 1921401117..d898a57f5d 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1443,28 +1443,6 @@ static int git_commit_config(const char *k, const char *v, void *cb)\n \treturn git_status_config(k, v, s);\n }\n \n-int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...)\n-{\n-\tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n-\tva_list args;\n-\tint ret;\n-\n-\targv_array_pushf(&hook_env, \"GIT_INDEX_FILE=%s\", index_file);\n-\n-\t/*\n-\t * Let the hook know that no editor will be launched.\n-\t */\n-\tif (!editor_is_used)\n-\t\targv_array_push(&hook_env, \"GIT_EDITOR=:\");\n-\n-\tva_start(args, name);\n-\tret = run_hook_ve(hook_env.argv,name, args);\n-\tva_end(args);\n-\targv_array_clear(&hook_env);\n-\n-\treturn ret;\n-}\n-\n int cmd_commit(int argc, const char **argv, const char *prefix)\n {\n \tconst char *argv_gc_auto[] = {\"gc\", \"--auto\", NULL};\ndiff --git a/commit.h b/commit.h\nindex f5295ca7f3..37684a35f0 100644\n--- a/commit.h\n+++ b/commit.h\n@@ -389,7 +389,4 @@ void verify_merge_signature(struct commit *commit, int verbose);\n int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused);\n int compare_commits_by_gen_then_commit_date(const void *a_, const void *b_, void *unused);\n \n-LAST_ARG_MUST_BE_NULL\n-int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n-\n #endif /* COMMIT_H */\ndiff --git a/sequencer.c b/sequencer.c\nindex 2adcf5a639..3ce578c40b 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -1123,28 +1123,51 @@ void commit_post_rewrite(struct repository *r,\n \trun_rewrite_hook(&old_head->object.oid, new_head);\n }\n \n+int run_commit_hook(int editor_is_used, const char *index_file,\n+\t\t    const char *name, ...)\n+{\n+\tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n+\tva_list args;\n+\tint ret;\n+\n+\targv_array_pushf(&hook_env, \"GIT_INDEX_FILE=%s\", index_file);\n+\n+\t/*\n+\t * Let the hook know that no editor will be launched.\n+\t */\n+\tif (!editor_is_used)\n+\t\targv_array_push(&hook_env, \"GIT_EDITOR=:\");\n+\n+\tva_start(args, name);\n+\tret = run_hook_ve(hook_env.argv,name, args);\n+\tva_end(args);\n+\targv_array_clear(&hook_env);\n+\n+\treturn ret;\n+}\n+\n static int run_prepare_commit_msg_hook(struct repository *r,\n \t\t\t\t       struct strbuf *msg,\n \t\t\t\t       const char *commit)\n {\n \tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n-\tint ret;\n-\tconst char *name;\n+\tint ret = 0;\n+\tconst char *name, *arg1 = NULL, *arg2 = NULL;\n \n \tname = git_path_commit_editmsg();\n \tif (write_message(msg->buf, msg->len, name, 0))\n \t\treturn -1;\n \n-\targv_array_pushf(&hook_env, \"GIT_INDEX_FILE=%s\", r->index_file);\n-\targv_array_push(&hook_env, \"GIT_EDITOR=:\");\n-\tif (commit)\n-\t\tret = run_hook_le(hook_env.argv, \"prepare-commit-msg\", name,\n-\t\t\t\t  \"commit\", commit, NULL);\n-\telse\n-\t\tret = run_hook_le(hook_env.argv, \"prepare-commit-msg\", name,\n-\t\t\t\t  \"message\", NULL);\n-\tif (ret)\n+\tif (commit) {\n+\t\targ1 = \"commit\";\n+\t\targ2 = commit;\n+\t} else {\n+\t\targ1 = \"message\";\n+\t}\n+\tif (run_commit_hook(0, r->index_file, \"prepare-commit-msg\", name,\n+\t\t\t    arg1, arg2, NULL))\n \t\tret = error(_(\"'prepare-commit-msg' hook failed\"));\n+\n \targv_array_clear(&hook_env);\n \n \treturn ret;\ndiff --git a/sequencer.h b/sequencer.h\nindex ac66892d71..b0419d6ddb 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -201,4 +201,6 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,\n void sequencer_post_commit_cleanup(struct repository *r);\n int sequencer_get_last_command(struct repository* r,\n \t\t\t       enum replay_action *action);\n+LAST_ARG_MUST_BE_NULL\n+int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n #endif /* SEQUENCER_H */\n-- \ngitgitgadget\n\n"},{"id":"383828","messageId":"7305f8d8e81b856ba535aaafe97c708d80567566.1570732608.git.gitgitgadget@gmail.com","threadId":"52013","inReplyTo":"pull.388.git.gitgitgadget@gmail.com","subject":"[PATCH 1/3] sequencer.h fix placement of #endif","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-10-10T18:36:50Z","receivedAt":"2019-10-10T18:36:54Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nCommit 65850686cf (\"rebase -i: rewrite write_basic_state() in C\",\n2018-08-28) accidentially added new function declarations after\nthe #endif at the end of the include guard.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n sequencer.h | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/sequencer.h b/sequencer.h\nindex 0c494b83d4..ac66892d71 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -195,11 +195,10 @@ void print_commit_summary(struct repository *repo,\n \n int read_author_script(const char *path, char **name, char **email, char **date,\n \t\t       int allow_missing);\n-#endif\n-\n void parse_strategy_opts(struct replay_opts *opts, char *raw_opts);\n int write_basic_state(struct replay_opts *opts, const char *head_name,\n \t\t      struct commit *onto, const char *orig_head);\n void sequencer_post_commit_cleanup(struct repository *r);\n int sequencer_get_last_command(struct repository* r,\n \t\t\t       enum replay_action *action);\n+#endif /* SEQUENCER_H */\n-- \ngitgitgadget\n\n"},{"id":"383827","messageId":"acaa086a4860b6853bc0f35dae7fcf07d3aa59e7.1570732608.git.gitgitgadget@gmail.com","threadId":"52013","inReplyTo":"pull.388.git.gitgitgadget@gmail.com","subject":"[PATCH 3/3] sequencer: run post-commit hook","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-10-10T18:36:51Z","receivedAt":"2019-10-10T18:36:55Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nPrior to commit 356ee4659b (\"sequencer: try to commit without forking\n'git commit'\", 2017-11-24) the sequencer would always run the\npost-commit hook after each pick or revert as it forked `git commit` to\ncreate the commit. The conversion to committing without forking `git\ncommit` omitted to call the post-commit hook after creating the commit.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/commit.c              |  2 +-\n sequencer.c                   |  5 +++++\n sequencer.h                   |  1 +\n t/t3404-rebase-interactive.sh | 17 +++++++++++++++++\n 4 files changed, 24 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex d898a57f5d..adb8c89c60 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1653,7 +1653,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \n \trepo_rerere(the_repository, 0);\n \trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n-\trun_commit_hook(use_editor, get_index_file(), \"post-commit\", NULL);\n+\trun_post_commit_hook(use_editor, get_index_file());\n \tif (amend && !no_post_rewrite) {\n \t\tcommit_post_rewrite(the_repository, current_head, &oid);\n \t}\ndiff --git a/sequencer.c b/sequencer.c\nindex 3ce578c40b..b4947f6969 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -1173,6 +1173,10 @@ static int run_prepare_commit_msg_hook(struct repository *r,\n \treturn ret;\n }\n \n+void run_post_commit_hook(int editor_is_used, const char *index_file) {\n+\trun_commit_hook(editor_is_used, index_file, \"post-commit\", NULL);\n+}\n+\n static const char implicit_ident_advice_noconfig[] =\n N_(\"Your name and email address were configured automatically based\\n\"\n \"on your username and hostname. Please check that they are accurate.\\n\"\n@@ -1427,6 +1431,7 @@ static int try_to_commit(struct repository *r,\n \t\tgoto out;\n \t}\n \n+\trun_post_commit_hook(0, r->index_file);\n \tif (flags & AMEND_MSG)\n \t\tcommit_post_rewrite(r, current_head, oid);\n \ndiff --git a/sequencer.h b/sequencer.h\nindex b0419d6ddb..e3e73c5635 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -203,4 +203,5 @@ int sequencer_get_last_command(struct repository* r,\n \t\t\t       enum replay_action *action);\n LAST_ARG_MUST_BE_NULL\n int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n+void run_post_commit_hook(int editor_is_used, const char *index_file);\n #endif /* SEQUENCER_H */\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex d2f1d5bd23..d9217235b6 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -1467,4 +1467,21 @@ test_expect_success 'valid author header when author contains single quote' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success 'post-commit hook is called' '\n+\ttest_when_finished \"rm -f .git/hooks/post-commit commits\" &&\n+\tmkdir -p .git/hooks &&\n+\twrite_script .git/hooks/post-commit <<-\\EOS &&\n+\tgit rev-parse HEAD >>commits\n+\tEOS\n+\tset_fake_editor &&\n+\tFAKE_LINES=\"edit 4 1 reword 2 fixup 3\" git rebase -i A E &&\n+\techo x>file3 &&\n+\tgit add file3 &&\n+\tFAKE_COMMIT_MESSAGE=edited git rebase --continue &&\n+\t# rev-list does not support -g --reverse\n+\tgit rev-list --no-walk=unsorted HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} \\\n+\t\tHEAD@{1} HEAD >expected &&\n+\ttest_cmp expected commits\n+'\n+\n test_done\n-- \ngitgitgadget\n"},{"id":"383841","messageId":"nycvar.QRO.7.76.6.1910102314390.46@tvgsbejvaqbjf.bet","threadId":"52013","inReplyTo":"420ecf442c729878da5219f3c718dd136e4fa2b4.1570732608.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/3] sequencer: use run_commit_hook()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2019-10-10T21:15:52Z","receivedAt":"2019-10-10T21:16:19Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Phillip,\n\nOn Thu, 10 Oct 2019, Phillip Wood via GitGitGadget wrote:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> This simplifies the implementation of run_prepare_commit_msg_hook() and\n> will be used in the next commit.\n>\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> ---\n>  builtin/commit.c | 22 ----------------------\n>  commit.h         |  3 ---\n>  sequencer.c      | 45 ++++++++++++++++++++++++++++++++++-----------\n>  sequencer.h      |  2 ++\n>  4 files changed, 36 insertions(+), 36 deletions(-)\n\nHmm. I would have thought that `commit.c` would be a more logical home\nfor that function (and that the declaration could remain in `commit.h`)?\n\nThe general thrust is good, of course: `commit.h` is supposedly a\n`libgit.a` header, but `builtin/commit.o` is _not_ included in\n`libgit.a`...\n\nThanks,\nDscho\n\n>\n> diff --git a/builtin/commit.c b/builtin/commit.c\n> index 1921401117..d898a57f5d 100644\n> --- a/builtin/commit.c\n> +++ b/builtin/commit.c\n> @@ -1443,28 +1443,6 @@ static int git_commit_config(const char *k, const char *v, void *cb)\n>  \treturn git_status_config(k, v, s);\n>  }\n>\n> -int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...)\n> -{\n> -\tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n> -\tva_list args;\n> -\tint ret;\n> -\n> -\targv_array_pushf(&hook_env, \"GIT_INDEX_FILE=%s\", index_file);\n> -\n> -\t/*\n> -\t * Let the hook know that no editor will be launched.\n> -\t */\n> -\tif (!editor_is_used)\n> -\t\targv_array_push(&hook_env, \"GIT_EDITOR=:\");\n> -\n> -\tva_start(args, name);\n> -\tret = run_hook_ve(hook_env.argv,name, args);\n> -\tva_end(args);\n> -\targv_array_clear(&hook_env);\n> -\n> -\treturn ret;\n> -}\n> -\n>  int cmd_commit(int argc, const char **argv, const char *prefix)\n>  {\n>  \tconst char *argv_gc_auto[] = {\"gc\", \"--auto\", NULL};\n> diff --git a/commit.h b/commit.h\n> index f5295ca7f3..37684a35f0 100644\n> --- a/commit.h\n> +++ b/commit.h\n> @@ -389,7 +389,4 @@ void verify_merge_signature(struct commit *commit, int verbose);\n>  int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused);\n>  int compare_commits_by_gen_then_commit_date(const void *a_, const void *b_, void *unused);\n>\n> -LAST_ARG_MUST_BE_NULL\n> -int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n> -\n>  #endif /* COMMIT_H */\n> diff --git a/sequencer.c b/sequencer.c\n> index 2adcf5a639..3ce578c40b 100644\n> --- a/sequencer.c\n> +++ b/sequencer.c\n> @@ -1123,28 +1123,51 @@ void commit_post_rewrite(struct repository *r,\n>  \trun_rewrite_hook(&old_head->object.oid, new_head);\n>  }\n>\n> +int run_commit_hook(int editor_is_used, const char *index_file,\n> +\t\t    const char *name, ...)\n> +{\n> +\tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n> +\tva_list args;\n> +\tint ret;\n> +\n> +\targv_array_pushf(&hook_env, \"GIT_INDEX_FILE=%s\", index_file);\n> +\n> +\t/*\n> +\t * Let the hook know that no editor will be launched.\n> +\t */\n> +\tif (!editor_is_used)\n> +\t\targv_array_push(&hook_env, \"GIT_EDITOR=:\");\n> +\n> +\tva_start(args, name);\n> +\tret = run_hook_ve(hook_env.argv,name, args);\n> +\tva_end(args);\n> +\targv_array_clear(&hook_env);\n> +\n> +\treturn ret;\n> +}\n> +\n>  static int run_prepare_commit_msg_hook(struct repository *r,\n>  \t\t\t\t       struct strbuf *msg,\n>  \t\t\t\t       const char *commit)\n>  {\n>  \tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n> -\tint ret;\n> -\tconst char *name;\n> +\tint ret = 0;\n> +\tconst char *name, *arg1 = NULL, *arg2 = NULL;\n>\n>  \tname = git_path_commit_editmsg();\n>  \tif (write_message(msg->buf, msg->len, name, 0))\n>  \t\treturn -1;\n>\n> -\targv_array_pushf(&hook_env, \"GIT_INDEX_FILE=%s\", r->index_file);\n> -\targv_array_push(&hook_env, \"GIT_EDITOR=:\");\n> -\tif (commit)\n> -\t\tret = run_hook_le(hook_env.argv, \"prepare-commit-msg\", name,\n> -\t\t\t\t  \"commit\", commit, NULL);\n> -\telse\n> -\t\tret = run_hook_le(hook_env.argv, \"prepare-commit-msg\", name,\n> -\t\t\t\t  \"message\", NULL);\n> -\tif (ret)\n> +\tif (commit) {\n> +\t\targ1 = \"commit\";\n> +\t\targ2 = commit;\n> +\t} else {\n> +\t\targ1 = \"message\";\n> +\t}\n> +\tif (run_commit_hook(0, r->index_file, \"prepare-commit-msg\", name,\n> +\t\t\t    arg1, arg2, NULL))\n>  \t\tret = error(_(\"'prepare-commit-msg' hook failed\"));\n> +\n>  \targv_array_clear(&hook_env);\n>\n>  \treturn ret;\n> diff --git a/sequencer.h b/sequencer.h\n> index ac66892d71..b0419d6ddb 100644\n> --- a/sequencer.h\n> +++ b/sequencer.h\n> @@ -201,4 +201,6 @@ int write_basic_state(struct replay_opts *opts, const char *head_name,\n>  void sequencer_post_commit_cleanup(struct repository *r);\n>  int sequencer_get_last_command(struct repository* r,\n>  \t\t\t       enum replay_action *action);\n> +LAST_ARG_MUST_BE_NULL\n> +int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n>  #endif /* SEQUENCER_H */\n> --\n> gitgitgadget\n>\n>\n"},{"id":"383842","messageId":"nycvar.QRO.7.76.6.1910102324140.46@tvgsbejvaqbjf.bet","threadId":"52013","inReplyTo":"acaa086a4860b6853bc0f35dae7fcf07d3aa59e7.1570732608.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 3/3] sequencer: run post-commit hook","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2019-10-10T21:31:38Z","receivedAt":"2019-10-10T21:32:07Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Phillip,\n\nOn Thu, 10 Oct 2019, Phillip Wood via GitGitGadget wrote:\n\n> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n> Prior to commit 356ee4659b (\"sequencer: try to commit without forking\n> 'git commit'\", 2017-11-24) the sequencer would always run the\n> post-commit hook after each pick or revert as it forked `git commit` to\n> create the commit. The conversion to committing without forking `git\n> commit` omitted to call the post-commit hook after creating the commit.\n>\n> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nMakes sense.\n\n> ---\n>  builtin/commit.c              |  2 +-\n>  sequencer.c                   |  5 +++++\n>  sequencer.h                   |  1 +\n>  t/t3404-rebase-interactive.sh | 17 +++++++++++++++++\n>  4 files changed, 24 insertions(+), 1 deletion(-)\n>\n> diff --git a/builtin/commit.c b/builtin/commit.c\n> index d898a57f5d..adb8c89c60 100644\n> --- a/builtin/commit.c\n> +++ b/builtin/commit.c\n> @@ -1653,7 +1653,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>\n>  \trepo_rerere(the_repository, 0);\n>  \trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n> -\trun_commit_hook(use_editor, get_index_file(), \"post-commit\", NULL);\n> +\trun_post_commit_hook(use_editor, get_index_file());\n\nDoes it really make sense to abstract the hook name away? It adds a lot\nof churn for just two callers...\n\n>  \tif (amend && !no_post_rewrite) {\n>  \t\tcommit_post_rewrite(the_repository, current_head, &oid);\n>  \t}\n> diff --git a/sequencer.c b/sequencer.c\n> index 3ce578c40b..b4947f6969 100644\n> --- a/sequencer.c\n> +++ b/sequencer.c\n> @@ -1173,6 +1173,10 @@ static int run_prepare_commit_msg_hook(struct repository *r,\n>  \treturn ret;\n>  }\n>\n> +void run_post_commit_hook(int editor_is_used, const char *index_file) {\n> +\trun_commit_hook(editor_is_used, index_file, \"post-commit\", NULL);\n> +}\n> +\n\nIf we must have a separate `run_post_commit_hook()`, then it should be\nan `inline` function, defined in the header. Or even a macro to begin\nwith.\n\n>  static const char implicit_ident_advice_noconfig[] =\n>  N_(\"Your name and email address were configured automatically based\\n\"\n>  \"on your username and hostname. Please check that they are accurate.\\n\"\n> @@ -1427,6 +1431,7 @@ static int try_to_commit(struct repository *r,\n>  \t\tgoto out;\n>  \t}\n>\n> +\trun_post_commit_hook(0, r->index_file);\n\nSo this is the _actual_ change of this patch.\n\n>  \tif (flags & AMEND_MSG)\n>  \t\tcommit_post_rewrite(r, current_head, oid);\n>\n> diff --git a/sequencer.h b/sequencer.h\n> index b0419d6ddb..e3e73c5635 100644\n> --- a/sequencer.h\n> +++ b/sequencer.h\n> @@ -203,4 +203,5 @@ int sequencer_get_last_command(struct repository* r,\n>  \t\t\t       enum replay_action *action);\n>  LAST_ARG_MUST_BE_NULL\n>  int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n> +void run_post_commit_hook(int editor_is_used, const char *index_file);\n>  #endif /* SEQUENCER_H */\n> diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\n> index d2f1d5bd23..d9217235b6 100755\n> --- a/t/t3404-rebase-interactive.sh\n> +++ b/t/t3404-rebase-interactive.sh\n> @@ -1467,4 +1467,21 @@ test_expect_success 'valid author header when author contains single quote' '\n>  \ttest_cmp expected actual\n>  '\n>\n> +test_expect_success 'post-commit hook is called' '\n> +\ttest_when_finished \"rm -f .git/hooks/post-commit commits\" &&\n> +\tmkdir -p .git/hooks &&\n> +\twrite_script .git/hooks/post-commit <<-\\EOS &&\n> +\tgit rev-parse HEAD >>commits\n\nShould `commits` be initialized before this script is written, e.g.\nusing\n\n\t>commits &&\n\n?\n\n> +\tEOS\n> +\tset_fake_editor &&\n\nThe `set_fake_editor` function sets a global environment variable, and\ntherefore needs to be run in a subshell. Therefore, this line (as well\nas the next one) need to be enclosed in `( ... )`.\n\n> +\tFAKE_LINES=\"edit 4 1 reword 2 fixup 3\" git rebase -i A E &&\n> +\techo x>file3 &&\n\nWe usually leave no space after the `>`, but we _do_ leave a space\n_before_ the `>`.\n\n> +\tgit add file3 &&\n> +\tFAKE_COMMIT_MESSAGE=edited git rebase --continue &&\n> +\t# rev-list does not support -g --reverse\n> +\tgit rev-list --no-walk=unsorted HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} \\\n> +\t\tHEAD@{1} HEAD >expected &&\n\nWouldn't this be better as:\n\n\tgit rev-parse HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} HEAD@{1} HEAD \\\n\t\t>expect &&\n\n> +\ttest_cmp expected commits\n\nWe usually use the name `expect` instead of `expected` in the test\nsuite.\n\nThanks,\nDscho\n\n> +'\n> +\n>  test_done\n> --\n> gitgitgadget\n>\n"},{"id":"383861","messageId":"xmqqk19bj4dk.fsf@gitster-ct.c.googlers.com","threadId":"52013","inReplyTo":"nycvar.QRO.7.76.6.1910102314390.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH 2/3] sequencer: use run_commit_hook()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-10-11T04:24:55Z","receivedAt":"2019-10-11T04:26:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>>  builtin/commit.c | 22 ----------------------\n>>  commit.h         |  3 ---\n>>  sequencer.c      | 45 ++++++++++++++++++++++++++++++++++-----------\n>>  sequencer.h      |  2 ++\n>>  4 files changed, 36 insertions(+), 36 deletions(-)\n>\n> Hmm. I would have thought that `commit.c` would be a more logical home\n> for that function (and that the declaration could remain in `commit.h`)?\n\nGood correction.\n\nThanks.\n"},{"id":"383862","messageId":"xmqqftjzj49u.fsf@gitster-ct.c.googlers.com","threadId":"52013","inReplyTo":"nycvar.QRO.7.76.6.1910102324140.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH 3/3] sequencer: run post-commit hook","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-10-11T04:27:09Z","receivedAt":"2019-10-11T04:27:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> diff --git a/builtin/commit.c b/builtin/commit.c\n>> index d898a57f5d..adb8c89c60 100644\n>> --- a/builtin/commit.c\n>> +++ b/builtin/commit.c\n>> @@ -1653,7 +1653,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>>\n>>  \trepo_rerere(the_repository, 0);\n>>  \trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n>> -\trun_commit_hook(use_editor, get_index_file(), \"post-commit\", NULL);\n>> +\trun_post_commit_hook(use_editor, get_index_file());\n>\n> Does it really make sense to abstract the hook name away? It adds a lot\n> of churn for just two callers...\n\nAfter looking at the three patches, I do not think so.\n\n>> diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\n>> index d2f1d5bd23..d9217235b6 100755\n>> --- a/t/t3404-rebase-interactive.sh\n>> +++ b/t/t3404-rebase-interactive.sh\n>> @@ -1467,4 +1467,21 @@ test_expect_success 'valid author header when author contains single quote' '\n>>  \ttest_cmp expected actual\n>>  '\n>>\n>> +test_expect_success 'post-commit hook is called' '\n>> +\ttest_when_finished \"rm -f .git/hooks/post-commit commits\" &&\n>> +\tmkdir -p .git/hooks &&\n>> +\twrite_script .git/hooks/post-commit <<-\\EOS &&\n>> +\tgit rev-parse HEAD >>commits\n>\n> Should `commits` be initialized before this script is written, e.g.\n> using\n>\n> \t>commits &&\n\nYes.\n\n>> +\tgit rev-list --no-walk=unsorted HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} \\\n>> +\t\tHEAD@{1} HEAD >expected &&\n>\n> Wouldn't this be better as:\n>\n> \tgit rev-parse HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} HEAD@{1} HEAD \\\n> \t\t>expect &&\n>\n\nYes.\n\n>> +\ttest_cmp expected commits\n>\n> We usually use the name `expect` instead of `expected` in the test\n> suite.\n\nAnd the actual output file is called 'actual'.\n\nThanks.\n"},{"id":"383892","messageId":"0692ed53-6ea4-18d4-ce60-7fbd82d2685c@gmail.com","threadId":"52013","inReplyTo":"nycvar.QRO.7.76.6.1910102324140.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH 3/3] sequencer: run post-commit hook","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2019-10-11T15:39:10Z","receivedAt":"2019-10-11T15:39:18Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Dscho\n\nOn 10/10/2019 22:31, Johannes Schindelin wrote:\n> Hi Phillip,\n> \n> On Thu, 10 Oct 2019, Phillip Wood via GitGitGadget wrote:\n> \n>> From: Phillip Wood <phillip.wood@dunelm.org.uk>\n>>\n>> Prior to commit 356ee4659b (\"sequencer: try to commit without forking\n>> 'git commit'\", 2017-11-24) the sequencer would always run the\n>> post-commit hook after each pick or revert as it forked `git commit` to\n>> create the commit. The conversion to committing without forking `git\n>> commit` omitted to call the post-commit hook after creating the commit.\n>>\n>> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n> \n> Makes sense.\n> \n>> ---\n>>   builtin/commit.c              |  2 +-\n>>   sequencer.c                   |  5 +++++\n>>   sequencer.h                   |  1 +\n>>   t/t3404-rebase-interactive.sh | 17 +++++++++++++++++\n>>   4 files changed, 24 insertions(+), 1 deletion(-)\n>>\n>> diff --git a/builtin/commit.c b/builtin/commit.c\n>> index d898a57f5d..adb8c89c60 100644\n>> --- a/builtin/commit.c\n>> +++ b/builtin/commit.c\n>> @@ -1653,7 +1653,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n>>\n>>   \trepo_rerere(the_repository, 0);\n>>   \trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n>> -\trun_commit_hook(use_editor, get_index_file(), \"post-commit\", NULL);\n>> +\trun_post_commit_hook(use_editor, get_index_file());\n> \n> Does it really make sense to abstract the hook name away? It adds a lot\n> of churn for just two callers...\n\nI'll drop the new function in the reroll\n\n>>   \tif (amend && !no_post_rewrite) {\n>>   \t\tcommit_post_rewrite(the_repository, current_head, &oid);\n>>   \t}\n>> diff --git a/sequencer.c b/sequencer.c\n>> index 3ce578c40b..b4947f6969 100644\n>> --- a/sequencer.c\n>> +++ b/sequencer.c\n>> @@ -1173,6 +1173,10 @@ static int run_prepare_commit_msg_hook(struct repository *r,\n>>   \treturn ret;\n>>   }\n>>\n>> +void run_post_commit_hook(int editor_is_used, const char *index_file) {\n>> +\trun_commit_hook(editor_is_used, index_file, \"post-commit\", NULL);\n>> +}\n>> +\n> \n> If we must have a separate `run_post_commit_hook()`, then it should be\n> an `inline` function, defined in the header. Or even a macro to begin\n> with.\n> \n>>   static const char implicit_ident_advice_noconfig[] =\n>>   N_(\"Your name and email address were configured automatically based\\n\"\n>>   \"on your username and hostname. Please check that they are accurate.\\n\"\n>> @@ -1427,6 +1431,7 @@ static int try_to_commit(struct repository *r,\n>>   \t\tgoto out;\n>>   \t}\n>>\n>> +\trun_post_commit_hook(0, r->index_file);\n> \n> So this is the _actual_ change of this patch.\n> \n>>   \tif (flags & AMEND_MSG)\n>>   \t\tcommit_post_rewrite(r, current_head, oid);\n>>\n>> diff --git a/sequencer.h b/sequencer.h\n>> index b0419d6ddb..e3e73c5635 100644\n>> --- a/sequencer.h\n>> +++ b/sequencer.h\n>> @@ -203,4 +203,5 @@ int sequencer_get_last_command(struct repository* r,\n>>   \t\t\t       enum replay_action *action);\n>>   LAST_ARG_MUST_BE_NULL\n>>   int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n>> +void run_post_commit_hook(int editor_is_used, const char *index_file);\n>>   #endif /* SEQUENCER_H */\n>> diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\n>> index d2f1d5bd23..d9217235b6 100755\n>> --- a/t/t3404-rebase-interactive.sh\n>> +++ b/t/t3404-rebase-interactive.sh\n>> @@ -1467,4 +1467,21 @@ test_expect_success 'valid author header when author contains single quote' '\n>>   \ttest_cmp expected actual\n>>   '\n>>\n>> +test_expect_success 'post-commit hook is called' '\n>> +\ttest_when_finished \"rm -f .git/hooks/post-commit commits\" &&\n>> +\tmkdir -p .git/hooks &&\n>> +\twrite_script .git/hooks/post-commit <<-\\EOS &&\n>> +\tgit rev-parse HEAD >>commits\n> \n> Should `commits` be initialized before this script is written, e.g.\n> using\n> \n> \t>commits &&\n\nGood point, especially if it is renamed to actual as Junio suggests\n\n>> +\tEOS\n>> +\tset_fake_editor &&\n> \n> The `set_fake_editor` function sets a global environment variable, and\n> therefore needs to be run in a subshell. Therefore, this line (as well\n> as the next one) need to be enclosed in `( ... )`.\n\nThere are ~80 instances of \nset_fake_editor/test_set_editor/set_cat_todo_editor in that file that \nare not in subshells. I've converted them in a preparatory patch (that \nwas fun), removing about 20 that can now safely rely on EDITOR=: \n(hopefully that will ameliorate the performance hit of ~60 extra \nsubshells a little)\n\n>> +\tFAKE_LINES=\"edit 4 1 reword 2 fixup 3\" git rebase -i A E &&\n>> +\techo x>file3 &&\n> \n> We usually leave no space after the `>`, but we _do_ leave a space\n> _before_ the `>`.\n> \n>> +\tgit add file3 &&\n>> +\tFAKE_COMMIT_MESSAGE=edited git rebase --continue &&\n>> +\t# rev-list does not support -g --reverse\n>> +\tgit rev-list --no-walk=unsorted HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} \\\n>> +\t\tHEAD@{1} HEAD >expected &&\n> \n> Wouldn't this be better as:\n> \n> \tgit rev-parse HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} HEAD@{1} HEAD \\\n> \t\t>expect &&\n\nGood point\n\n>> +\ttest_cmp expected commits\n> \n> We usually use the name `expect` instead of `expected` in the test\n> suite.\n\nOK\n\nThanks for looking at this series\n\nPhillip\n\n> Thanks,\n> Dscho\n> \n>> +'\n>> +\n>>   test_done\n>> --\n>> gitgitgadget\n>>\n"},{"id":"384018","messageId":"7a56faf1-a0e3-98ad-bdfe-e9ba0b97b5c2@gmail.com","threadId":"52013","inReplyTo":"xmqqk19bj4dk.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH 2/3] sequencer: use run_commit_hook()","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2019-10-14T13:26:45Z","receivedAt":"2019-10-14T13:26:48Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"Hi Dscho & Junio\n\nOn 11/10/2019 05:24, Junio C Hamano wrote:\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n>>>  builtin/commit.c | 22 ----------------------\n>>>  commit.h         |  3 ---\n>>>  sequencer.c      | 45 ++++++++++++++++++++++++++++++++++-----------\n>>>  sequencer.h      |  2 ++\n>>>  4 files changed, 36 insertions(+), 36 deletions(-)\n>>\n>> Hmm. I would have thought that `commit.c` would be a more logical home\n>> for that function (and that the declaration could remain in `commit.h`)?\n> \n> Good correction.\n\nThere are some other public commit related functions in sequencer.c -\nprint_commit_summary(), commit_post_rewrite(), rest_is_empty(),\ncleanup_message(), message_is_empty(), template_untouched(),\nupdate_head_with_reflog() . Would you like to see them moved to commit.c\n(probably as a separate series)?\n\nBest Wishes\n\nPhillip\n\n> \n> Thanks.\n> \n\n"},{"id":"384044","messageId":"nycvar.QRO.7.76.6.1910150013010.46@tvgsbejvaqbjf.bet","threadId":"52013","inReplyTo":"7a56faf1-a0e3-98ad-bdfe-e9ba0b97b5c2@gmail.com","subject":"Re: [PATCH 2/3] sequencer: use run_commit_hook()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2019-10-14T22:14:32Z","receivedAt":"2019-10-14T22:15:00Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Phillip,\n\nOn Mon, 14 Oct 2019, Phillip Wood wrote:\n\n> Hi Dscho & Junio\n>\n> On 11/10/2019 05:24, Junio C Hamano wrote:\n> > Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> >\n> >>>  builtin/commit.c | 22 ----------------------\n> >>>  commit.h         |  3 ---\n> >>>  sequencer.c      | 45 ++++++++++++++++++++++++++++++++++-----------\n> >>>  sequencer.h      |  2 ++\n> >>>  4 files changed, 36 insertions(+), 36 deletions(-)\n> >>\n> >> Hmm. I would have thought that `commit.c` would be a more logical home\n> >> for that function (and that the declaration could remain in `commit.h`)?\n> >\n> > Good correction.\n>\n> There are some other public commit related functions in sequencer.c -\n> print_commit_summary(), commit_post_rewrite(), rest_is_empty(),\n> cleanup_message(), message_is_empty(), template_untouched(),\n> update_head_with_reflog() . Would you like to see them moved to commit.c\n> (probably as a separate series)?\n\nI don't think that it is necessary to move any of those functions out of\ntheir existing habitat just yet. While I haven't looked more closely\nwhich of these functions are specific to the sequencer and which are\nmore generic, I would argue that moving any of them is outside of the\ngoals of your patch series.\n\nThanks,\nDscho\n"},{"id":"384074","messageId":"b9689e85e593062f4d82cb955f36c8ef65ad0c4e.1571135132.git.gitgitgadget@gmail.com","threadId":"52013","inReplyTo":"pull.388.v2.git.1571135132.gitgitgadget@gmail.com","subject":"[PATCH v2 1/6] t3404: remove unnecessary subshell","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-10-15T10:25:27Z","receivedAt":"2019-10-15T10:25:38Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nNeither of the commands executed in the subshell change any shell\nvariables or the current directory so there is no need for them to be\nexecuted in a subshell.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n t/t3404-rebase-interactive.sh | 6 ++----\n 1 file changed, 2 insertions(+), 4 deletions(-)\n\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex d2f1d5bd23..c26b3362ef 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -945,10 +945,8 @@ test_expect_success C_LOCALE_OUTPUT 'rebase -ix with --autosquash' '\n \tgit add bis.txt &&\n \tgit commit -m \"fixup! two_exec\" &&\n \tset_fake_editor &&\n-\t(\n-\t\tgit checkout -b autosquash_actual &&\n-\t\tgit rebase -i --exec \"git show HEAD\" --autosquash HEAD~4 >actual\n-\t) &&\n+\tgit checkout -b autosquash_actual &&\n+\tgit rebase -i --exec \"git show HEAD\" --autosquash HEAD~4 >actual &&\n \tgit checkout autosquash &&\n \t(\n \t\tgit checkout -b autosquash_expected &&\n-- \ngitgitgadget\n\n"},{"id":"384075","messageId":"96432cd0f005aa7ef6865af535682c4607a27b33.1571135132.git.gitgitgadget@gmail.com","threadId":"52013","inReplyTo":"pull.388.v2.git.1571135132.gitgitgadget@gmail.com","subject":"[PATCH v2 2/6] t3404: set $EDITOR in subshell","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-10-15T10:25:28Z","receivedAt":"2019-10-15T10:25:41Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nAs $EDITOR is exported setting it in one test affects all subsequent\ntests. Avoid this by always setting it in a subshell. This commit leaves\n20 calls to set_fake_editor that are not in subshells as they can\nsafely be removed in the next commit once all the other editor setting\nis done inside subshells.\n\nI have moved the call to set_fake_editor in some tests so it comes\nimmediately before the call to 'git rebase' to avoid moving unrelated\ncommands into the subshell. In one case ('rebase -ix with\n--autosquash') the call to set_fake_editor is moved past an invocation\nof 'git rebase'. This is safe as that invocation of 'git rebase'\nrequires EDITOR=: or EDITOR=fake-editor.sh without FAKE_LINES being\nset which will be the case as the preceding tests either set their\neditor in a subshell or call set_fake_editor without setting FAKE_LINES.\n\nIn a one test ('auto-amend only edited commits after \"edit\"') a call\nto test_tick are now in a subshell. I think this is OK as it is there\nto set the date for the next commit which is executed in the same\nsubshell rather than updating GIT_COMMITTER_DATE for later tests (the\nnext test calls test_tick before doing anything else).\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n t/t3404-rebase-interactive.sh | 546 +++++++++++++++++++++-------------\n 1 file changed, 342 insertions(+), 204 deletions(-)\n\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex c26b3362ef..cb9b210000 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -79,8 +79,11 @@ test_expect_success 'rebase -i with empty HEAD' '\n \tcat >expect <<-\\EOF &&\n \terror: nothing to do\n \tEOF\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"1 exec_true\" git rebase -i HEAD^ >actual 2>&1 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"1 exec_true\" \\\n+\t\t\tgit rebase -i HEAD^ >actual 2>&1\n+\t) &&\n \ttest_i18ncmp expect actual\n '\n \n@@ -139,8 +142,11 @@ test_expect_success 'rebase -i sets work tree properly' '\n \n test_expect_success 'rebase -i with the exec command checks tree cleanness' '\n \tgit checkout master &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"exec_echo_foo_>file1 1\" git rebase -i HEAD^ &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"exec_echo_foo_>file1 1\" \\\n+\t\t\tgit rebase -i HEAD^\n+\t) &&\n \ttest_cmp_rev master^ HEAD &&\n \tgit reset --hard &&\n \tgit rebase --continue\n@@ -168,9 +174,11 @@ test_expect_success 'rebase -x with newline in command fails' '\n test_expect_success 'rebase -i with exec of inexistent command' '\n \tgit checkout master &&\n \ttest_when_finished \"git rebase --abort\" &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"exec_this-command-does-not-exist 1\" \\\n-\tgit rebase -i HEAD^ >actual 2>&1 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"exec_this-command-does-not-exist 1\" \\\n+\t\t\tgit rebase -i HEAD^ >actual 2>&1\n+\t) &&\n \t! grep \"Maybe git-rebase is broken\" actual\n '\n \n@@ -230,8 +238,10 @@ test_expect_success 'reflog for the branch shows correct finish message' '\n '\n \n test_expect_success 'exchange two commits' '\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"2 1\" git rebase -i HEAD~2 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"2 1\" git rebase -i HEAD~2\n+\t) &&\n \ttest H = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n \ttest G = $(git cat-file commit HEAD | sed -ne \\$p)\n '\n@@ -332,9 +342,11 @@ test_expect_success 'squash' '\n \ttest_tick &&\n \tGIT_AUTHOR_NAME=\"Nitfol\" git commit -m \"nitfol\" file7 &&\n \techo \"******************************\" &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"1 squash 2\" EXPECT_HEADER_COUNT=2 \\\n-\t\tgit rebase -i --onto master HEAD~2 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"1 squash 2\" EXPECT_HEADER_COUNT=2 \\\n+\t\t\tgit rebase -i --onto master HEAD~2\n+\t) &&\n \ttest B = $(cat file7) &&\n \ttest $(git rev-parse HEAD^) = $(git rev-parse master)\n '\n@@ -355,8 +367,10 @@ test_expect_success REBASE_P '-p handles \"no changes\" gracefully' '\n \n test_expect_failure REBASE_P 'exchange two commits with -p' '\n \tgit checkout H &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"2 1\" git rebase -i -p HEAD~2 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"2 1\" git rebase -i -p HEAD~2\n+\t) &&\n \ttest H = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n \ttest G = $(git cat-file commit HEAD | sed -ne \\$p)\n '\n@@ -405,8 +419,10 @@ test_expect_success REBASE_P 'preserve merges with -p' '\n '\n \n test_expect_success REBASE_P 'edit ancestor with -p' '\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"1 2 edit 3 4\" git rebase -i -p HEAD~3 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"1 2 edit 3 4\" git rebase -i -p HEAD~3\n+\t) &&\n \techo 2 > unrelated-file &&\n \ttest_tick &&\n \tgit commit -m L2-modified --amend unrelated-file &&\n@@ -420,11 +436,13 @@ test_expect_success REBASE_P 'edit ancestor with -p' '\n test_expect_success '--continue tries to commit' '\n \tgit reset --hard D &&\n \ttest_tick &&\n-\tset_fake_editor &&\n-\ttest_must_fail git rebase -i --onto new-branch1 HEAD^ &&\n-\techo resolved > file1 &&\n-\tgit add file1 &&\n-\tFAKE_COMMIT_MESSAGE=\"chouette!\" git rebase --continue &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail git rebase -i --onto new-branch1 HEAD^ &&\n+\t\techo resolved > file1 &&\n+\t\tgit add file1 &&\n+\t\tFAKE_COMMIT_MESSAGE=\"chouette!\" git rebase --continue\n+\t) &&\n \ttest $(git rev-parse HEAD^) = $(git rev-parse new-branch1) &&\n \tgit show HEAD | grep chouette\n '\n@@ -442,10 +460,13 @@ test_expect_success 'verbose flag is heeded, even after --continue' '\n \n test_expect_success C_LOCALE_OUTPUT 'multi-squash only fires up editor once' '\n \tbase=$(git rev-parse HEAD~4) &&\n-\tset_fake_editor &&\n-\tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"1 squash 2 squash 3 squash 4\" \\\n-\t\tEXPECT_HEADER_COUNT=4 \\\n-\t\tgit rebase -i $base &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_COMMIT_AMEND=\"ONCE\" \\\n+\t\t\tFAKE_LINES=\"1 squash 2 squash 3 squash 4\" \\\n+\t\t\tEXPECT_HEADER_COUNT=4 \\\n+\t\t\tgit rebase -i $base\n+\t) &&\n \ttest $base = $(git rev-parse HEAD^) &&\n \ttest 1 = $(git show | grep ONCE | wc -l)\n '\n@@ -453,9 +474,12 @@ test_expect_success C_LOCALE_OUTPUT 'multi-squash only fires up editor once' '\n test_expect_success C_LOCALE_OUTPUT 'multi-fixup does not fire up editor' '\n \tgit checkout -b multi-fixup E &&\n \tbase=$(git rev-parse HEAD~4) &&\n-\tset_fake_editor &&\n-\tFAKE_COMMIT_AMEND=\"NEVER\" FAKE_LINES=\"1 fixup 2 fixup 3 fixup 4\" \\\n-\t\tgit rebase -i $base &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_COMMIT_AMEND=\"NEVER\" \\\n+\t\t\tFAKE_LINES=\"1 fixup 2 fixup 3 fixup 4\" \\\n+\t\t\tgit rebase -i $base\n+\t) &&\n \ttest $base = $(git rev-parse HEAD^) &&\n \ttest 0 = $(git show | grep NEVER | wc -l) &&\n \tgit checkout @{-1} &&\n@@ -465,12 +489,15 @@ test_expect_success C_LOCALE_OUTPUT 'multi-fixup does not fire up editor' '\n test_expect_success 'commit message used after conflict' '\n \tgit checkout -b conflict-fixup conflict-branch &&\n \tbase=$(git rev-parse HEAD~4) &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"1 fixup 3 fixup 4\" git rebase -i $base &&\n-\techo three > conflict &&\n-\tgit add conflict &&\n-\tFAKE_COMMIT_AMEND=\"ONCE\" EXPECT_HEADER_COUNT=2 \\\n-\t\tgit rebase --continue &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"1 fixup 3 fixup 4\" \\\n+\t\t\tgit rebase -i $base &&\n+\t\techo three > conflict &&\n+\t\tgit add conflict &&\n+\t\tFAKE_COMMIT_AMEND=\"ONCE\" EXPECT_HEADER_COUNT=2 \\\n+\t\t\tgit rebase --continue\n+\t) &&\n \ttest $base = $(git rev-parse HEAD^) &&\n \ttest 1 = $(git show | grep ONCE | wc -l) &&\n \tgit checkout @{-1} &&\n@@ -480,12 +507,15 @@ test_expect_success 'commit message used after conflict' '\n test_expect_success 'commit message retained after conflict' '\n \tgit checkout -b conflict-squash conflict-branch &&\n \tbase=$(git rev-parse HEAD~4) &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"1 fixup 3 squash 4\" git rebase -i $base &&\n-\techo three > conflict &&\n-\tgit add conflict &&\n-\tFAKE_COMMIT_AMEND=\"TWICE\" EXPECT_HEADER_COUNT=2 \\\n-\t\tgit rebase --continue &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"1 fixup 3 squash 4\" \\\n+\t\t\tgit rebase -i $base &&\n+\t\techo three > conflict &&\n+\t\tgit add conflict &&\n+\t\tFAKE_COMMIT_AMEND=\"TWICE\" EXPECT_HEADER_COUNT=2 \\\n+\t\t\tgit rebase --continue\n+\t) &&\n \ttest $base = $(git rev-parse HEAD^) &&\n \ttest 2 = $(git show | grep TWICE | wc -l) &&\n \tgit checkout @{-1} &&\n@@ -502,10 +532,13 @@ test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messa\n \tEOF\n \tgit checkout -b squash-fixup E &&\n \tbase=$(git rev-parse HEAD~4) &&\n-\tset_fake_editor &&\n-\tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"1 fixup 2 squash 3 fixup 4\" \\\n-\t\tEXPECT_HEADER_COUNT=4 \\\n-\t\tgit rebase -i $base &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_COMMIT_AMEND=\"ONCE\" \\\n+\t\t\tFAKE_LINES=\"1 fixup 2 squash 3 fixup 4\" \\\n+\t\t\tEXPECT_HEADER_COUNT=4 \\\n+\t\t\tgit rebase -i $base\n+\t) &&\n \tgit cat-file commit HEAD | sed -e 1,/^\\$/d > actual-squash-fixup &&\n \ttest_cmp expect-squash-fixup actual-squash-fixup &&\n \tgit cat-file commit HEAD@{2} |\n@@ -519,10 +552,13 @@ test_expect_success C_LOCALE_OUTPUT 'squash and fixup generate correct log messa\n test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '\n \tgit checkout -b skip-comments E &&\n \tbase=$(git rev-parse HEAD~4) &&\n-\tset_fake_editor &&\n-\tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"# 1 # squash 2 # squash 3 # squash 4 #\" \\\n-\t\tEXPECT_HEADER_COUNT=4 \\\n-\t\tgit rebase -i $base &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_COMMIT_AMEND=\"ONCE\" \\\n+\t\t\tFAKE_LINES=\"# 1 # squash 2 # squash 3 # squash 4 #\" \\\n+\t\t\tEXPECT_HEADER_COUNT=4 \\\n+\t\t\tgit rebase -i $base\n+\t) &&\n \ttest $base = $(git rev-parse HEAD^) &&\n \ttest 1 = $(git show | grep ONCE | wc -l) &&\n \tgit checkout @{-1} &&\n@@ -532,10 +568,13 @@ test_expect_success C_LOCALE_OUTPUT 'squash ignores comments' '\n test_expect_success C_LOCALE_OUTPUT 'squash ignores blank lines' '\n \tgit checkout -b skip-blank-lines E &&\n \tbase=$(git rev-parse HEAD~4) &&\n-\tset_fake_editor &&\n-\tFAKE_COMMIT_AMEND=\"ONCE\" FAKE_LINES=\"> 1 > squash 2 > squash 3 > squash 4 >\" \\\n-\t\tEXPECT_HEADER_COUNT=4 \\\n-\t\tgit rebase -i $base &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_COMMIT_AMEND=\"ONCE\" \\\n+\t\t\tFAKE_LINES=\"> 1 > squash 2 > squash 3 > squash 4 >\" \\\n+\t\t\tEXPECT_HEADER_COUNT=4 \\\n+\t\t\tgit rebase -i $base\n+\t) &&\n \ttest $base = $(git rev-parse HEAD^) &&\n \ttest 1 = $(git show | grep ONCE | wc -l) &&\n \tgit checkout @{-1} &&\n@@ -545,17 +584,21 @@ test_expect_success C_LOCALE_OUTPUT 'squash ignores blank lines' '\n test_expect_success 'squash works as expected' '\n \tgit checkout -b squash-works no-conflict-branch &&\n \tone=$(git rev-parse HEAD~3) &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"1 s 3 2\" EXPECT_HEADER_COUNT=2 \\\n-\t\tgit rebase -i HEAD~3 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"1 s 3 2\" EXPECT_HEADER_COUNT=2 git rebase -i HEAD~3\n+\t) &&\n \ttest $one = $(git rev-parse HEAD~2)\n '\n \n test_expect_success 'interrupted squash works as expected' '\n \tgit checkout -b interrupted-squash conflict-branch &&\n \tone=$(git rev-parse HEAD~3) &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"1 squash 3 2\" git rebase -i HEAD~3 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"1 squash 3 2\" \\\n+\t\t\tgit rebase -i HEAD~3\n+\t) &&\n \ttest_write_lines one two four > conflict &&\n \tgit add conflict &&\n \ttest_must_fail git rebase --continue &&\n@@ -568,8 +611,11 @@ test_expect_success 'interrupted squash works as expected' '\n test_expect_success 'interrupted squash works as expected (case 2)' '\n \tgit checkout -b interrupted-squash2 conflict-branch &&\n \tone=$(git rev-parse HEAD~3) &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"3 squash 1 2\" git rebase -i HEAD~3 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"3 squash 1 2\" \\\n+\t\t\tgit rebase -i HEAD~3\n+\t) &&\n \ttest_write_lines one four > conflict &&\n \tgit add conflict &&\n \ttest_must_fail git rebase --continue &&\n@@ -589,11 +635,13 @@ test_expect_success '--continue tries to commit, even for \"edit\"' '\n \tgit commit -m \"unrelated change\" &&\n \tparent=$(git rev-parse HEAD^) &&\n \ttest_tick &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"edit 1\" git rebase -i HEAD^ &&\n-\techo edited > file7 &&\n-\tgit add file7 &&\n-\tFAKE_COMMIT_MESSAGE=\"chouette!\" git rebase --continue &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"edit 1\" git rebase -i HEAD^ &&\n+\t\techo edited > file7 &&\n+\t\tgit add file7 &&\n+\t\tFAKE_COMMIT_MESSAGE=\"chouette!\" git rebase --continue\n+\t) &&\n \ttest edited = $(git show HEAD:file7) &&\n \tgit show HEAD | grep chouette &&\n \ttest $parent = $(git rev-parse HEAD^)\n@@ -602,34 +650,41 @@ test_expect_success '--continue tries to commit, even for \"edit\"' '\n test_expect_success 'aborted --continue does not squash commits after \"edit\"' '\n \told=$(git rev-parse HEAD) &&\n \ttest_tick &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"edit 1\" git rebase -i HEAD^ &&\n-\techo \"edited again\" > file7 &&\n-\tgit add file7 &&\n-\ttest_must_fail env FAKE_COMMIT_MESSAGE=\" \" git rebase --continue &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"edit 1\" git rebase -i HEAD^ &&\n+\t\techo \"edited again\" > file7 &&\n+\t\tgit add file7 &&\n+\t\ttest_must_fail env FAKE_COMMIT_MESSAGE=\" \" git rebase --continue\n+\t) &&\n \ttest $old = $(git rev-parse HEAD) &&\n \tgit rebase --abort\n '\n \n test_expect_success 'auto-amend only edited commits after \"edit\"' '\n \ttest_tick &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"edit 1\" git rebase -i HEAD^ &&\n-\techo \"edited again\" > file7 &&\n-\tgit add file7 &&\n-\tFAKE_COMMIT_MESSAGE=\"edited file7 again\" git commit &&\n-\techo \"and again\" > file7 &&\n-\tgit add file7 &&\n-\ttest_tick &&\n-\ttest_must_fail env FAKE_COMMIT_MESSAGE=\"and again\" git rebase --continue &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"edit 1\" git rebase -i HEAD^ &&\n+\t\techo \"edited again\" > file7 &&\n+\t\tgit add file7 &&\n+\t\tFAKE_COMMIT_MESSAGE=\"edited file7 again\" git commit &&\n+\t\techo \"and again\" > file7 &&\n+\t\tgit add file7 &&\n+\t\ttest_tick &&\n+\t\ttest_must_fail env FAKE_COMMIT_MESSAGE=\"and again\" \\\n+\t\t\tgit rebase --continue\n+\t) &&\n \tgit rebase --abort\n '\n \n test_expect_success 'clean error after failed \"exec\"' '\n \ttest_tick &&\n \ttest_when_finished \"git rebase --abort || :\" &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"1 exec_false\" git rebase -i HEAD^ &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"1 exec_false\" git rebase -i HEAD^\n+\t) &&\n \techo \"edited again\" > file7 &&\n \tgit add file7 &&\n \ttest_must_fail git rebase --continue 2>error &&\n@@ -640,8 +695,10 @@ test_expect_success 'rebase a detached HEAD' '\n \tgrandparent=$(git rev-parse HEAD~2) &&\n \tgit checkout $(git rev-parse HEAD) &&\n \ttest_tick &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"2 1\" git rebase -i HEAD~2 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"2 1\" git rebase -i HEAD~2\n+\t) &&\n \ttest $grandparent = $(git rev-parse HEAD~2)\n '\n \n@@ -656,9 +713,10 @@ test_expect_success 'rebase a commit violating pre-commit' '\n \ttest_must_fail git commit -m doesnt-verify file1 &&\n \tgit commit -m doesnt-verify --no-verify file1 &&\n \ttest_tick &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=2 git rebase -i HEAD~2\n-\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=2 git rebase -i HEAD~2\n+\t)\n '\n \n test_expect_success 'rebase with a file named HEAD in worktree' '\n@@ -678,8 +736,10 @@ test_expect_success 'rebase with a file named HEAD in worktree' '\n \t\tgit commit -m \"Add body\"\n \t) &&\n \n-\tset_fake_editor &&\n-\tFAKE_LINES=\"1 squash 2\" git rebase -i @{-1} &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"1 squash 2\" git rebase -i @{-1}\n+\t) &&\n \ttest \"$(git show -s --pretty=format:%an)\" = \"Squashed Away\"\n \n '\n@@ -720,8 +780,10 @@ test_expect_success 'submodule rebase setup' '\n '\n \n test_expect_success 'submodule rebase -i' '\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"1 squash 2 3\" git rebase -i A\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"1 squash 2 3\" git rebase -i A\n+\t)\n '\n \n test_expect_success 'submodule conflict setup' '\n@@ -770,16 +832,22 @@ test_expect_success 'avoid unnecessary reset' '\n \n test_expect_success 'reword' '\n \tgit checkout -b reword-branch master &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"1 2 3 reword 4\" FAKE_COMMIT_MESSAGE=\"E changed\" git rebase -i A &&\n-\tgit show HEAD | grep \"E changed\" &&\n-\ttest $(git rev-parse master) != $(git rev-parse HEAD) &&\n-\ttest $(git rev-parse master^) = $(git rev-parse HEAD^) &&\n-\tFAKE_LINES=\"1 2 reword 3 4\" FAKE_COMMIT_MESSAGE=\"D changed\" git rebase -i A &&\n-\tgit show HEAD^ | grep \"D changed\" &&\n-\tFAKE_LINES=\"reword 1 2 3 4\" FAKE_COMMIT_MESSAGE=\"B changed\" git rebase -i A &&\n-\tgit show HEAD~3 | grep \"B changed\" &&\n-\tFAKE_LINES=\"1 r 2 pick 3 p 4\" FAKE_COMMIT_MESSAGE=\"C changed\" git rebase -i A &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"1 2 3 reword 4\" FAKE_COMMIT_MESSAGE=\"E changed\" \\\n+\t\t\tgit rebase -i A &&\n+\t\tgit show HEAD | grep \"E changed\" &&\n+\t\ttest $(git rev-parse master) != $(git rev-parse HEAD) &&\n+\t\ttest $(git rev-parse master^) = $(git rev-parse HEAD^) &&\n+\t\tFAKE_LINES=\"1 2 reword 3 4\" FAKE_COMMIT_MESSAGE=\"D changed\" \\\n+\t\t\tgit rebase -i A &&\n+\t\tgit show HEAD^ | grep \"D changed\" &&\n+\t\tFAKE_LINES=\"reword 1 2 3 4\" FAKE_COMMIT_MESSAGE=\"B changed\" \\\n+\t\t\tgit rebase -i A &&\n+\t\tgit show HEAD~3 | grep \"B changed\" &&\n+\t\tFAKE_LINES=\"1 r 2 pick 3 p 4\" FAKE_COMMIT_MESSAGE=\"C changed\" \\\n+\t\t\tgit rebase -i A\n+\t) &&\n \tgit show HEAD~2 | grep \"C changed\"\n '\n \n@@ -803,8 +871,11 @@ test_expect_success 'rebase -i can copy notes over a fixup' '\n \tEOF\n \tgit reset --hard n3 &&\n \tgit notes add -m\"an earlier note\" n2 &&\n-\tset_fake_editor &&\n-\tGIT_NOTES_REWRITE_MODE=concatenate FAKE_LINES=\"1 f 2\" git rebase -i n1 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tGIT_NOTES_REWRITE_MODE=concatenate FAKE_LINES=\"1 f 2\" \\\n+\t\t\tgit rebase -i n1\n+\t) &&\n \tgit notes show > output &&\n \ttest_cmp expect output\n '\n@@ -813,8 +884,10 @@ test_expect_success 'rebase while detaching HEAD' '\n \tgit symbolic-ref HEAD &&\n \tgrandparent=$(git rev-parse HEAD~2) &&\n \ttest_tick &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"2 1\" git rebase -i HEAD~2 HEAD^0 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"2 1\" git rebase -i HEAD~2 HEAD^0\n+\t) &&\n \ttest $grandparent = $(git rev-parse HEAD~2) &&\n \ttest_must_fail git symbolic-ref HEAD\n '\n@@ -855,8 +928,10 @@ test_expect_success 'set up commits with funny messages' '\n test_expect_success 'rebase-i history with funny messages' '\n \tgit rev-list A..funny >expect &&\n \ttest_tick &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"1 2 3 4\" git rebase -i A &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"1 2 3 4\" git rebase -i A\n+\t) &&\n \tgit rev-list A.. >actual &&\n \ttest_cmp expect actual\n '\n@@ -870,9 +945,9 @@ test_expect_success 'prepare for rebase -i --exec' '\n '\n \n test_expect_success 'running \"git rebase -i --exec git show HEAD\"' '\n-\tset_fake_editor &&\n-\tgit rebase -i --exec \"git show HEAD\" HEAD~2 >actual &&\n \t(\n+\t\tset_fake_editor &&\n+\t\tgit rebase -i --exec \"git show HEAD\" HEAD~2 >actual &&\n \t\tFAKE_LINES=\"1 exec_git_show_HEAD 2 exec_git_show_HEAD\" &&\n \t\texport FAKE_LINES &&\n \t\tgit rebase -i HEAD~2 >expect\n@@ -883,9 +958,9 @@ test_expect_success 'running \"git rebase -i --exec git show HEAD\"' '\n \n test_expect_success 'running \"git rebase --exec git show HEAD -i\"' '\n \tgit reset --hard execute &&\n-\tset_fake_editor &&\n-\tgit rebase --exec \"git show HEAD\" -i HEAD~2 >actual &&\n \t(\n+\t\tset_fake_editor &&\n+\t\tgit rebase --exec \"git show HEAD\" -i HEAD~2 >actual &&\n \t\tFAKE_LINES=\"1 exec_git_show_HEAD 2 exec_git_show_HEAD\" &&\n \t\texport FAKE_LINES &&\n \t\tgit rebase -i HEAD~2 >expect\n@@ -896,9 +971,9 @@ test_expect_success 'running \"git rebase --exec git show HEAD -i\"' '\n \n test_expect_success 'running \"git rebase -ix git show HEAD\"' '\n \tgit reset --hard execute &&\n-\tset_fake_editor &&\n-\tgit rebase -ix \"git show HEAD\" HEAD~2 >actual &&\n \t(\n+\t\tset_fake_editor &&\n+\t\tgit rebase -ix \"git show HEAD\" HEAD~2 >actual &&\n \t\tFAKE_LINES=\"1 exec_git_show_HEAD 2 exec_git_show_HEAD\" &&\n \t\texport FAKE_LINES &&\n \t\tgit rebase -i HEAD~2 >expect\n@@ -910,9 +985,9 @@ test_expect_success 'running \"git rebase -ix git show HEAD\"' '\n \n test_expect_success 'rebase -ix with several <CMD>' '\n \tgit reset --hard execute &&\n-\tset_fake_editor &&\n-\tgit rebase -ix \"git show HEAD; pwd\" HEAD~2 >actual &&\n \t(\n+\t\tset_fake_editor &&\n+\t\tgit rebase -ix \"git show HEAD; pwd\" HEAD~2 >actual &&\n \t\tFAKE_LINES=\"1 exec_git_show_HEAD;_pwd 2 exec_git_show_HEAD;_pwd\" &&\n \t\texport FAKE_LINES &&\n \t\tgit rebase -i HEAD~2 >expect\n@@ -923,9 +998,9 @@ test_expect_success 'rebase -ix with several <CMD>' '\n \n test_expect_success 'rebase -ix with several instances of --exec' '\n \tgit reset --hard execute &&\n-\tset_fake_editor &&\n-\tgit rebase -i --exec \"git show HEAD\" --exec \"pwd\" HEAD~2 >actual &&\n \t(\n+\t\tset_fake_editor &&\n+\t\tgit rebase -i --exec \"git show HEAD\" --exec \"pwd\" HEAD~2 >actual &&\n \t\tFAKE_LINES=\"1 exec_git_show_HEAD exec_pwd 2\n \t\t\t\texec_git_show_HEAD exec_pwd\" &&\n \t\texport FAKE_LINES &&\n@@ -944,11 +1019,11 @@ test_expect_success C_LOCALE_OUTPUT 'rebase -ix with --autosquash' '\n \techo bis >bis.txt &&\n \tgit add bis.txt &&\n \tgit commit -m \"fixup! two_exec\" &&\n-\tset_fake_editor &&\n \tgit checkout -b autosquash_actual &&\n \tgit rebase -i --exec \"git show HEAD\" --autosquash HEAD~4 >actual &&\n \tgit checkout autosquash &&\n \t(\n+\t\tset_fake_editor &&\n \t\tgit checkout -b autosquash_expected &&\n \t\tFAKE_LINES=\"1 fixup 3 fixup 4 exec_git_show_HEAD 2 exec_git_show_HEAD\" &&\n \t\texport FAKE_LINES &&\n@@ -977,8 +1052,10 @@ test_expect_success 'rebase -i --exec without <CMD>' '\n \n test_expect_success 'rebase -i --root re-order and drop commits' '\n \tgit checkout E &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"3 1 2 5\" git rebase -i --root &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"3 1 2 5\" git rebase -i --root\n+\t) &&\n \ttest E = $(git cat-file commit HEAD | sed -ne \\$p) &&\n \ttest B = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n \ttest A = $(git cat-file commit HEAD^^ | sed -ne \\$p) &&\n@@ -991,24 +1068,30 @@ test_expect_success 'rebase -i --root retain root commit author and message' '\n \techo B >file7 &&\n \tgit add file7 &&\n \tGIT_AUTHOR_NAME=\"Twerp Snog\" git commit -m \"different author\" &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"2\" git rebase -i --root &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"2\" git rebase -i --root\n+\t) &&\n \tgit cat-file commit HEAD | grep -q \"^author Twerp Snog\" &&\n \tgit cat-file commit HEAD | grep -q \"^different author$\"\n '\n \n test_expect_success 'rebase -i --root temporary sentinel commit' '\n \tgit checkout B &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"2\" git rebase -i --root &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"2\" git rebase -i --root\n+\t) &&\n \tgit cat-file commit HEAD | grep \"^tree 4b825dc642cb\" &&\n \tgit rebase --abort\n '\n \n test_expect_success 'rebase -i --root fixup root commit' '\n \tgit checkout B &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"1 fixup 2\" git rebase -i --root &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"1 fixup 2\" git rebase -i --root\n+\t) &&\n \ttest A = $(git cat-file commit HEAD | sed -ne \\$p) &&\n \ttest B = $(git show HEAD:file1) &&\n \ttest 0 = $(git cat-file commit HEAD | grep -c ^parent\\ )\n@@ -1017,9 +1100,11 @@ test_expect_success 'rebase -i --root fixup root commit' '\n test_expect_success 'rebase -i --root reword original root commit' '\n \ttest_when_finished \"test_might_fail git rebase --abort\" &&\n \tgit checkout -b reword-original-root-branch master &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"reword 1 2\" FAKE_COMMIT_MESSAGE=\"A changed\" \\\n-\tgit rebase -i --root &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"reword 1 2\" FAKE_COMMIT_MESSAGE=\"A changed\" \\\n+\t\t\tgit rebase -i --root\n+\t) &&\n \tgit show HEAD^ | grep \"A changed\" &&\n \ttest -z \"$(git show -s --format=%p HEAD^)\"\n '\n@@ -1027,9 +1112,11 @@ test_expect_success 'rebase -i --root reword original root commit' '\n test_expect_success 'rebase -i --root reword new root commit' '\n \ttest_when_finished \"test_might_fail git rebase --abort\" &&\n \tgit checkout -b reword-now-root-branch master &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"reword 3 1\" FAKE_COMMIT_MESSAGE=\"C changed\" \\\n-\tgit rebase -i --root &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"reword 3 1\" FAKE_COMMIT_MESSAGE=\"C changed\" \\\n+\t\tgit rebase -i --root\n+\t) &&\n \tgit show HEAD^ | grep \"C changed\" &&\n \ttest -z \"$(git show -s --format=%p HEAD^)\"\n '\n@@ -1041,8 +1128,10 @@ test_expect_success 'rebase -i --root when root has untracked file conflict' '\n \tgit rm file1 &&\n \tgit commit -m \"remove file 1 add file 2\" &&\n \techo z >file1 &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"1 2\" git rebase -i --root &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"1 2\" git rebase -i --root\n+\t) &&\n \trm file1 &&\n \tgit rebase --continue &&\n \ttest \"$(git log -1 --format=%B)\" = \"remove file 1 add file 2\" &&\n@@ -1052,11 +1141,13 @@ test_expect_success 'rebase -i --root when root has untracked file conflict' '\n test_expect_success 'rebase -i --root reword root when root has untracked file conflict' '\n \ttest_when_finished \"reset_rebase\" &&\n \techo z>file1 &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"reword 1 2\" \\\n-\t\tFAKE_COMMIT_MESSAGE=\"Modified A\" git rebase -i --root &&\n-\trm file1 &&\n-\tFAKE_COMMIT_MESSAGE=\"Reworded A\" git rebase --continue &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"reword 1 2\" \\\n+\t\t\tFAKE_COMMIT_MESSAGE=\"Modified A\" git rebase -i --root &&\n+\t\trm file1 &&\n+\t\tFAKE_COMMIT_MESSAGE=\"Reworded A\" git rebase --continue\n+\t) &&\n \ttest \"$(git log -1 --format=%B HEAD^)\" = \"Reworded A\" &&\n \ttest \"$(git rev-list --count HEAD)\" = 2\n '\n@@ -1065,19 +1156,23 @@ test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-int\n \tgit checkout reword-original-root-branch &&\n \tgit reset --hard &&\n \tgit checkout conflict-branch &&\n-\tset_fake_editor &&\n-\ttest_must_fail git rebase --onto HEAD~2 HEAD~ &&\n-\ttest_must_fail git rebase --edit-todo &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail git rebase --onto HEAD~2 HEAD~ &&\n+\t\ttest_must_fail git rebase --edit-todo\n+\t) &&\n \tgit rebase --abort\n '\n \n test_expect_success 'rebase --edit-todo can be used to modify todo' '\n \tgit reset --hard &&\n \tgit checkout no-conflict-branch^0 &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"edit 1 2 3\" git rebase -i HEAD~3 &&\n-\tFAKE_LINES=\"2 1\" git rebase --edit-todo &&\n-\tgit rebase --continue &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"edit 1 2 3\" git rebase -i HEAD~3 &&\n+\t\tFAKE_LINES=\"2 1\" git rebase --edit-todo &&\n+\t\tgit rebase --continue\n+\t) &&\n \ttest M = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n \ttest L = $(git cat-file commit HEAD | sed -ne \\$p)\n '\n@@ -1106,8 +1201,10 @@ test_expect_success 'rebase -i respects core.commentchar' '\n \tsed -e \"2,\\$s/^/\\\\\\\\/\" \"$1\" >\"$1.tmp\" &&\n \tmv \"$1.tmp\" \"$1\"\n \tEOF\n-\ttest_set_editor \"$(pwd)/remove-all-but-first.sh\" &&\n-\tgit rebase -i B &&\n+\t(\n+\t\ttest_set_editor \"$(pwd)/remove-all-but-first.sh\" &&\n+\t\tgit rebase -i B\n+\t) &&\n \ttest B = $(git cat-file commit HEAD^ | sed -ne \\$p)\n '\n \n@@ -1116,9 +1213,11 @@ test_expect_success 'rebase -i respects core.commentchar=auto' '\n \twrite_script copy-edit-script.sh <<-\\EOF &&\n \tcp \"$1\" edit-script\n \tEOF\n-\ttest_set_editor \"$(pwd)/copy-edit-script.sh\" &&\n \ttest_when_finished \"git rebase --abort || :\" &&\n-\tgit rebase -i HEAD^ &&\n+\t(\n+\t\ttest_set_editor \"$(pwd)/copy-edit-script.sh\" &&\n+\t\tgit rebase -i HEAD^\n+\t) &&\n \ttest -z \"$(grep -ve \"^#\" -e \"^\\$\" -e \"^pick\" edit-script)\"\n '\n \n@@ -1153,8 +1252,11 @@ test_expect_success 'interrupted rebase -i with --strategy and -X' '\n \techo five >conflict &&\n \techo Z >file1 &&\n \tgit commit -a -m \"one file conflict\" &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"edit 1 2\" git rebase -i --strategy=recursive -Xours conflict-branch &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"edit 1 2\" git rebase -i --strategy=recursive \\\n+\t\t\t-Xours conflict-branch\n+\t) &&\n \tgit rebase --continue &&\n \ttest $(git show conflict-branch:conflict) = $(cat conflict) &&\n \ttest $(cat file1) = Z\n@@ -1195,8 +1297,10 @@ test_expect_success 'short SHA-1 collide' '\n \n test_expect_success 'respect core.abbrev' '\n \tgit config core.abbrev 12 &&\n-\tset_cat_todo_editor &&\n-\ttest_must_fail git rebase -i HEAD~4 >todo-list &&\n+\t(\n+\t\tset_cat_todo_editor &&\n+\t\ttest_must_fail git rebase -i HEAD~4 >todo-list\n+\t) &&\n \ttest 4 = $(grep -c \"pick [0-9a-f]\\{12,\\}\" todo-list)\n '\n \n@@ -1204,16 +1308,20 @@ test_expect_success 'todo count' '\n \twrite_script dump-raw.sh <<-\\EOF &&\n \t\tcat \"$1\"\n \tEOF\n-\ttest_set_editor \"$(pwd)/dump-raw.sh\" &&\n-\tgit rebase -i HEAD~4 >actual &&\n+\t(\n+\t\ttest_set_editor \"$(pwd)/dump-raw.sh\" &&\n+\t\tgit rebase -i HEAD~4 >actual\n+\t) &&\n \ttest_i18ngrep \"^# Rebase ..* onto ..* ([0-9]\" actual\n '\n \n test_expect_success 'rebase -i commits that overwrite untracked files (pick)' '\n \tgit checkout --force branch2 &&\n \tgit clean -f &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"edit 1 2\" git rebase -i A &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"edit 1 2\" git rebase -i A\n+\t) &&\n \ttest_cmp_rev HEAD F &&\n \ttest_path_is_missing file6 &&\n \t>file6 &&\n@@ -1228,8 +1336,10 @@ test_expect_success 'rebase -i commits that overwrite untracked files (squash)'\n \tgit checkout --force branch2 &&\n \tgit clean -f &&\n \tgit tag original-branch2 &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"edit 1 squash 2\" git rebase -i A &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"edit 1 squash 2\" git rebase -i A\n+\t) &&\n \ttest_cmp_rev HEAD F &&\n \ttest_path_is_missing file6 &&\n \t>file6 &&\n@@ -1244,8 +1354,10 @@ test_expect_success 'rebase -i commits that overwrite untracked files (squash)'\n test_expect_success 'rebase -i commits that overwrite untracked files (no ff)' '\n \tgit checkout --force branch2 &&\n \tgit clean -f &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"edit 1 2\" git rebase -i --no-ff A &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"edit 1 2\" git rebase -i --no-ff A\n+\t) &&\n \ttest $(git cat-file commit HEAD | sed -ne \\$p) = F &&\n \ttest_path_is_missing file6 &&\n \t>file6 &&\n@@ -1268,8 +1380,10 @@ test_expect_success 'rebase --continue removes CHERRY_PICK_HEAD' '\n \tgit tag seq-onto &&\n \tgit reset --hard HEAD~2 &&\n \tgit cherry-pick seq-onto &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES= git rebase -i seq-onto &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES= git rebase -i seq-onto\n+\t) &&\n \ttest -d .git/rebase-merge &&\n \tgit rebase --continue &&\n \tgit diff --exit-code seq-onto &&\n@@ -1288,8 +1402,10 @@ rebase_setup_and_clean () {\n \n test_expect_success 'drop' '\n \trebase_setup_and_clean drop-test &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"1 drop 2 3 d 4 5\" git rebase -i --root &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"1 drop 2 3 d 4 5\" git rebase -i --root\n+\t) &&\n \ttest E = $(git cat-file commit HEAD | sed -ne \\$p) &&\n \ttest C = $(git cat-file commit HEAD^ | sed -ne \\$p) &&\n \ttest A = $(git cat-file commit HEAD^^ | sed -ne \\$p)\n@@ -1298,9 +1414,10 @@ test_expect_success 'drop' '\n test_expect_success 'rebase -i respects rebase.missingCommitsCheck = ignore' '\n \ttest_config rebase.missingCommitsCheck ignore &&\n \trebase_setup_and_clean missing-commit &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"1 2 3 4\" \\\n-\t\tgit rebase -i --root 2>actual &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"1 2 3 4\" git rebase -i --root 2>actual\n+\t) &&\n \ttest D = $(git cat-file commit HEAD | sed -ne \\$p) &&\n \ttest_i18ngrep \\\n \t\t\"Successfully rebased and updated refs/heads/missing-commit\" \\\n@@ -1316,9 +1433,10 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = warn' '\n \tEOF\n \ttest_config rebase.missingCommitsCheck warn &&\n \trebase_setup_and_clean missing-commit &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"1 2 3 4\" \\\n-\t\tgit rebase -i --root 2>actual.2 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"1 2 3 4\" git rebase -i --root 2>actual.2\n+\t) &&\n \thead -n4 actual.2 >actual &&\n \ttest_i18ncmp expect actual &&\n \ttest D = $(git cat-file commit HEAD | sed -ne \\$p)\n@@ -1340,14 +1458,15 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = error' '\n \tEOF\n \ttest_config rebase.missingCommitsCheck error &&\n \trebase_setup_and_clean missing-commit &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"1 2 4\" \\\n-\t\tgit rebase -i --root 2>actual &&\n-\ttest_i18ncmp expect actual &&\n-\tcp .git/rebase-merge/git-rebase-todo.backup \\\n-\t\t.git/rebase-merge/git-rebase-todo &&\n-\tFAKE_LINES=\"1 2 drop 3 4 drop 5\" \\\n-\t\tgit rebase --edit-todo &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"1 2 4\" \\\n+\t\t\tgit rebase -i --root 2>actual &&\n+\t\ttest_i18ncmp expect actual &&\n+\t\tcp .git/rebase-merge/git-rebase-todo.backup \\\n+\t\t\t.git/rebase-merge/git-rebase-todo &&\n+\t\tFAKE_LINES=\"1 2 drop 3 4 drop 5\" git rebase --edit-todo\n+\t) &&\n \tgit rebase --continue &&\n \ttest D = $(git cat-file commit HEAD | sed -ne \\$p) &&\n \ttest B = $(git cat-file commit HEAD^ | sed -ne \\$p)\n@@ -1368,21 +1487,27 @@ test_expect_success 'respects rebase.abbreviateCommands with fixup, squash and e\n \tx git show HEAD\n \tEOF\n \tgit checkout abbrevcmd &&\n-\tset_cat_todo_editor &&\n \ttest_config rebase.abbreviateCommands true &&\n-\ttest_must_fail git rebase -i --exec \"git show HEAD\" \\\n-\t\t--autosquash master >actual &&\n+\t(\n+\t\tset_cat_todo_editor &&\n+\t\ttest_must_fail git rebase -i --exec \"git show HEAD\" \\\n+\t\t\t--autosquash master >actual\n+\t) &&\n \ttest_cmp expected actual\n '\n \n test_expect_success 'static check of bad command' '\n \trebase_setup_and_clean bad-cmd &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"1 2 3 bad 4 5\" \\\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"1 2 3 bad 4 5\" \\\n \t\tgit rebase -i --root 2>actual &&\n-\ttest_i18ngrep \"badcmd $(git rev-list --oneline -1 master~1)\" actual &&\n-\ttest_i18ngrep \"You can fix this with .git rebase --edit-todo..\" actual &&\n-\tFAKE_LINES=\"1 2 3 drop 4 5\" git rebase --edit-todo &&\n+\t\ttest_i18ngrep \"badcmd $(git rev-list --oneline -1 master~1)\" \\\n+\t\t\t\tactual &&\n+\t\ttest_i18ngrep \"You can fix this with .git rebase --edit-todo..\" \\\n+\t\t\t\tactual &&\n+\t\tFAKE_LINES=\"1 2 3 drop 4 5\" git rebase --edit-todo\n+\t) &&\n \tgit rebase --continue &&\n \ttest E = $(git cat-file commit HEAD | sed -ne \\$p) &&\n \ttest C = $(git cat-file commit HEAD^ | sed -ne \\$p)\n@@ -1398,19 +1523,24 @@ test_expect_success 'tabs and spaces are accepted in the todolist' '\n \t) >\"$1.new\"\n \tmv \"$1.new\" \"$1\"\n \tEOF\n-\ttest_set_editor \"$(pwd)/add-indent.sh\" &&\n-\tgit rebase -i HEAD^^^ &&\n+\t(\n+\t\ttest_set_editor \"$(pwd)/add-indent.sh\" &&\n+\t\tgit rebase -i HEAD^^^\n+\t) &&\n \ttest E = $(git cat-file commit HEAD | sed -ne \\$p)\n '\n \n test_expect_success 'static check of bad SHA-1' '\n \trebase_setup_and_clean bad-sha &&\n-\tset_fake_editor &&\n-\ttest_must_fail env FAKE_LINES=\"1 2 edit fakesha 3 4 5 #\" \\\n-\t\tgit rebase -i --root 2>actual &&\n-\ttest_i18ngrep \"edit XXXXXXX False commit\" actual &&\n-\ttest_i18ngrep \"You can fix this with .git rebase --edit-todo..\" actual &&\n-\tFAKE_LINES=\"1 2 4 5 6\" git rebase --edit-todo &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\ttest_must_fail env FAKE_LINES=\"1 2 edit fakesha 3 4 5 #\" \\\n+\t\t\tgit rebase -i --root 2>actual &&\n+\t\t\ttest_i18ngrep \"edit XXXXXXX False commit\" actual &&\n+\t\t\ttest_i18ngrep \"You can fix this with .git rebase --edit-todo..\" \\\n+\t\t\t\t\tactual &&\n+\t\tFAKE_LINES=\"1 2 4 5 6\" git rebase --edit-todo\n+\t) &&\n \tgit rebase --continue &&\n \ttest E = $(git cat-file commit HEAD | sed -ne \\$p)\n '\n@@ -1430,37 +1560,45 @@ test_expect_success 'editor saves as CR/LF' '\n SQ=\"'\"\n test_expect_success 'rebase -i --gpg-sign=<key-id>' '\n \ttest_when_finished \"test_might_fail git rebase --abort\" &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"edit 1\" git rebase -i --gpg-sign=\"\\\"S I Gner\\\"\" HEAD^ \\\n-\t\t>out 2>err &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"edit 1\" git rebase -i --gpg-sign=\"\\\"S I Gner\\\"\" \\\n+\t\t\tHEAD^ >out 2>err\n+\t) &&\n \ttest_i18ngrep \"$SQ-S\\\"S I Gner\\\"$SQ\" err\n '\n \n test_expect_success 'rebase -i --gpg-sign=<key-id> overrides commit.gpgSign' '\n \ttest_when_finished \"test_might_fail git rebase --abort\" &&\n \ttest_config commit.gpgsign true &&\n-\tset_fake_editor &&\n-\tFAKE_LINES=\"edit 1\" git rebase -i --gpg-sign=\"\\\"S I Gner\\\"\" HEAD^ \\\n-\t\t>out 2>err &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"edit 1\" git rebase -i --gpg-sign=\"\\\"S I Gner\\\"\" \\\n+\t\t\tHEAD^ >out 2>err\n+\t) &&\n \ttest_i18ngrep \"$SQ-S\\\"S I Gner\\\"$SQ\" err\n '\n \n test_expect_success 'valid author header after --root swap' '\n \trebase_setup_and_clean author-header no-conflict-branch &&\n-\tset_fake_editor &&\n \tgit commit --amend --author=\"Au ${SQ}thor <author@example.com>\" --no-edit &&\n \tgit cat-file commit HEAD | grep ^author >expected &&\n-\tFAKE_LINES=\"5 1\" git rebase -i --root &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"5 1\" git rebase -i --root\n+\t) &&\n \tgit cat-file commit HEAD^ | grep ^author >actual &&\n \ttest_cmp expected actual\n '\n \n test_expect_success 'valid author header when author contains single quote' '\n \trebase_setup_and_clean author-header no-conflict-branch &&\n-\tset_fake_editor &&\n \tgit commit --amend --author=\"Au ${SQ}thor <author@example.com>\" --no-edit &&\n \tgit cat-file commit HEAD | grep ^author >expected &&\n-\tFAKE_LINES=\"2\" git rebase -i HEAD~2 &&\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"2\" git rebase -i HEAD~2\n+\t) &&\n \tgit cat-file commit HEAD | grep ^author >actual &&\n \ttest_cmp expected actual\n '\n-- \ngitgitgadget\n\n"},{"id":"384076","messageId":"09857dee784910b2123764be8cced9364dac4844.1571135132.git.gitgitgadget@gmail.com","threadId":"52013","inReplyTo":"pull.388.v2.git.1571135132.gitgitgadget@gmail.com","subject":"[PATCH v2 3/6] t3404: remove uneeded calls to set_fake_editor","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-10-15T10:25:29Z","receivedAt":"2019-10-15T10:25:42Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nSome tests were calling set_fake_editor to ensure they had a sane no-op\neditor set. Now that all the editor setting is done in subshells these\ntests can rely on EDITOR=: and so do not need to call set_fake_editor.\n\nAlso add a test at the end to detect any future additions messing with\nthe exported value of $EDITOR.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n t/lib-rebase.sh               | 28 ++++++++++++++++++++++++++++\n t/t3404-rebase-interactive.sh | 25 +++++--------------------\n 2 files changed, 33 insertions(+), 20 deletions(-)\n\ndiff --git a/t/lib-rebase.sh b/t/lib-rebase.sh\nindex 7ea30e5006..e4554db85e 100644\n--- a/t/lib-rebase.sh\n+++ b/t/lib-rebase.sh\n@@ -118,3 +118,31 @@ make_empty () {\n \tgit commit --allow-empty -m \"$1\" &&\n \tgit tag \"$1\"\n }\n+\n+# Call this (inside test_expect_success) at the end of a test file to\n+# check that no tests have changed editor related environment\n+# variables or config settings\n+test_editor_unchanged () {\n+\t# We're only interested in exported variables hence 'sh -c'\n+\tsh -c 'cat >actual <<-EOF\n+\tEDITOR=$EDITOR\n+\tFAKE_COMMIT_AMEND=$FAKE_COMMIT_AMEND\n+\tFAKE_COMMIT_MESSAGE=$FAKE_COMMIT_MESSAGE\n+\tFAKE_LINES=$FAKE_LINES\n+\tGIT_EDITOR=$GIT_EDITOR\n+\tGIT_SEQUENCE_EDITOR=$GIT_SEQUENCE_EDITOR\n+\tcore.editor=$(git config core.editor)\n+\tsequence.editor=$(git config sequence.editor)\n+\tEOF'\n+\tcat >expect <<-\\EOF\n+\tEDITOR=:\n+\tFAKE_COMMIT_AMEND=\n+\tFAKE_COMMIT_MESSAGE=\n+\tFAKE_LINES=\n+\tGIT_EDITOR=\n+\tGIT_SEQUENCE_EDITOR=\n+\tcore.editor=\n+\tsequence.editor=\n+\tEOF\n+\ttest_cmp expect actual\n+}\ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex cb9b210000..c5d0326825 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -189,7 +189,6 @@ test_expect_success 'implicit interactive rebase does not invoke sequence editor\n \n test_expect_success 'no changes are a nop' '\n \tgit checkout branch2 &&\n-\tset_fake_editor &&\n \tgit rebase -i F &&\n \ttest \"$(git symbolic-ref -q HEAD)\" = \"refs/heads/branch2\" &&\n \ttest $(git rev-parse I) = $(git rev-parse HEAD)\n@@ -199,7 +198,6 @@ test_expect_success 'test the [branch] option' '\n \tgit checkout -b dead-end &&\n \tgit rm file6 &&\n \tgit commit -m \"stop here\" &&\n-\tset_fake_editor &&\n \tgit rebase -i F branch2 &&\n \ttest \"$(git symbolic-ref -q HEAD)\" = \"refs/heads/branch2\" &&\n \ttest $(git rev-parse I) = $(git rev-parse branch2) &&\n@@ -208,7 +206,6 @@ test_expect_success 'test the [branch] option' '\n \n test_expect_success 'test --onto <branch>' '\n \tgit checkout -b test-onto branch2 &&\n-\tset_fake_editor &&\n \tgit rebase -i --onto branch1 F &&\n \ttest \"$(git symbolic-ref -q HEAD)\" = \"refs/heads/test-onto\" &&\n \ttest $(git rev-parse HEAD^) = $(git rev-parse branch1) &&\n@@ -218,7 +215,6 @@ test_expect_success 'test --onto <branch>' '\n test_expect_success 'rebase on top of a non-conflicting commit' '\n \tgit checkout branch1 &&\n \tgit tag original-branch1 &&\n-\tset_fake_editor &&\n \tgit rebase -i branch2 &&\n \ttest file6 = $(git diff --name-only original-branch1) &&\n \ttest \"$(git symbolic-ref -q HEAD)\" = \"refs/heads/branch1\" &&\n@@ -264,7 +260,6 @@ test_expect_success 'stop on conflicting pick' '\n \t>>>>>>> 5d18e54... G\n \tEOF\n \tgit tag new-branch1 &&\n-\tset_fake_editor &&\n \ttest_must_fail git rebase -i master &&\n \ttest \"$(git rev-parse HEAD~3)\" = \"$(git rev-parse master)\" &&\n \ttest_cmp expect .git/rebase-merge/patch &&\n@@ -293,7 +288,6 @@ test_expect_success 'abort' '\n test_expect_success 'abort with error when new base cannot be checked out' '\n \tgit rm --cached file1 &&\n \tgit commit -m \"remove file in base\" &&\n-\tset_fake_editor &&\n \ttest_must_fail git rebase -i master > output 2>&1 &&\n \ttest_i18ngrep \"The following untracked working tree files would be overwritten by checkout:\" \\\n \t\toutput &&\n@@ -308,7 +302,6 @@ test_expect_success 'retain authorship' '\n \ttest_tick &&\n \tGIT_AUTHOR_NAME=\"Twerp Snog\" git commit -m \"different author\" &&\n \tgit tag twerp &&\n-\tset_fake_editor &&\n \tgit rebase -i --onto master HEAD^ &&\n \tgit show HEAD | grep \"^Author: Twerp Snog\"\n '\n@@ -326,7 +319,6 @@ test_expect_success 'retain authorship w/ conflicts' '\n \ttest_commit b conflict b conflict-b &&\n \tGIT_AUTHOR_NAME=$oGIT_AUTHOR_NAME &&\n \n-\tset_fake_editor &&\n \ttest_must_fail git rebase -i conflict-a &&\n \techo resolved >conflict &&\n \tgit add conflict &&\n@@ -357,7 +349,6 @@ test_expect_success 'retain authorship when squashing' '\n \n test_expect_success REBASE_P '-p handles \"no changes\" gracefully' '\n \tHEAD=$(git rev-parse HEAD) &&\n-\tset_fake_editor &&\n \tgit rebase -i -p HEAD^ &&\n \tgit update-index --refresh &&\n \tgit diff-files --quiet &&\n@@ -404,7 +395,6 @@ test_expect_success REBASE_P 'preserve merges with -p' '\n \tgit commit -m M file1 &&\n \tgit checkout -b to-be-rebased &&\n \ttest_tick &&\n-\tset_fake_editor &&\n \tgit rebase -i -p --onto branch1 master &&\n \tgit update-index --refresh &&\n \tgit diff-files --quiet &&\n@@ -450,7 +440,6 @@ test_expect_success '--continue tries to commit' '\n test_expect_success 'verbose flag is heeded, even after --continue' '\n \tgit reset --hard master@{1} &&\n \ttest_tick &&\n-\tset_fake_editor &&\n \ttest_must_fail git rebase -v -i --onto new-branch1 HEAD^ &&\n \techo resolved > file1 &&\n \tgit add file1 &&\n@@ -750,7 +739,6 @@ test_expect_success 'do \"noop\" when there is nothing to cherry-pick' '\n \tGIT_EDITOR=: git commit --amend \\\n \t\t--author=\"Somebody else <somebody@else.com>\" &&\n \ttest $(git rev-parse branch3) != $(git rev-parse branch4) &&\n-\tset_fake_editor &&\n \tgit rebase -i branch3 &&\n \ttest $(git rev-parse branch3) = $(git rev-parse branch4)\n \n@@ -775,7 +763,6 @@ test_expect_success 'submodule rebase setup' '\n \t\tgit commit -a -m \"submodule second\"\n \t) &&\n \ttest_tick &&\n-\tset_fake_editor &&\n \tgit commit -a -m \"Three changes submodule\"\n '\n \n@@ -800,7 +787,6 @@ test_expect_success 'submodule conflict setup' '\n '\n \n test_expect_success 'rebase -i continue with only submodule staged' '\n-\tset_fake_editor &&\n \ttest_must_fail git rebase -i submodule-base &&\n \tgit add sub &&\n \tgit rebase --continue &&\n@@ -810,7 +796,6 @@ test_expect_success 'rebase -i continue with only submodule staged' '\n test_expect_success 'rebase -i continue with unstaged submodule' '\n \tgit checkout submodule-topic &&\n \tgit reset --hard &&\n-\tset_fake_editor &&\n \ttest_must_fail git rebase -i submodule-base &&\n \tgit reset &&\n \tgit rebase --continue &&\n@@ -823,7 +808,6 @@ test_expect_success 'avoid unnecessary reset' '\n \ttest-tool chmtime =123456789 file3 &&\n \tgit update-index --refresh &&\n \tHEAD=$(git rev-parse HEAD) &&\n-\tset_fake_editor &&\n \tgit rebase -i HEAD~4 &&\n \ttest $HEAD = $(git rev-parse HEAD) &&\n \tMTIME=$(test-tool chmtime --get file3) &&\n@@ -858,7 +842,6 @@ test_expect_success 'rebase -i can copy notes' '\n \ttest_commit n2 &&\n \ttest_commit n3 &&\n \tgit notes add -m\"a note\" n3 &&\n-\tset_fake_editor &&\n \tgit rebase -i --onto n1 n2 &&\n \ttest \"a note\" = \"$(git notes show HEAD)\"\n '\n@@ -896,7 +879,6 @@ test_tick # Ensure that the rebased commits get a different timestamp.\n test_expect_success 'always cherry-pick with --no-ff' '\n \tgit checkout no-ff-branch &&\n \tgit tag original-no-ff-branch &&\n-\tset_fake_editor &&\n \tgit rebase -i --no-ff A &&\n \tfor p in 0 1 2\n \tdo\n@@ -1044,7 +1026,6 @@ test_expect_success 'rebase --exec works without -i ' '\n \n test_expect_success 'rebase -i --exec without <CMD>' '\n \tgit reset --hard execute &&\n-\tset_fake_editor &&\n \ttest_must_fail git rebase -i --exec 2>actual &&\n \ttest_i18ngrep \"requires a value\" actual &&\n \tgit checkout master\n@@ -1180,7 +1161,6 @@ test_expect_success 'rebase --edit-todo can be used to modify todo' '\n test_expect_success 'rebase -i produces readable reflog' '\n \tgit reset --hard &&\n \tgit branch -f branch-reflog-test H &&\n-\tset_fake_editor &&\n \tgit rebase -i --onto I F branch-reflog-test &&\n \tcat >expect <<-\\EOF &&\n \trebase -i (finish): returning to refs/heads/branch-reflog-test\n@@ -1603,4 +1583,9 @@ test_expect_success 'valid author header when author contains single quote' '\n \ttest_cmp expected actual\n '\n \n+# This must be the last test in this file\n+test_expect_success '$EDITOR and friends are unchanged' '\n+\ttest_editor_unchanged\n+'\n+\n test_done\n-- \ngitgitgadget\n\n"},{"id":"384077","messageId":"pull.388.v2.git.1571135132.gitgitgadget@gmail.com","threadId":"52013","inReplyTo":"pull.388.git.gitgitgadget@gmail.com","subject":"[PATCH v2 0/6] sequencer: start running post-commit hook again","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-10-15T10:25:26Z","receivedAt":"2019-10-15T10:25:44Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"When I converted the sequencer to avoid forking git commit i forgot about\nthe post-commit hook. These patches are based on\npw/rebase-i-show-HEAD-to-reword, otherwise the new test fails as that branch\nchanges the number of commits we make.\n\nThanks to Dscho & Junio for their comments on V1. I've made the following\nchanges:\n\nPatches 1-3 These are new patches in response to Dscho's request to set\n$EDITOR in a subshell. There were ~80 other tests that weren't doing that\nand they are fixed in these patches. Patch 2 contains the main action,\nunfortunately due to a combination of having to remove the trailing ' &&'\nfrom the last line moved into the subshell and re-wrapping some lines due to\nthe increased indentation --color-moved and --color-moved-ws are of limited\nuse when viewing this patch.\n\nPatch 4 (was 1) Unchanged\n\nPatch 5 (was 2) I've moved the function definition to commit.c rather than\nsequencer.c as suggested. I've also removed an unused struct argv_array from\nrun_prepare_commit_msg_hook() (There wasn't a compiler warning as it was\nstill calling argv_array_clear() at the end of the function) and reworded\nthe commit message.\n\nPatch 6 (was 3) I've tided up the test and removed the wrapper function for\nrunning the post-commit hook as suggested.\n\nPhillip Wood (6):\n  t3404: remove unnecessary subshell\n  t3404: set $EDITOR in subshell\n  t3404: remove uneeded calls to set_fake_editor\n  sequencer.h fix placement of #endif\n  move run_commit_hook() to libgit and use it there\n  sequencer: run post-commit hook\n\n builtin/commit.c              |  22 --\n commit.c                      |  24 ++\n sequencer.c                   |  24 +-\n sequencer.h                   |   3 +-\n t/lib-rebase.sh               |  28 ++\n t/t3404-rebase-interactive.sh | 596 +++++++++++++++++++++-------------\n 6 files changed, 432 insertions(+), 265 deletions(-)\n\n\nbase-commit: b0a3186140dbc7bd64cbc6ef733386a0f1eb6a4d\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-388%2Fphillipwood%2Fwip%2Frebase-commit-hooks-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-388/phillipwood/wip/rebase-commit-hooks-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/388\n\nRange-diff vs v1:\n\n -:  ---------- > 1:  b9689e85e5 t3404: remove unnecessary subshell\n -:  ---------- > 2:  96432cd0f0 t3404: set $EDITOR in subshell\n -:  ---------- > 3:  09857dee78 t3404: remove uneeded calls to set_fake_editor\n 1:  7305f8d8e8 = 4:  0eac3ede02 sequencer.h fix placement of #endif\n 2:  420ecf442c ! 5:  f394a0e163 sequencer: use run_commit_hook()\n     @@ -1,9 +1,11 @@\n      Author: Phillip Wood <phillip.wood@dunelm.org.uk>\n      \n     -    sequencer: use run_commit_hook()\n     +    move run_commit_hook() to libgit and use it there\n      \n     -    This simplifies the implementation of run_prepare_commit_msg_hook() and\n     -    will be used in the next commit.\n     +    This function was declared in commit.h but was implemented in\n     +    builtin/commit.c so was not part of libgit. Move it to libgit so we can\n     +    use it in the sequencer. This simplifies the implementation of\n     +    run_prepare_commit_msg_hook() and will be used in the next commit.\n      \n          Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n      \n     @@ -40,25 +42,22 @@\n       {\n       \tconst char *argv_gc_auto[] = {\"gc\", \"--auto\", NULL};\n      \n     - diff --git a/commit.h b/commit.h\n     - --- a/commit.h\n     - +++ b/commit.h\n     + diff --git a/commit.c b/commit.c\n     + --- a/commit.c\n     + +++ b/commit.c\n      @@\n     - int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused);\n     - int compare_commits_by_gen_then_commit_date(const void *a_, const void *b_, void *unused);\n     + #include \"advice.h\"\n     + #include \"refs.h\"\n     + #include \"commit-reach.h\"\n     ++#include \"run-command.h\"\n     + \n     + static struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);\n       \n     --LAST_ARG_MUST_BE_NULL\n     --int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n     --\n     - #endif /* COMMIT_H */\n     -\n     - diff --git a/sequencer.c b/sequencer.c\n     - --- a/sequencer.c\n     - +++ b/sequencer.c\n      @@\n     - \trun_rewrite_hook(&old_head->object.oid, new_head);\n     + \t}\n     + \treturn boc ? len - boc : len - cutoff;\n       }\n     - \n     ++\n      +int run_commit_hook(int editor_is_used, const char *index_file,\n      +\t\t    const char *name, ...)\n      +{\n     @@ -81,12 +80,15 @@\n      +\n      +\treturn ret;\n      +}\n     -+\n     - static int run_prepare_commit_msg_hook(struct repository *r,\n     +\n     + diff --git a/sequencer.c b/sequencer.c\n     + --- a/sequencer.c\n     + +++ b/sequencer.c\n     +@@\n       \t\t\t\t       struct strbuf *msg,\n       \t\t\t\t       const char *commit)\n       {\n     - \tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n     +-\tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n      -\tint ret;\n      -\tconst char *name;\n      +\tint ret = 0;\n     @@ -114,18 +116,7 @@\n      +\tif (run_commit_hook(0, r->index_file, \"prepare-commit-msg\", name,\n      +\t\t\t    arg1, arg2, NULL))\n       \t\tret = error(_(\"'prepare-commit-msg' hook failed\"));\n     -+\n     - \targv_array_clear(&hook_env);\n     +-\targv_array_clear(&hook_env);\n       \n       \treturn ret;\n     -\n     - diff --git a/sequencer.h b/sequencer.h\n     - --- a/sequencer.h\n     - +++ b/sequencer.h\n     -@@\n     - void sequencer_post_commit_cleanup(struct repository *r);\n     - int sequencer_get_last_command(struct repository* r,\n     - \t\t\t       enum replay_action *action);\n     -+LAST_ARG_MUST_BE_NULL\n     -+int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n     - #endif /* SEQUENCER_H */\n     + }\n 3:  acaa086a48 ! 6:  67a711754e sequencer: run post-commit hook\n     @@ -10,52 +10,18 @@\n      \n          Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n      \n     - diff --git a/builtin/commit.c b/builtin/commit.c\n     - --- a/builtin/commit.c\n     - +++ b/builtin/commit.c\n     -@@\n     - \n     - \trepo_rerere(the_repository, 0);\n     - \trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n     --\trun_commit_hook(use_editor, get_index_file(), \"post-commit\", NULL);\n     -+\trun_post_commit_hook(use_editor, get_index_file());\n     - \tif (amend && !no_post_rewrite) {\n     - \t\tcommit_post_rewrite(the_repository, current_head, &oid);\n     - \t}\n     -\n       diff --git a/sequencer.c b/sequencer.c\n       --- a/sequencer.c\n       +++ b/sequencer.c\n     -@@\n     - \treturn ret;\n     - }\n     - \n     -+void run_post_commit_hook(int editor_is_used, const char *index_file) {\n     -+\trun_commit_hook(editor_is_used, index_file, \"post-commit\", NULL);\n     -+}\n     -+\n     - static const char implicit_ident_advice_noconfig[] =\n     - N_(\"Your name and email address were configured automatically based\\n\"\n     - \"on your username and hostname. Please check that they are accurate.\\n\"\n      @@\n       \t\tgoto out;\n       \t}\n       \n     -+\trun_post_commit_hook(0, r->index_file);\n     ++\trun_commit_hook(0, r->index_file, \"post-commit\", NULL);\n       \tif (flags & AMEND_MSG)\n       \t\tcommit_post_rewrite(r, current_head, oid);\n       \n      \n     - diff --git a/sequencer.h b/sequencer.h\n     - --- a/sequencer.h\n     - +++ b/sequencer.h\n     -@@\n     - \t\t\t       enum replay_action *action);\n     - LAST_ARG_MUST_BE_NULL\n     - int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n     -+void run_post_commit_hook(int editor_is_used, const char *index_file);\n     - #endif /* SEQUENCER_H */\n     -\n       diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\n       --- a/t/t3404-rebase-interactive.sh\n       +++ b/t/t3404-rebase-interactive.sh\n     @@ -64,20 +30,24 @@\n       '\n       \n      +test_expect_success 'post-commit hook is called' '\n     -+\ttest_when_finished \"rm -f .git/hooks/post-commit commits\" &&\n     ++\ttest_when_finished \"rm -f .git/hooks/post-commit\" &&\n     ++\t>actual &&\n      +\tmkdir -p .git/hooks &&\n      +\twrite_script .git/hooks/post-commit <<-\\EOS &&\n     -+\tgit rev-parse HEAD >>commits\n     ++\tgit rev-parse HEAD >>actual\n      +\tEOS\n     -+\tset_fake_editor &&\n     -+\tFAKE_LINES=\"edit 4 1 reword 2 fixup 3\" git rebase -i A E &&\n     -+\techo x>file3 &&\n     -+\tgit add file3 &&\n     -+\tFAKE_COMMIT_MESSAGE=edited git rebase --continue &&\n     -+\t# rev-list does not support -g --reverse\n     -+\tgit rev-list --no-walk=unsorted HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} \\\n     -+\t\tHEAD@{1} HEAD >expected &&\n     -+\ttest_cmp expected commits\n     ++\t(\n     ++\t\tset_fake_editor &&\n     ++\t\tFAKE_LINES=\"edit 4 1 reword 2 fixup 3\" git rebase -i A E &&\n     ++\t\techo x>file3 &&\n     ++\t\tgit add file3 &&\n     ++\t\tFAKE_COMMIT_MESSAGE=edited git rebase --continue\n     ++\t) &&\n     ++\tgit rev-parse HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} HEAD@{1} HEAD \\\n     ++\t\t>expect &&\n     ++\ttest_cmp expect actual\n      +'\n      +\n     - test_done\n     + # This must be the last test in this file\n     + test_expect_success '$EDITOR and friends are unchanged' '\n     + \ttest_editor_unchanged\n\n-- \ngitgitgadget\n"},{"id":"384078","messageId":"67a711754efce038914e8ec15c5dec4a5983566d.1571135132.git.gitgitgadget@gmail.com","threadId":"52013","inReplyTo":"pull.388.v2.git.1571135132.gitgitgadget@gmail.com","subject":"[PATCH v2 6/6] sequencer: run post-commit hook","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-10-15T10:25:32Z","receivedAt":"2019-10-15T10:25:45Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nPrior to commit 356ee4659b (\"sequencer: try to commit without forking\n'git commit'\", 2017-11-24) the sequencer would always run the\npost-commit hook after each pick or revert as it forked `git commit` to\ncreate the commit. The conversion to committing without forking `git\ncommit` omitted to call the post-commit hook after creating the commit.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n sequencer.c                   |  1 +\n t/t3404-rebase-interactive.sh | 19 +++++++++++++++++++\n 2 files changed, 20 insertions(+)\n\ndiff --git a/sequencer.c b/sequencer.c\nindex cdc0d1dfba..da2decbd3a 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -1401,6 +1401,7 @@ static int try_to_commit(struct repository *r,\n \t\tgoto out;\n \t}\n \n+\trun_commit_hook(0, r->index_file, \"post-commit\", NULL);\n \tif (flags & AMEND_MSG)\n \t\tcommit_post_rewrite(r, current_head, oid);\n \ndiff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\nindex c5d0326825..c573c99069 100755\n--- a/t/t3404-rebase-interactive.sh\n+++ b/t/t3404-rebase-interactive.sh\n@@ -1583,6 +1583,25 @@ test_expect_success 'valid author header when author contains single quote' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success 'post-commit hook is called' '\n+\ttest_when_finished \"rm -f .git/hooks/post-commit\" &&\n+\t>actual &&\n+\tmkdir -p .git/hooks &&\n+\twrite_script .git/hooks/post-commit <<-\\EOS &&\n+\tgit rev-parse HEAD >>actual\n+\tEOS\n+\t(\n+\t\tset_fake_editor &&\n+\t\tFAKE_LINES=\"edit 4 1 reword 2 fixup 3\" git rebase -i A E &&\n+\t\techo x>file3 &&\n+\t\tgit add file3 &&\n+\t\tFAKE_COMMIT_MESSAGE=edited git rebase --continue\n+\t) &&\n+\tgit rev-parse HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} HEAD@{1} HEAD \\\n+\t\t>expect &&\n+\ttest_cmp expect actual\n+'\n+\n # This must be the last test in this file\n test_expect_success '$EDITOR and friends are unchanged' '\n \ttest_editor_unchanged\n-- \ngitgitgadget\n"},{"id":"384079","messageId":"0eac3ede02c9518ce81ba113e0dc2f7d78f5a22c.1571135132.git.gitgitgadget@gmail.com","threadId":"52013","inReplyTo":"pull.388.v2.git.1571135132.gitgitgadget@gmail.com","subject":"[PATCH v2 4/6] sequencer.h fix placement of #endif","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-10-15T10:25:30Z","receivedAt":"2019-10-15T10:25:46Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nCommit 65850686cf (\"rebase -i: rewrite write_basic_state() in C\",\n2018-08-28) accidentially added new function declarations after\nthe #endif at the end of the include guard.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n sequencer.h | 3 +--\n 1 file changed, 1 insertion(+), 2 deletions(-)\n\ndiff --git a/sequencer.h b/sequencer.h\nindex 0c494b83d4..ac66892d71 100644\n--- a/sequencer.h\n+++ b/sequencer.h\n@@ -195,11 +195,10 @@ void print_commit_summary(struct repository *repo,\n \n int read_author_script(const char *path, char **name, char **email, char **date,\n \t\t       int allow_missing);\n-#endif\n-\n void parse_strategy_opts(struct replay_opts *opts, char *raw_opts);\n int write_basic_state(struct replay_opts *opts, const char *head_name,\n \t\t      struct commit *onto, const char *orig_head);\n void sequencer_post_commit_cleanup(struct repository *r);\n int sequencer_get_last_command(struct repository* r,\n \t\t\t       enum replay_action *action);\n+#endif /* SEQUENCER_H */\n-- \ngitgitgadget\n\n"},{"id":"384080","messageId":"f394a0e1634d865b64b0e44135e525e3c5a2cf3f.1571135132.git.gitgitgadget@gmail.com","threadId":"52013","inReplyTo":"pull.388.v2.git.1571135132.gitgitgadget@gmail.com","subject":"[PATCH v2 5/6] move run_commit_hook() to libgit and use it there","fromName":"Phillip Wood via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2019-10-15T10:25:31Z","receivedAt":"2019-10-15T10:25:46Z","isPatch":true,"sender":{"key":"phillip.wood@dunelm.org.uk","avatar":null},"body":"From: Phillip Wood <phillip.wood@dunelm.org.uk>\n\nThis function was declared in commit.h but was implemented in\nbuiltin/commit.c so was not part of libgit. Move it to libgit so we can\nuse it in the sequencer. This simplifies the implementation of\nrun_prepare_commit_msg_hook() and will be used in the next commit.\n\nSigned-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n---\n builtin/commit.c | 22 ----------------------\n commit.c         | 24 ++++++++++++++++++++++++\n sequencer.c      | 23 ++++++++++-------------\n 3 files changed, 34 insertions(+), 35 deletions(-)\n\ndiff --git a/builtin/commit.c b/builtin/commit.c\nindex 1921401117..d898a57f5d 100644\n--- a/builtin/commit.c\n+++ b/builtin/commit.c\n@@ -1443,28 +1443,6 @@ static int git_commit_config(const char *k, const char *v, void *cb)\n \treturn git_status_config(k, v, s);\n }\n \n-int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...)\n-{\n-\tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n-\tva_list args;\n-\tint ret;\n-\n-\targv_array_pushf(&hook_env, \"GIT_INDEX_FILE=%s\", index_file);\n-\n-\t/*\n-\t * Let the hook know that no editor will be launched.\n-\t */\n-\tif (!editor_is_used)\n-\t\targv_array_push(&hook_env, \"GIT_EDITOR=:\");\n-\n-\tva_start(args, name);\n-\tret = run_hook_ve(hook_env.argv,name, args);\n-\tva_end(args);\n-\targv_array_clear(&hook_env);\n-\n-\treturn ret;\n-}\n-\n int cmd_commit(int argc, const char **argv, const char *prefix)\n {\n \tconst char *argv_gc_auto[] = {\"gc\", \"--auto\", NULL};\ndiff --git a/commit.c b/commit.c\nindex 26ce0770f6..7ca8d12174 100644\n--- a/commit.c\n+++ b/commit.c\n@@ -19,6 +19,7 @@\n #include \"advice.h\"\n #include \"refs.h\"\n #include \"commit-reach.h\"\n+#include \"run-command.h\"\n \n static struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);\n \n@@ -1581,3 +1582,26 @@ size_t ignore_non_trailer(const char *buf, size_t len)\n \t}\n \treturn boc ? len - boc : len - cutoff;\n }\n+\n+int run_commit_hook(int editor_is_used, const char *index_file,\n+\t\t    const char *name, ...)\n+{\n+\tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n+\tva_list args;\n+\tint ret;\n+\n+\targv_array_pushf(&hook_env, \"GIT_INDEX_FILE=%s\", index_file);\n+\n+\t/*\n+\t * Let the hook know that no editor will be launched.\n+\t */\n+\tif (!editor_is_used)\n+\t\targv_array_push(&hook_env, \"GIT_EDITOR=:\");\n+\n+\tva_start(args, name);\n+\tret = run_hook_ve(hook_env.argv,name, args);\n+\tva_end(args);\n+\targv_array_clear(&hook_env);\n+\n+\treturn ret;\n+}\ndiff --git a/sequencer.c b/sequencer.c\nindex 2adcf5a639..cdc0d1dfba 100644\n--- a/sequencer.c\n+++ b/sequencer.c\n@@ -1127,25 +1127,22 @@ static int run_prepare_commit_msg_hook(struct repository *r,\n \t\t\t\t       struct strbuf *msg,\n \t\t\t\t       const char *commit)\n {\n-\tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n-\tint ret;\n-\tconst char *name;\n+\tint ret = 0;\n+\tconst char *name, *arg1 = NULL, *arg2 = NULL;\n \n \tname = git_path_commit_editmsg();\n \tif (write_message(msg->buf, msg->len, name, 0))\n \t\treturn -1;\n \n-\targv_array_pushf(&hook_env, \"GIT_INDEX_FILE=%s\", r->index_file);\n-\targv_array_push(&hook_env, \"GIT_EDITOR=:\");\n-\tif (commit)\n-\t\tret = run_hook_le(hook_env.argv, \"prepare-commit-msg\", name,\n-\t\t\t\t  \"commit\", commit, NULL);\n-\telse\n-\t\tret = run_hook_le(hook_env.argv, \"prepare-commit-msg\", name,\n-\t\t\t\t  \"message\", NULL);\n-\tif (ret)\n+\tif (commit) {\n+\t\targ1 = \"commit\";\n+\t\targ2 = commit;\n+\t} else {\n+\t\targ1 = \"message\";\n+\t}\n+\tif (run_commit_hook(0, r->index_file, \"prepare-commit-msg\", name,\n+\t\t\t    arg1, arg2, NULL))\n \t\tret = error(_(\"'prepare-commit-msg' hook failed\"));\n-\targv_array_clear(&hook_env);\n \n \treturn ret;\n }\n-- \ngitgitgadget\n\n"},{"id":"384102","messageId":"nycvar.QRO.7.76.6.1910151624450.46@tvgsbejvaqbjf.bet","threadId":"52013","inReplyTo":"pull.388.v2.git.1571135132.gitgitgadget@gmail.com","subject":"Re: [PATCH v2 0/6] sequencer: start running post-commit hook again","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2019-10-15T14:26:01Z","receivedAt":"2019-10-15T14:26:30Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Phillip,\n\nOn Tue, 15 Oct 2019, Phillip Wood via GitGitGadget wrote:\n\n> When I converted the sequencer to avoid forking git commit i forgot about\n> the post-commit hook. These patches are based on\n> pw/rebase-i-show-HEAD-to-reword, otherwise the new test fails as that branch\n> changes the number of commits we make.\n>\n> Thanks to Dscho & Junio for their comments on V1. I've made the following\n> changes:\n>\n> Patches 1-3 These are new patches in response to Dscho's request to set\n> $EDITOR in a subshell. There were ~80 other tests that weren't doing that\n> and they are fixed in these patches. Patch 2 contains the main action,\n> unfortunately due to a combination of having to remove the trailing ' &&'\n> from the last line moved into the subshell and re-wrapping some lines due to\n> the increased indentation --color-moved and --color-moved-ws are of limited\n> use when viewing this patch.\n>\n> Patch 4 (was 1) Unchanged\n>\n> Patch 5 (was 2) I've moved the function definition to commit.c rather than\n> sequencer.c as suggested. I've also removed an unused struct argv_array from\n> run_prepare_commit_msg_hook() (There wasn't a compiler warning as it was\n> still calling argv_array_clear() at the end of the function) and reworded\n> the commit message.\n>\n> Patch 6 (was 3) I've tided up the test and removed the wrapper function for\n> running the post-commit hook as suggested.\n\nI had a look over the patches, too, and all looks good to me.\n\nThank you so much!\nDscho\n\n>\n> Phillip Wood (6):\n>   t3404: remove unnecessary subshell\n>   t3404: set $EDITOR in subshell\n>   t3404: remove uneeded calls to set_fake_editor\n>   sequencer.h fix placement of #endif\n>   move run_commit_hook() to libgit and use it there\n>   sequencer: run post-commit hook\n>\n>  builtin/commit.c              |  22 --\n>  commit.c                      |  24 ++\n>  sequencer.c                   |  24 +-\n>  sequencer.h                   |   3 +-\n>  t/lib-rebase.sh               |  28 ++\n>  t/t3404-rebase-interactive.sh | 596 +++++++++++++++++++++-------------\n>  6 files changed, 432 insertions(+), 265 deletions(-)\n>\n>\n> base-commit: b0a3186140dbc7bd64cbc6ef733386a0f1eb6a4d\n> Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-388%2Fphillipwood%2Fwip%2Frebase-commit-hooks-v2\n> Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-388/phillipwood/wip/rebase-commit-hooks-v2\n> Pull-Request: https://github.com/gitgitgadget/git/pull/388\n>\n> Range-diff vs v1:\n>\n>  -:  ---------- > 1:  b9689e85e5 t3404: remove unnecessary subshell\n>  -:  ---------- > 2:  96432cd0f0 t3404: set $EDITOR in subshell\n>  -:  ---------- > 3:  09857dee78 t3404: remove uneeded calls to set_fake_editor\n>  1:  7305f8d8e8 = 4:  0eac3ede02 sequencer.h fix placement of #endif\n>  2:  420ecf442c ! 5:  f394a0e163 sequencer: use run_commit_hook()\n>      @@ -1,9 +1,11 @@\n>       Author: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n>      -    sequencer: use run_commit_hook()\n>      +    move run_commit_hook() to libgit and use it there\n>\n>      -    This simplifies the implementation of run_prepare_commit_msg_hook() and\n>      -    will be used in the next commit.\n>      +    This function was declared in commit.h but was implemented in\n>      +    builtin/commit.c so was not part of libgit. Move it to libgit so we can\n>      +    use it in the sequencer. This simplifies the implementation of\n>      +    run_prepare_commit_msg_hook() and will be used in the next commit.\n>\n>           Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n>      @@ -40,25 +42,22 @@\n>        {\n>        \tconst char *argv_gc_auto[] = {\"gc\", \"--auto\", NULL};\n>\n>      - diff --git a/commit.h b/commit.h\n>      - --- a/commit.h\n>      - +++ b/commit.h\n>      + diff --git a/commit.c b/commit.c\n>      + --- a/commit.c\n>      + +++ b/commit.c\n>       @@\n>      - int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused);\n>      - int compare_commits_by_gen_then_commit_date(const void *a_, const void *b_, void *unused);\n>      + #include \"advice.h\"\n>      + #include \"refs.h\"\n>      + #include \"commit-reach.h\"\n>      ++#include \"run-command.h\"\n>      +\n>      + static struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);\n>\n>      --LAST_ARG_MUST_BE_NULL\n>      --int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n>      --\n>      - #endif /* COMMIT_H */\n>      -\n>      - diff --git a/sequencer.c b/sequencer.c\n>      - --- a/sequencer.c\n>      - +++ b/sequencer.c\n>       @@\n>      - \trun_rewrite_hook(&old_head->object.oid, new_head);\n>      + \t}\n>      + \treturn boc ? len - boc : len - cutoff;\n>        }\n>      -\n>      ++\n>       +int run_commit_hook(int editor_is_used, const char *index_file,\n>       +\t\t    const char *name, ...)\n>       +{\n>      @@ -81,12 +80,15 @@\n>       +\n>       +\treturn ret;\n>       +}\n>      -+\n>      - static int run_prepare_commit_msg_hook(struct repository *r,\n>      +\n>      + diff --git a/sequencer.c b/sequencer.c\n>      + --- a/sequencer.c\n>      + +++ b/sequencer.c\n>      +@@\n>        \t\t\t\t       struct strbuf *msg,\n>        \t\t\t\t       const char *commit)\n>        {\n>      - \tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n>      +-\tstruct argv_array hook_env = ARGV_ARRAY_INIT;\n>       -\tint ret;\n>       -\tconst char *name;\n>       +\tint ret = 0;\n>      @@ -114,18 +116,7 @@\n>       +\tif (run_commit_hook(0, r->index_file, \"prepare-commit-msg\", name,\n>       +\t\t\t    arg1, arg2, NULL))\n>        \t\tret = error(_(\"'prepare-commit-msg' hook failed\"));\n>      -+\n>      - \targv_array_clear(&hook_env);\n>      +-\targv_array_clear(&hook_env);\n>\n>        \treturn ret;\n>      -\n>      - diff --git a/sequencer.h b/sequencer.h\n>      - --- a/sequencer.h\n>      - +++ b/sequencer.h\n>      -@@\n>      - void sequencer_post_commit_cleanup(struct repository *r);\n>      - int sequencer_get_last_command(struct repository* r,\n>      - \t\t\t       enum replay_action *action);\n>      -+LAST_ARG_MUST_BE_NULL\n>      -+int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n>      - #endif /* SEQUENCER_H */\n>      + }\n>  3:  acaa086a48 ! 6:  67a711754e sequencer: run post-commit hook\n>      @@ -10,52 +10,18 @@\n>\n>           Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>\n>\n>      - diff --git a/builtin/commit.c b/builtin/commit.c\n>      - --- a/builtin/commit.c\n>      - +++ b/builtin/commit.c\n>      -@@\n>      -\n>      - \trepo_rerere(the_repository, 0);\n>      - \trun_command_v_opt(argv_gc_auto, RUN_GIT_CMD);\n>      --\trun_commit_hook(use_editor, get_index_file(), \"post-commit\", NULL);\n>      -+\trun_post_commit_hook(use_editor, get_index_file());\n>      - \tif (amend && !no_post_rewrite) {\n>      - \t\tcommit_post_rewrite(the_repository, current_head, &oid);\n>      - \t}\n>      -\n>        diff --git a/sequencer.c b/sequencer.c\n>        --- a/sequencer.c\n>        +++ b/sequencer.c\n>      -@@\n>      - \treturn ret;\n>      - }\n>      -\n>      -+void run_post_commit_hook(int editor_is_used, const char *index_file) {\n>      -+\trun_commit_hook(editor_is_used, index_file, \"post-commit\", NULL);\n>      -+}\n>      -+\n>      - static const char implicit_ident_advice_noconfig[] =\n>      - N_(\"Your name and email address were configured automatically based\\n\"\n>      - \"on your username and hostname. Please check that they are accurate.\\n\"\n>       @@\n>        \t\tgoto out;\n>        \t}\n>\n>      -+\trun_post_commit_hook(0, r->index_file);\n>      ++\trun_commit_hook(0, r->index_file, \"post-commit\", NULL);\n>        \tif (flags & AMEND_MSG)\n>        \t\tcommit_post_rewrite(r, current_head, oid);\n>\n>\n>      - diff --git a/sequencer.h b/sequencer.h\n>      - --- a/sequencer.h\n>      - +++ b/sequencer.h\n>      -@@\n>      - \t\t\t       enum replay_action *action);\n>      - LAST_ARG_MUST_BE_NULL\n>      - int run_commit_hook(int editor_is_used, const char *index_file, const char *name, ...);\n>      -+void run_post_commit_hook(int editor_is_used, const char *index_file);\n>      - #endif /* SEQUENCER_H */\n>      -\n>        diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh\n>        --- a/t/t3404-rebase-interactive.sh\n>        +++ b/t/t3404-rebase-interactive.sh\n>      @@ -64,20 +30,24 @@\n>        '\n>\n>       +test_expect_success 'post-commit hook is called' '\n>      -+\ttest_when_finished \"rm -f .git/hooks/post-commit commits\" &&\n>      ++\ttest_when_finished \"rm -f .git/hooks/post-commit\" &&\n>      ++\t>actual &&\n>       +\tmkdir -p .git/hooks &&\n>       +\twrite_script .git/hooks/post-commit <<-\\EOS &&\n>      -+\tgit rev-parse HEAD >>commits\n>      ++\tgit rev-parse HEAD >>actual\n>       +\tEOS\n>      -+\tset_fake_editor &&\n>      -+\tFAKE_LINES=\"edit 4 1 reword 2 fixup 3\" git rebase -i A E &&\n>      -+\techo x>file3 &&\n>      -+\tgit add file3 &&\n>      -+\tFAKE_COMMIT_MESSAGE=edited git rebase --continue &&\n>      -+\t# rev-list does not support -g --reverse\n>      -+\tgit rev-list --no-walk=unsorted HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} \\\n>      -+\t\tHEAD@{1} HEAD >expected &&\n>      -+\ttest_cmp expected commits\n>      ++\t(\n>      ++\t\tset_fake_editor &&\n>      ++\t\tFAKE_LINES=\"edit 4 1 reword 2 fixup 3\" git rebase -i A E &&\n>      ++\t\techo x>file3 &&\n>      ++\t\tgit add file3 &&\n>      ++\t\tFAKE_COMMIT_MESSAGE=edited git rebase --continue\n>      ++\t) &&\n>      ++\tgit rev-parse HEAD@{5} HEAD@{4} HEAD@{3} HEAD@{2} HEAD@{1} HEAD \\\n>      ++\t\t>expect &&\n>      ++\ttest_cmp expect actual\n>       +'\n>       +\n>      - test_done\n>      + # This must be the last test in this file\n>      + test_expect_success '$EDITOR and friends are unchanged' '\n>      + \ttest_editor_unchanged\n>\n> --\n> gitgitgadget\n>\n"},{"id":"384151","messageId":"xmqqtv89a31p.fsf@gitster-ct.c.googlers.com","threadId":"52013","inReplyTo":"nycvar.QRO.7.76.6.1910151624450.46@tvgsbejvaqbjf.bet","subject":"Re: [PATCH v2 0/6] sequencer: start running post-commit hook again","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-10-16T01:32:02Z","receivedAt":"2019-10-16T01:32:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Hi Phillip,\n>\n> On Tue, 15 Oct 2019, Phillip Wood via GitGitGadget wrote:\n>\n>> When I converted the sequencer to avoid forking git commit i forgot about\n>> the post-commit hook. These patches are based on\n>> pw/rebase-i-show-HEAD-to-reword, otherwise the new test fails as that branch\n>> changes the number of commits we make.\n>> ...\n>\n> I had a look over the patches, too, and all looks good to me.\n\nMe three; thanks, both.\n"}]}