sequencer: update reading author-script

Rather than abusing a strbuf to come up with an environment block, let's just use the argv_array structure which serves the same purpose much better. While at it, rename the function to reflect the fact that it does not really care exactly what environment variables are defined in said file. Suggested-by: Jeff King <peff@peff.net> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Jan 2, 2017 at 16:35 UTC a2a20b0d5c97580497da37814c8b62114ce25f81
2 files changed +28 -22
sequencer.c
+12 -22
@@ -544,18 +544,17 @@ missing_author:
544 }
545
546 /*
547 - * Read the author-script file into an environment block, ready for use in
548 - * run_command(), that can be free()d afterwards.
547 + * Read a list of environment variable assignments (such as the author-script
548 + * file) into an environment block. Returns -1 on error, 0 otherwise.
549 */
550 -static char **read_author_script(void)
550 +static int read_env_script(struct argv_array *env)
551 {
552 struct strbuf script = STRBUF_INIT;
553 int i, count = 0;
554 - char *p, *p2, **env;
555 - size_t env_size;
554 + char *p, *p2;
555
556 if (strbuf_read_file(&script, rebase_path_author_script(), 256) <= 0)
558 - return NULL;
557 + return -1;
558
559 for (p = script.buf; *p; p++)
560 if (skip_prefix(p, "'\\\\''", (const char **)&p2))
@@ -567,19 +566,12 @@ static char **read_author_script(void)
566 count++;
567 }
568
570 - env_size = (count + 1) * sizeof(*env);
571 - strbuf_grow(&script, env_size);
572 - memmove(script.buf + env_size, script.buf, script.len);
573 - p = script.buf + env_size;
574 - env = (char **)strbuf_detach(&script, NULL);
575 -
576 - for (i = 0; i < count; i++) {
577 - env[i] = p;
569 + for (i = 0, p = script.buf; i < count; i++) {
570 + argv_array_push(env, p);
571 p += strlen(p) + 1;
572 }
580 - env[count] = NULL;
573
582 - return env;
574 + return 0;
575 }
576
577 static const char staged_changes_advice[] =
@@ -612,14 +604,12 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
604 int allow_empty, int edit, int amend,
605 int cleanup_commit_message)
606 {
615 - char **env = NULL;
616 - struct argv_array array;
607 + struct argv_array env = ARGV_ARRAY_INIT, array;
608 int rc;
609 const char *value;
610
611 if (is_rebase_i(opts)) {
621 - env = read_author_script();
622 - if (!env) {
612 + if (!read_env_script(&env)) {
613 const char *gpg_opt = gpg_sign_opt_quoted(opts);
614
615 return error(_(staged_changes_advice),
@@ -655,9 +645,9 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
645 argv_array_push(&array, "--allow-empty-message");
646
647 rc = run_command_v_opt_cd_env(array.argv, RUN_GIT_CMD, NULL,
658 - (const char *const *)env);
648 + (const char *const *)env.argv);
649 argv_array_clear(&array);
660 - free(env);
650 + argv_array_clear(&env);
651
652 return rc;
653 }
t/t3404-rebase-interactive.sh
+16
@@ -237,6 +237,22 @@ test_expect_success 'retain authorship' '
237 git show HEAD | grep "^Author: Twerp Snog"
238 '
239
240 +test_expect_success 'retain authorship w/ conflicts' '
241 + git reset --hard twerp &&
242 + test_commit a conflict a conflict-a &&
243 + git reset --hard twerp &&
244 + GIT_AUTHOR_NAME=AttributeMe \
245 + test_commit b conflict b conflict-b &&
246 + set_fake_editor &&
247 + test_must_fail git rebase -i conflict-a &&
248 + echo resolved >conflict &&
249 + git add conflict &&
250 + git rebase --continue &&
251 + test $(git rev-parse conflict-a^0) = $(git rev-parse HEAD^) &&
252 + git show >out &&
253 + grep AttributeMe out
254 +'
255 +
256 test_expect_success 'squash' '
257 git reset --hard twerp &&
258 echo B > file7 &&