From 8dccc7a6b2deb05783ea5d57b53548dab32d99ae Mon Sep 17 00:00:00 2001 From: Liam Beguin Date: Tue, 5 Dec 2017 12:52:30 -0500 Subject: rebase -i: refactor transform_todo_ids The transform_todo_ids function is a little hard to read. Lets try to make it easier by using more of the strbuf API. Also, since we'll soon be adding command abbreviations, let's rename the function so it's name reflects that change. Signed-off-by: Liam Beguin Signed-off-by: Junio C Hamano --- builtin/rebase--helper.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'builtin') diff --git a/builtin/rebase--helper.c b/builtin/rebase--helper.c index f8519363a3..8ad4779d16 100644 --- a/builtin/rebase--helper.c +++ b/builtin/rebase--helper.c @@ -55,9 +55,9 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) if (command == MAKE_SCRIPT && argc > 1) return !!sequencer_make_script(keep_empty, stdout, argc, argv); if (command == SHORTEN_SHA1S && argc == 1) - return !!transform_todo_ids(1); + return !!transform_todos(1); if (command == EXPAND_SHA1S && argc == 1) - return !!transform_todo_ids(0); + return !!transform_todos(0); if (command == CHECK_TODO_LIST && argc == 1) return !!check_todo_list(); if (command == SKIP_UNNECESSARY_PICKS && argc == 1) -- cgit v1.3-5-g9baa From d80fc29367a6cf92792db6e3d1b5ce2ae2d81de8 Mon Sep 17 00:00:00 2001 From: Liam Beguin Date: Tue, 5 Dec 2017 12:52:31 -0500 Subject: rebase -i: replace reference to sha1 with oid Since we are trying to abstract the hash function name elsewhere in the code base, lets use OID instead of SHA-1 in the rebase--helper too. Signed-off-by: Liam Beguin Signed-off-by: Junio C Hamano --- builtin/rebase--helper.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'builtin') diff --git a/builtin/rebase--helper.c b/builtin/rebase--helper.c index 8ad4779d16..c3b8e4d401 100644 --- a/builtin/rebase--helper.c +++ b/builtin/rebase--helper.c @@ -14,7 +14,7 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) struct replay_opts opts = REPLAY_OPTS_INIT; int keep_empty = 0; enum { - CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_SHA1S, EXPAND_SHA1S, + CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_OIDS, EXPAND_OIDS, CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH } command = 0; struct option options[] = { @@ -27,9 +27,9 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) OPT_CMDMODE(0, "make-script", &command, N_("make rebase script"), MAKE_SCRIPT), OPT_CMDMODE(0, "shorten-ids", &command, - N_("shorten SHA-1s in the todo list"), SHORTEN_SHA1S), + N_("shorten commit ids in the todo list"), SHORTEN_OIDS), OPT_CMDMODE(0, "expand-ids", &command, - N_("expand SHA-1s in the todo list"), EXPAND_SHA1S), + N_("expand commit ids in the todo list"), EXPAND_OIDS), OPT_CMDMODE(0, "check-todo-list", &command, N_("check the todo list"), CHECK_TODO_LIST), OPT_CMDMODE(0, "skip-unnecessary-picks", &command, @@ -54,9 +54,9 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) return !!sequencer_remove_state(&opts); if (command == MAKE_SCRIPT && argc > 1) return !!sequencer_make_script(keep_empty, stdout, argc, argv); - if (command == SHORTEN_SHA1S && argc == 1) + if (command == SHORTEN_OIDS && argc == 1) return !!transform_todos(1); - if (command == EXPAND_SHA1S && argc == 1) + if (command == EXPAND_OIDS && argc == 1) return !!transform_todos(0); if (command == CHECK_TODO_LIST && argc == 1) return !!check_todo_list(); -- cgit v1.3-5-g9baa From 313a48eaca58ecd170bef9e6a5a55001c7511f08 Mon Sep 17 00:00:00 2001 From: Liam Beguin Date: Tue, 5 Dec 2017 12:52:32 -0500 Subject: rebase -i: update functions to use a flags parameter Update functions used in the rebase--helper so that they take a generic 'flags' parameter instead of a growing list of options. Signed-off-by: Liam Beguin Signed-off-by: Junio C Hamano --- builtin/rebase--helper.c | 13 +++++++------ sequencer.c | 9 +++++---- sequencer.h | 8 +++++--- 3 files changed, 17 insertions(+), 13 deletions(-) (limited to 'builtin') diff --git a/builtin/rebase--helper.c b/builtin/rebase--helper.c index c3b8e4d401..1102ecb43b 100644 --- a/builtin/rebase--helper.c +++ b/builtin/rebase--helper.c @@ -12,7 +12,7 @@ static const char * const builtin_rebase_helper_usage[] = { int cmd_rebase__helper(int argc, const char **argv, const char *prefix) { struct replay_opts opts = REPLAY_OPTS_INIT; - int keep_empty = 0; + unsigned flags = 0, keep_empty = 0; enum { CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_OIDS, EXPAND_OIDS, CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH @@ -48,16 +48,17 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, NULL, options, builtin_rebase_helper_usage, PARSE_OPT_KEEP_ARGV0); + flags |= keep_empty ? TODO_LIST_KEEP_EMPTY : 0; + flags |= command == SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0; + if (command == CONTINUE && argc == 1) return !!sequencer_continue(&opts); if (command == ABORT && argc == 1) return !!sequencer_remove_state(&opts); if (command == MAKE_SCRIPT && argc > 1) - return !!sequencer_make_script(keep_empty, stdout, argc, argv); - if (command == SHORTEN_OIDS && argc == 1) - return !!transform_todos(1); - if (command == EXPAND_OIDS && argc == 1) - return !!transform_todos(0); + return !!sequencer_make_script(stdout, argc, argv, flags); + if ((command == SHORTEN_OIDS || command == EXPAND_OIDS) && argc == 1) + return !!transform_todos(flags); if (command == CHECK_TODO_LIST && argc == 1) return !!check_todo_list(); if (command == SKIP_UNNECESSARY_PICKS && argc == 1) diff --git a/sequencer.c b/sequencer.c index c9a661a8c4..8b0dd610c8 100644 --- a/sequencer.c +++ b/sequencer.c @@ -2444,14 +2444,15 @@ void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag) strbuf_release(&sob); } -int sequencer_make_script(int keep_empty, FILE *out, - int argc, const char **argv) +int sequencer_make_script(FILE *out, int argc, const char **argv, + unsigned flags) { char *format = NULL; struct pretty_print_context pp = {0}; struct strbuf buf = STRBUF_INIT; struct rev_info revs; struct commit *commit; + int keep_empty = flags & TODO_LIST_KEEP_EMPTY; init_revisions(&revs, NULL); revs.verbose_header = 1; @@ -2494,7 +2495,7 @@ int sequencer_make_script(int keep_empty, FILE *out, } -int transform_todos(int shorten_ids) +int transform_todos(unsigned flags) { const char *todo_file = rebase_path_todo(); struct todo_list todo_list = TODO_LIST_INIT; @@ -2522,7 +2523,7 @@ int transform_todos(int shorten_ids) /* add commit id */ if (item->commit) { - const char *oid = shorten_ids ? + const char *oid = flags & TODO_LIST_SHORTEN_IDS ? short_commit_name(item->commit) : oid_to_hex(&item->commit->object.oid); diff --git a/sequencer.h b/sequencer.h index 4f7f2c93f8..68284e9762 100644 --- a/sequencer.h +++ b/sequencer.h @@ -45,10 +45,12 @@ int sequencer_continue(struct replay_opts *opts); int sequencer_rollback(struct replay_opts *opts); int sequencer_remove_state(struct replay_opts *opts); -int sequencer_make_script(int keep_empty, FILE *out, - int argc, const char **argv); +#define TODO_LIST_KEEP_EMPTY (1U << 0) +#define TODO_LIST_SHORTEN_IDS (1U << 1) +int sequencer_make_script(FILE *out, int argc, const char **argv, + unsigned flags); -int transform_todos(int shorten_ids); +int transform_todos(unsigned flags); int check_todo_list(void); int skip_unnecessary_picks(void); int rearrange_squash(void); -- cgit v1.3-5-g9baa From 0cce4a2756eb2c66544615e5ccd74671afb33256 Mon Sep 17 00:00:00 2001 From: Liam Beguin Date: Tue, 5 Dec 2017 12:52:33 -0500 Subject: rebase -i -x: add exec commands via the rebase--helper Recent work on `git-rebase--interactive` aims to convert shell code to C. Even if this is most likely not a big performance enhancement, let's convert it too since a coming change to abbreviate command names requires it to be updated. Signed-off-by: Liam Beguin Signed-off-by: Junio C Hamano --- builtin/rebase--helper.c | 7 ++++++- git-rebase--interactive.sh | 23 +---------------------- sequencer.c | 39 +++++++++++++++++++++++++++++++++++++++ sequencer.h | 1 + 4 files changed, 47 insertions(+), 23 deletions(-) (limited to 'builtin') diff --git a/builtin/rebase--helper.c b/builtin/rebase--helper.c index 1102ecb43b..4229ea0dc1 100644 --- a/builtin/rebase--helper.c +++ b/builtin/rebase--helper.c @@ -15,7 +15,8 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) unsigned flags = 0, keep_empty = 0; enum { CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_OIDS, EXPAND_OIDS, - CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH + CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH, + ADD_EXEC } command = 0; struct option options[] = { OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")), @@ -36,6 +37,8 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) N_("skip unnecessary picks"), SKIP_UNNECESSARY_PICKS), OPT_CMDMODE(0, "rearrange-squash", &command, N_("rearrange fixup/squash lines"), REARRANGE_SQUASH), + OPT_CMDMODE(0, "add-exec-commands", &command, + N_("insert exec commands in todo list"), ADD_EXEC), OPT_END() }; @@ -65,5 +68,7 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) return !!skip_unnecessary_picks(); if (command == REARRANGE_SQUASH && argc == 1) return !!rearrange_squash(); + if (command == ADD_EXEC && argc == 2) + return !!sequencer_add_exec_commands(argv[1]); usage_with_options(builtin_rebase_helper_usage, options); } diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 437815669f..e3f5a0abf3 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -722,27 +722,6 @@ collapse_todo_ids() { git rebase--helper --shorten-ids } -# Add commands after a pick or after a squash/fixup series -# in the todo list. -add_exec_commands () { - { - first=t - while read -r insn rest - do - case $insn in - pick) - test -n "$first" || - printf "%s" "$cmd" - ;; - esac - printf "%s %s\n" "$insn" "$rest" - first= - done - printf "%s" "$cmd" - } <"$1" >"$1.new" && - mv "$1.new" "$1" -} - # Switch to the branch in $into and notify it in the reflog checkout_onto () { GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name" @@ -982,7 +961,7 @@ fi test -s "$todo" || echo noop >> "$todo" test -z "$autosquash" || git rebase--helper --rearrange-squash || exit -test -n "$cmd" && add_exec_commands "$todo" +test -n "$cmd" && git rebase--helper --add-exec-commands "$cmd" todocount=$(git stripspace --strip-comments <"$todo" | wc -l) todocount=${todocount##* } diff --git a/sequencer.c b/sequencer.c index 8b0dd610c8..892d242f69 100644 --- a/sequencer.c +++ b/sequencer.c @@ -2494,6 +2494,45 @@ int sequencer_make_script(FILE *out, int argc, const char **argv, return 0; } +/* + * Add commands after pick and (series of) squash/fixup commands + * in the todo list. + */ +int sequencer_add_exec_commands(const char *commands) +{ + const char *todo_file = rebase_path_todo(); + struct todo_list todo_list = TODO_LIST_INIT; + struct todo_item *item; + struct strbuf *buf = &todo_list.buf; + size_t offset = 0, commands_len = strlen(commands); + int i, first; + + if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0) + return error(_("could not read '%s'."), todo_file); + + if (parse_insn_buffer(todo_list.buf.buf, &todo_list)) { + todo_list_release(&todo_list); + return error(_("unusable todo list: '%s'"), todo_file); + } + + first = 1; + /* insert before every pick except the first one */ + for (item = todo_list.items, i = 0; i < todo_list.nr; i++, item++) { + if (item->command == TODO_PICK && !first) { + strbuf_insert(buf, item->offset_in_buf + offset, + commands, commands_len); + offset += commands_len; + } + first = 0; + } + + /* append final */ + strbuf_add(buf, commands, commands_len); + + i = write_message(buf->buf, buf->len, todo_file, 0); + todo_list_release(&todo_list); + return i; +} int transform_todos(unsigned flags) { diff --git a/sequencer.h b/sequencer.h index 68284e9762..212426c445 100644 --- a/sequencer.h +++ b/sequencer.h @@ -50,6 +50,7 @@ int sequencer_remove_state(struct replay_opts *opts); int sequencer_make_script(FILE *out, int argc, const char **argv, unsigned flags); +int sequencer_add_exec_commands(const char *command); int transform_todos(unsigned flags); int check_todo_list(void); int skip_unnecessary_picks(void); -- cgit v1.3-5-g9baa From d8ae6c84da52a210e84b3734bb93c575638236d3 Mon Sep 17 00:00:00 2001 From: Liam Beguin Date: Tue, 5 Dec 2017 12:52:34 -0500 Subject: rebase -i: learn to abbreviate command names `git rebase -i` already know how to interpret single-letter command names. Teach it to generate the todo list with these same abbreviated names. Based-on-patch-by: Johannes Schindelin Signed-off-by: Liam Beguin Signed-off-by: Junio C Hamano --- Documentation/rebase-config.txt | 20 ++++++++++++++++++++ builtin/rebase--helper.c | 3 +++ sequencer.c | 16 ++++++++++++++-- sequencer.h | 1 + 4 files changed, 38 insertions(+), 2 deletions(-) (limited to 'builtin') diff --git a/Documentation/rebase-config.txt b/Documentation/rebase-config.txt index 30ae08cb5a..42e1ba7575 100644 --- a/Documentation/rebase-config.txt +++ b/Documentation/rebase-config.txt @@ -30,3 +30,23 @@ rebase.instructionFormat:: A format string, as specified in linkgit:git-log[1], to be used for the todo list during an interactive rebase. The format will automatically have the long commit hash prepended to the format. + +rebase.abbreviateCommands:: + If set to true, `git rebase` will use abbreviated command names in the + todo list resulting in something like this: ++ +------------------------------------------- + p deadbee The oneline of the commit + p fa1afe1 The oneline of the next commit + ... +------------------------------------------- ++ +instead of: ++ +------------------------------------------- + pick deadbee The oneline of the commit + pick fa1afe1 The oneline of the next commit + ... +------------------------------------------- ++ +Defaults to false. diff --git a/builtin/rebase--helper.c b/builtin/rebase--helper.c index 4229ea0dc1..7daee544b7 100644 --- a/builtin/rebase--helper.c +++ b/builtin/rebase--helper.c @@ -13,6 +13,7 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) { struct replay_opts opts = REPLAY_OPTS_INIT; unsigned flags = 0, keep_empty = 0; + int abbreviate_commands = 0; enum { CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_OIDS, EXPAND_OIDS, CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH, @@ -43,6 +44,7 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) }; git_config(git_default_config, NULL); + git_config_get_bool("rebase.abbreviatecommands", &abbreviate_commands); opts.action = REPLAY_INTERACTIVE_REBASE; opts.allow_ff = 1; @@ -52,6 +54,7 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix) builtin_rebase_helper_usage, PARSE_OPT_KEEP_ARGV0); flags |= keep_empty ? TODO_LIST_KEEP_EMPTY : 0; + flags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0; flags |= command == SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0; if (command == CONTINUE && argc == 1) diff --git a/sequencer.c b/sequencer.c index 892d242f69..115085d39c 100644 --- a/sequencer.c +++ b/sequencer.c @@ -795,6 +795,13 @@ static const char *command_to_string(const enum todo_command command) die("Unknown command: %d", command); } +static const char command_to_char(const enum todo_command command) +{ + if (command < TODO_COMMENT && todo_command_info[command].c) + return todo_command_info[command].c; + return comment_line_char; +} + static int is_noop(const enum todo_command command) { return TODO_NOOP <= command; @@ -2453,6 +2460,7 @@ int sequencer_make_script(FILE *out, int argc, const char **argv, struct rev_info revs; struct commit *commit; int keep_empty = flags & TODO_LIST_KEEP_EMPTY; + const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick"; init_revisions(&revs, NULL); revs.verbose_header = 1; @@ -2485,7 +2493,8 @@ int sequencer_make_script(FILE *out, int argc, const char **argv, strbuf_reset(&buf); if (!keep_empty && is_original_commit_empty(commit)) strbuf_addf(&buf, "%c ", comment_line_char); - strbuf_addf(&buf, "pick %s ", oid_to_hex(&commit->object.oid)); + strbuf_addf(&buf, "%s %s ", insn, + oid_to_hex(&commit->object.oid)); pretty_print_commit(&pp, commit, &buf); strbuf_addch(&buf, '\n'); fputs(buf.buf, out); @@ -2558,7 +2567,10 @@ int transform_todos(unsigned flags) } /* add command to the buffer */ - strbuf_addstr(&buf, command_to_string(item->command)); + if (flags & TODO_LIST_ABBREVIATE_CMDS) + strbuf_addch(&buf, command_to_char(item->command)); + else + strbuf_addstr(&buf, command_to_string(item->command)); /* add commit id */ if (item->commit) { diff --git a/sequencer.h b/sequencer.h index 212426c445..81f6d7d393 100644 --- a/sequencer.h +++ b/sequencer.h @@ -47,6 +47,7 @@ int sequencer_remove_state(struct replay_opts *opts); #define TODO_LIST_KEEP_EMPTY (1U << 0) #define TODO_LIST_SHORTEN_IDS (1U << 1) +#define TODO_LIST_ABBREVIATE_CMDS (1U << 2) int sequencer_make_script(FILE *out, int argc, const char **argv, unsigned flags); -- cgit v1.3-5-g9baa