From 5d94d54564fb0dea1f3caf2f1dacb7701f4be25c Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Sat, 29 Dec 2018 17:03:59 +0100 Subject: sequencer: make the todo_list structure public This makes the structures todo_list and todo_item, and the functions todo_list_release() and parse_insn_buffer(), accessible outside of sequencer.c. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index 9d83f0f3e9..c6360bac66 100644 --- a/sequencer.h +++ b/sequencer.h @@ -73,6 +73,56 @@ enum missing_commit_check_level { int write_message(const void *buf, size_t len, const char *filename, int append_eol); +/* + * Note that ordering matters in this enum. Not only must it match the mapping + * of todo_command_info (in sequencer.c), it is also divided into several + * sections that matter. When adding new commands, make sure you add it in the + * right section. + */ +enum todo_command { + /* commands that handle commits */ + TODO_PICK = 0, + TODO_REVERT, + TODO_EDIT, + TODO_REWORD, + TODO_FIXUP, + TODO_SQUASH, + /* commands that do something else than handling a single commit */ + TODO_EXEC, + TODO_BREAK, + TODO_LABEL, + TODO_RESET, + TODO_MERGE, + /* commands that do nothing but are counted for reporting progress */ + TODO_NOOP, + TODO_DROP, + /* comments (not counted for reporting progress) */ + TODO_COMMENT +}; + +struct todo_item { + enum todo_command command; + struct commit *commit; + unsigned int flags; + const char *arg; + int arg_len; + size_t offset_in_buf; +}; + +struct todo_list { + struct strbuf buf; + struct todo_item *items; + int nr, alloc, current; + int done_nr, total_nr; + struct stat_data stat; +}; + +#define TODO_LIST_INIT { STRBUF_INIT } + +int todo_list_parse_insn_buffer(struct repository *r, char *buf, + struct todo_list *todo_list); +void todo_list_release(struct todo_list *todo_list); + /* Call this to setup defaults before parsing command line options */ void sequencer_init_config(struct replay_opts *opts); int sequencer_pick_revisions(struct repository *repo, -- cgit v1.2.3 From 6ad656db9b2d2426a0a884b431e8adc9877101bc Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 29 Jan 2019 16:01:46 +0100 Subject: sequencer: remove the 'arg' field from todo_item The 'arg' field of todo_item used to store the address of the first byte of the parameter of a command in a todo list. It was associated with the length of the parameter (the 'arg_len' field). This replaces the 'arg' field by 'arg_offset'. This new field does not store the address of the parameter, but the position of the first character of the parameter in the buffer. todo_item_get_arg() is added to return the address of the parameter of an item. This will prevent todo_list_add_exec_commands() from having to do awful pointer arithmetics when growing the todo list buffer. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index c6360bac66..50d552429c 100644 --- a/sequencer.h +++ b/sequencer.h @@ -104,9 +104,9 @@ struct todo_item { enum todo_command command; struct commit *commit; unsigned int flags; - const char *arg; int arg_len; - size_t offset_in_buf; + /* The offset of the command and its argument in the strbuf */ + size_t offset_in_buf, arg_offset; }; struct todo_list { @@ -122,6 +122,8 @@ struct todo_list { int todo_list_parse_insn_buffer(struct repository *r, char *buf, struct todo_list *todo_list); void todo_list_release(struct todo_list *todo_list); +const char *todo_item_get_arg(struct todo_list *todo_list, + struct todo_item *item); /* Call this to setup defaults before parsing command line options */ void sequencer_init_config(struct replay_opts *opts); -- cgit v1.2.3 From cbef27d61cd6ae4f1ecae054eb9df06e898148d8 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 29 Jan 2019 16:01:47 +0100 Subject: sequencer: refactor transform_todos() to work on a todo_list This refactors transform_todos() to work on a todo_list. The function is renamed todo_list_transform(). As rebase -p still need to check the todo list from the disk, a new function is introduced, transform_todo_file(). It is still used by complete_action() and edit_todo_list() for now, but they will be replaced in a future commit. todo_list_transform() is not a static function, because it will be used by edit_todo_list() from rebase-interactive.c in a future commit. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index 50d552429c..2ddb20cbc1 100644 --- a/sequencer.h +++ b/sequencer.h @@ -121,6 +121,8 @@ struct todo_list { int todo_list_parse_insn_buffer(struct repository *r, char *buf, struct todo_list *todo_list); +void todo_list_transform(struct repository *r, struct todo_list *todo_list, + unsigned flags); void todo_list_release(struct todo_list *todo_list); const char *todo_item_get_arg(struct todo_list *todo_list, struct todo_item *item); @@ -148,7 +150,7 @@ int sequencer_make_script(struct repository *repo, FILE *out, unsigned flags); int sequencer_add_exec_commands(struct repository *r, const char *command); -int transform_todos(struct repository *r, unsigned flags); +int transform_todo_file(struct repository *r, unsigned flags); enum missing_commit_check_level get_missing_commit_check_level(void); int check_todo_list(struct repository *r); int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags, -- cgit v1.2.3 From 616d7740cfbe65533af8ff1dabcf4e56f6baad5a Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 29 Jan 2019 16:01:48 +0100 Subject: sequencer: introduce todo_list_write_to_file() This introduces a new function to recreate the text of a todo list from its commands and write it to a file. This will be useful as the next few commits will change the use of the buffer in struct todo_list so it will no longer be a mirror of the file on disk. This functionality already exists in todo_list_transform(), but this function was made to replace the buffer of a todo list, which is not what we want here. Thus, the part of todo_list_transform() that replaces the buffer is dropped, and the function is renamed todo_list_to_strbuf(). It is called by todo_list_write_to_file() to fill the buffer to write to the disk. todo_list_write_to_file() can also take care of appending the help text to the buffer before writing it to the disk, or to write only the first n items of the list. This feature will be used by skip_unnecessary_picks(), which has to write done commands in a file. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index 2ddb20cbc1..7278f9675b 100644 --- a/sequencer.h +++ b/sequencer.h @@ -121,8 +121,9 @@ struct todo_list { int todo_list_parse_insn_buffer(struct repository *r, char *buf, struct todo_list *todo_list); -void todo_list_transform(struct repository *r, struct todo_list *todo_list, - unsigned flags); +int todo_list_write_to_file(struct repository *r, struct todo_list *todo_list, + const char *file, const char *shortrevisions, + const char *shortonto, int num, unsigned flags); void todo_list_release(struct todo_list *todo_list); const char *todo_item_get_arg(struct todo_list *todo_list, struct todo_item *item); @@ -145,8 +146,10 @@ int sequencer_remove_state(struct replay_opts *opts); * commits should be rebased onto the new base, this flag needs to be passed. */ #define TODO_LIST_REBASE_COUSINS (1U << 4) -int sequencer_make_script(struct repository *repo, FILE *out, - int argc, const char **argv, +#define TODO_LIST_APPEND_TODO_HELP (1U << 5) + +int sequencer_make_script(struct repository *r, FILE *out, int argc, + const char **argv, unsigned flags); int sequencer_add_exec_commands(struct repository *r, const char *command); -- cgit v1.2.3 From 6ca89c6f399b86983c7e93a3c5b918cad8292b47 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 29 Jan 2019 16:01:49 +0100 Subject: sequencer: refactor check_todo_list() to work on a todo_list This refactors check_todo_list() to work on a todo_list to avoid redundant reads and writes to the disk. The function is renamed todo_list_check(). The parsing of the two todo lists is left to the caller. As rebase -p still need to check the todo list from the disk, a new function is introduced, check_todo_list_from_file(). It reads the file from the disk, parses it, pass the todo_list to todo_list_check(), and writes it back to the disk. As get_missing_commit_check_level() and the enum missing_commit_check_level are no longer needed inside of sequencer.c, they are moved to rebase-interactive.c, and made static again. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index 7278f9675b..217353e9f0 100644 --- a/sequencer.h +++ b/sequencer.h @@ -64,12 +64,6 @@ struct replay_opts { }; #define REPLAY_OPTS_INIT { .action = -1, .current_fixups = STRBUF_INIT } -enum missing_commit_check_level { - MISSING_COMMIT_CHECK_IGNORE = 0, - MISSING_COMMIT_CHECK_WARN, - MISSING_COMMIT_CHECK_ERROR -}; - int write_message(const void *buf, size_t len, const char *filename, int append_eol); @@ -154,8 +148,7 @@ int sequencer_make_script(struct repository *r, FILE *out, int argc, int sequencer_add_exec_commands(struct repository *r, const char *command); int transform_todo_file(struct repository *r, unsigned flags); -enum missing_commit_check_level get_missing_commit_check_level(void); -int check_todo_list(struct repository *r); +int check_todo_list_from_file(struct repository *r); int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags, const char *shortrevisions, const char *onto_name, const char *onto, const char *orig_head, const char *cmd, -- cgit v1.2.3 From 683153a438f1b6b8e1a289a71f36244bde67e38f Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Mar 2019 20:17:54 +0100 Subject: sequencer: refactor sequencer_add_exec_commands() to work on a todo_list This refactors sequencer_add_exec_commands() to work on a todo_list to avoid redundant reads and writes to the disk. Instead of inserting the `exec' commands between the other commands and re-parsing the buffer at the end, they are appended to the buffer once, and a new list of items is created. Items from the old list are copied across and new `exec' items are appended when necessary. This eliminates the need to reparse the buffer, but this also means we have to use todo_list_write_to_disk() to write the file. todo_list_add_exec_commands() and sequencer_add_exec_commands() are modified to take a string list instead of a string -- one item for each command. This makes it easier to insert a new command to the todo list for each command to execute. sequencer_add_exec_commands() still reads the todo list from the disk, as it is needed by rebase -p. complete_action() still uses sequencer_add_exec_commands() for now. This will be changed in a future commit. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index 217353e9f0..87d04a3b9b 100644 --- a/sequencer.h +++ b/sequencer.h @@ -146,12 +146,13 @@ int sequencer_make_script(struct repository *r, FILE *out, int argc, const char **argv, unsigned flags); -int sequencer_add_exec_commands(struct repository *r, const char *command); +int sequencer_add_exec_commands(struct repository *r, + struct string_list *commands); int transform_todo_file(struct repository *r, unsigned flags); int check_todo_list_from_file(struct repository *r); int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags, const char *shortrevisions, const char *onto_name, - const char *onto, const char *orig_head, const char *cmd, + const char *onto, const char *orig_head, struct string_list *commands, unsigned autosquash); int rearrange_squash(struct repository *r); -- cgit v1.2.3 From f2a04904be6584f1ec783ed5d3c425026bcf908f Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Mar 2019 20:17:55 +0100 Subject: sequencer: refactor rearrange_squash() to work on a todo_list This refactors rearrange_squash() to work on a todo_list to avoid redundant reads and writes. The function is renamed todo_list_rearrange_squash(). The old version created a new buffer, which was directly written to the disk. This new version creates a new item list by just copying items from the old item list, without creating a new buffer. This eliminates the need to reparse the todo list, but this also means its buffer cannot be directly written to the disk. As rebase -p still need to check the todo list from the disk, a new function is introduced, rearrange_squash_in_todo_file(). complete_action() still uses rearrange_squash_in_todo_file() for now. This will be changed in a future commit. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index 87d04a3b9b..add50f04f1 100644 --- a/sequencer.h +++ b/sequencer.h @@ -154,7 +154,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla const char *shortrevisions, const char *onto_name, const char *onto, const char *orig_head, struct string_list *commands, unsigned autosquash); -int rearrange_squash(struct repository *r); +int rearrange_squash_in_todo_file(struct repository *r); extern const char sign_off_header[]; -- cgit v1.2.3 From d358fc286d1da690fb4acea629457faa9010944a Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Mar 2019 20:17:56 +0100 Subject: sequencer: make sequencer_make_script() write its script to a strbuf This makes sequencer_make_script() write its script to a strbuf (ie. the buffer of a todo_list) instead of a FILE. This reduce the amount of read/write made by rebase interactive. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index add50f04f1..e25f5151d3 100644 --- a/sequencer.h +++ b/sequencer.h @@ -142,9 +142,8 @@ int sequencer_remove_state(struct replay_opts *opts); #define TODO_LIST_REBASE_COUSINS (1U << 4) #define TODO_LIST_APPEND_TODO_HELP (1U << 5) -int sequencer_make_script(struct repository *r, FILE *out, int argc, - const char **argv, - unsigned flags); +int sequencer_make_script(struct repository *r, struct strbuf *out, int argc, + const char **argv, unsigned flags); int sequencer_add_exec_commands(struct repository *r, struct string_list *commands); -- cgit v1.2.3 From 94bcad797966b6a3490bc6806d3ee3eed54da9d9 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Mar 2019 20:17:57 +0100 Subject: sequencer: change complete_action() to use the refactored functions complete_action() used functions that read the todo-list file, made some changes to it, and wrote it back to the disk. The previous commits were dedicated to separate the part that deals with the file from the actual logic of these functions. Now that this is done, we can call directly the "logic" functions to avoid useless file access. The parsing of the list has to be done by the caller. If the buffer of the todo list provided by the caller is empty, a `noop' command is directly added to the todo list, without touching the buffer. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index e25f5151d3..7029b39cd6 100644 --- a/sequencer.h +++ b/sequencer.h @@ -152,7 +152,7 @@ int check_todo_list_from_file(struct repository *r); int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags, const char *shortrevisions, const char *onto_name, const char *onto, const char *orig_head, struct string_list *commands, - unsigned autosquash); + unsigned autosquash, struct todo_list *todo_list); int rearrange_squash_in_todo_file(struct repository *r); extern const char sign_off_header[]; -- cgit v1.2.3 From 1ba204de6924b171024638bb5f3f405a0e0946d0 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Mar 2019 20:17:58 +0100 Subject: rebase--interactive: move sequencer_add_exec_commands() As sequencer_add_exec_commands() is only needed inside of rebase--interactive.c for `rebase -p', it is moved there from sequencer.c. The parameter r (repository) is dropped along the way. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index 7029b39cd6..0c4b7c80f8 100644 --- a/sequencer.h +++ b/sequencer.h @@ -145,9 +145,9 @@ int sequencer_remove_state(struct replay_opts *opts); int sequencer_make_script(struct repository *r, struct strbuf *out, int argc, const char **argv, unsigned flags); -int sequencer_add_exec_commands(struct repository *r, - struct string_list *commands); int transform_todo_file(struct repository *r, unsigned flags); +void todo_list_add_exec_commands(struct todo_list *todo_list, + struct string_list *commands); int check_todo_list_from_file(struct repository *r); int complete_action(struct repository *r, struct replay_opts *opts, unsigned flags, const char *shortrevisions, const char *onto_name, -- cgit v1.2.3 From 79d7e883bb69803daf4a6f44692cb8fc0eee5b24 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Mar 2019 20:17:59 +0100 Subject: rebase--interactive: move rearrange_squash_in_todo_file() As rearrange_squash_in_todo_file() is only needed inside of rebase--interactive.c for `rebase -p', it is moved there from sequencer.c. The parameter r (repository) is dropped along the way, and the error handling is slightly improved. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index 0c4b7c80f8..13c5676c24 100644 --- a/sequencer.h +++ b/sequencer.h @@ -153,7 +153,7 @@ int complete_action(struct repository *r, struct replay_opts *opts, unsigned fla const char *shortrevisions, const char *onto_name, const char *onto, const char *orig_head, struct string_list *commands, unsigned autosquash, struct todo_list *todo_list); -int rearrange_squash_in_todo_file(struct repository *r); +int todo_list_rearrange_squash(struct todo_list *todo_list); extern const char sign_off_header[]; -- cgit v1.2.3 From ddb81e50724002645d7ec7d9ffdb714d02a47759 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Mar 2019 20:18:01 +0100 Subject: rebase-interactive: use todo_list_write_to_file() in edit_todo_list() Just like complete_action(), edit_todo_list() used a function (transform_todo_file()) that read the todo list from the disk and wrote it back, resulting in useless disk accesses. This changes edit_todo_list() to call directly todo_list_write_to_file() instead. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index 13c5676c24..fb31a30d15 100644 --- a/sequencer.h +++ b/sequencer.h @@ -64,9 +64,6 @@ struct replay_opts { }; #define REPLAY_OPTS_INIT { .action = -1, .current_fixups = STRBUF_INIT } -int write_message(const void *buf, size_t len, const char *filename, - int append_eol); - /* * Note that ordering matters in this enum. Not only must it match the mapping * of todo_command_info (in sequencer.c), it is also divided into several -- cgit v1.2.3 From a930eb03a8299b5b29284dd9e3c253c38187167a Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Mar 2019 20:18:03 +0100 Subject: rebase-interactive: rewrite edit_todo_list() to handle the initial edit edit_todo_list() is changed to work on a todo_list, and to handle the initial edition of the todo list (ie. making a backup of the todo list). It does not check for dropped commits yet, as todo_list_check() does not take the commits that have already been processed by the rebase (ie. the todo list is edited in the middle of a rebase session). Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 1 + 1 file changed, 1 insertion(+) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index fb31a30d15..195891a267 100644 --- a/sequencer.h +++ b/sequencer.h @@ -10,6 +10,7 @@ struct repository; const char *git_path_commit_editmsg(void); const char *git_path_seq_dir(void); const char *rebase_path_todo(void); +const char *rebase_path_todo_backup(void); #define APPEND_SIGNOFF_DEDUP (1u << 0) -- cgit v1.2.3 From ed35d18841130fee0109cbe40b659275a3f78cc9 Mon Sep 17 00:00:00 2001 From: Alban Gruin Date: Tue, 5 Mar 2019 20:18:05 +0100 Subject: rebase--interactive: move transform_todo_file() As transform_todo_file() is only needed inside of rebase--interactive.c for `rebase -p', it is moved there from sequencer.c. The parameter r (repository) is dropped along the way. Signed-off-by: Alban Gruin Signed-off-by: Junio C Hamano --- sequencer.h | 1 - 1 file changed, 1 deletion(-) (limited to 'sequencer.h') diff --git a/sequencer.h b/sequencer.h index 195891a267..7cca49eff2 100644 --- a/sequencer.h +++ b/sequencer.h @@ -143,7 +143,6 @@ int sequencer_remove_state(struct replay_opts *opts); int sequencer_make_script(struct repository *r, struct strbuf *out, int argc, const char **argv, unsigned flags); -int transform_todo_file(struct repository *r, unsigned flags); void todo_list_add_exec_commands(struct todo_list *todo_list, struct string_list *commands); int check_todo_list_from_file(struct repository *r); -- cgit v1.2.3