summaryrefslogtreecommitdiff
path: root/sequencer.h
AgeCommit message (Collapse)AuthorFilesLines
2020-03-25Merge branch 'pw/advise-rebase-skip'Libravatar Junio C Hamano1-1/+2
The mechanism to prevent "git commit" from making an empty commit or amending during an interrupted cherry-pick was broken during the rewrite of "git rebase" in C, which has been corrected. * pw/advise-rebase-skip: commit: give correct advice for empty commit during a rebase commit: encapsulate determine_whence() for sequencer commit: use enum value for multiple cherry-picks sequencer: write CHERRY_PICK_HEAD for reword and edit cherry-pick: check commit error messages cherry-pick: add test for `--skip` advice in `git commit` t3404: use test_cmp_rev
2020-03-02Merge branch 'en/rebase-backend'Libravatar Junio C Hamano1-1/+2
"git rebase" has learned to use the merge backend (i.e. the machinery that drives "rebase -i") by default, while allowing "--apply" option to use the "apply" backend (e.g. the moral equivalent of "format-patch piped to am"). The rebase.backend configuration variable can be set to customize. * en/rebase-backend: rebase: rename the two primary rebase backends rebase: change the default backend from "am" to "merge" rebase: make the backend configurable via config setting rebase tests: repeat some tests using the merge backend instead of am rebase tests: mark tests specific to the am-backend with --am rebase: drop '-i' from the reflog for interactive-based rebases git-prompt: change the prompt for interactive-based rebases rebase: add an --am option rebase: move incompatibility checks between backend options a bit earlier git-rebase.txt: add more details about behavioral differences of backends rebase: allow more types of rebases to fast-forward t3432: make these tests work with either am or merge backends rebase: fix handling of restrict_revision rebase: make sure to pass along the quiet flag to the sequencer rebase, sequencer: remove the broken GIT_QUIET handling t3406: simplify an already simple test rebase (interactive-backend): fix handling of commits that become empty rebase (interactive-backend): make --keep-empty the default t3404: directly test the behavior of interest git-rebase.txt: update description of --allow-empty-message
2020-02-16rebase (interactive-backend): fix handling of commits that become emptyLibravatar Elijah Newren1-0/+1
As established in the previous commit and commit b00bf1c9a8dd (git-rebase: make --allow-empty-message the default, 2018-06-27), the behavior for rebase with different backends in various edge or corner cases is often more happenstance than design. This commit addresses another such corner case: commits which "become empty". A careful reader may note that there are two types of commits which would become empty due to a rebase: * [clean cherry-pick] Commits which are clean cherry-picks of upstream commits, as determined by `git log --cherry-mark ...`. Re-applying these commits would result in an empty set of changes and a duplicative commit message; i.e. these are commits that have "already been applied" upstream. * [become empty] Commits which are not empty to start, are not clean cherry-picks of upstream commits, but which still become empty after being rebased. This happens e.g. when a commit has changes which are a strict subset of the changes in an upstream commit, or when the changes of a commit can be found spread across or among several upstream commits. Clearly, in both cases the changes in the commit in question are found upstream already, but the commit message may not be in the latter case. When cherry-mark can determine a commit is already upstream, then because of how cherry-mark works this means the upstream commit message was about the *exact* same set of changes. Thus, the commit messages can be assumed to be fully interchangeable (and are in fact likely to be completely identical). As such, the clean cherry-pick case represents a case when there is no information to be gained by keeping the extra commit around. All rebase types have always dropped these commits, and no one to my knowledge has ever requested that we do otherwise. For many of the become empty cases (and likely even most), we will also be able to drop the commit without loss of information -- but this isn't quite always the case. Since these commits represent cases that were not clean cherry-picks, there is no upstream commit message explaining the same set of changes. Projects with good commit message hygiene will likely have the explanation from our commit message contained within or spread among the relevant upstream commits, but not all projects run that way. As such, the commit message of the commit being rebased may have reasoning that suggests additional changes that should be made to adapt to the new base, or it may have information that someone wants to add as a note to another commit, or perhaps someone even wants to create an empty commit with the commit message as-is. Junio commented on the "become-empty" types of commits as follows[1]: WRT a change that ends up being empty (as opposed to a change that is empty from the beginning), I'd think that the current behaviour is desireable one. "am" based rebase is solely to transplant an existing history and want to stop much less than "interactive" one whose purpose is to polish a series before making it publishable, and asking for confirmation ("this has become empty--do you want to drop it?") is more appropriate from the workflow point of view. [1] https://lore.kernel.org/git/xmqqfu1fswdh.fsf@gitster-ct.c.googlers.com/ I would simply add that his arguments for "am"-based rebases actually apply to all non-explicitly-interactive rebases. Also, since we are stating that different cases should have different defaults, it may be worth providing a flag to allow users to select which behavior they want for these commits. Introduce a new command line flag for selecting the desired behavior: --empty={drop,keep,ask} with the definitions: drop: drop commits which become empty keep: keep commits which become empty ask: provide the user a chance to interact and pick what to do with commits which become empty on a case-by-case basis In line with Junio's suggestion, if the --empty flag is not specified, pick defaults as follows: explicitly interactive: ask otherwise: drop Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-02-16rebase (interactive-backend): make --keep-empty the defaultLibravatar Elijah Newren1-1/+1
Different rebase backends have different treatment for commits which start empty (i.e. have no changes relative to their parent), and the --keep-empty option was added at some point to allow adjusting behavior. The handling of commits which start empty is actually quite similar to commit b00bf1c9a8dd (git-rebase: make --allow-empty-message the default, 2018-06-27), which pointed out that the behavior for various backends is often more happenstance than design. The specific change made in that commit is actually quite relevant as well and much of the logic there directly applies here. It makes a lot of sense in 'git commit' to error out on the creation of empty commits, unless an override flag is provided. However, once someone determines that there is a rare case that merits using the manual override to create such a commit, it is somewhere between annoying and harmful to have to take extra steps to keep such intentional commits around. Granted, empty commits are quite rare, which is why handling of them doesn't get considered much and folks tend to defer to existing (accidental) behavior and assume there was a reason for it, leading them to just add flags (--keep-empty in this case) that allow them to override the bad defaults. Fix the interactive backend so that --keep-empty is the default, much like we did with --allow-empty-message. The am backend should also be fixed to have --keep-empty semantics for commits that start empty, but that is not included in this patch other than a testcase documenting the failure. Note that there was one test in t3421 which appears to have been written expecting --keep-empty to not be the default as correct behavior. This test was introduced in commit 00b8be5a4d38 ("add tests for rebasing of empty commits", 2013-06-06), which was part of a series focusing on rebase topology and which had an interesting original cover letter at https://lore.kernel.org/git/1347949878-12578-1-git-send-email-martinvonz@gmail.com/ which noted Your input especially appreciated on whether you agree with the intent of the test cases. and then went into a long example about how one of the many tests added had several questions about whether it was correct. As such, I believe most the tests in that series were about testing rebase topology with as many different flags as possible and were not trying to state in general how those flags should behave otherwise. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-02-14Merge branch 'ag/edit-todo-drop-check'Libravatar Junio C Hamano1-1/+1
Allow the rebase.missingCommitsCheck configuration to kick in when "rebase --edit-todo" and "rebase --continue" restarts the procedure. * ag/edit-todo-drop-check: rebase-interactive: warn if commit is dropped with `rebase --edit-todo' sequencer: move check_todo_list_from_file() to rebase-interactive.c
2020-02-14Merge branch 'ag/rebase-avoid-unneeded-checkout'Libravatar Junio C Hamano1-3/+0
"git rebase -i" (and friends) used to unnecessarily check out the tip of the branch to be rebased, which has been corrected. * ag/rebase-avoid-unneeded-checkout: rebase -i: stop checking out the tip of the branch to rebase
2020-01-28rebase-interactive: warn if commit is dropped with `rebase --edit-todo'Libravatar Alban Gruin1-0/+1
When set to "warn" or "error", `rebase.missingCommitsCheck' would make `rebase -i' warn if the user removed commits from the todo list to prevent mistakes. Unfortunately, `rebase --edit-todo' and `rebase --continue' don't take it into account. This adds the ability for `rebase --edit-todo' and `rebase --continue' to check if commits were dropped by the user. As both edit_todo_list() and complete_action() parse the todo list and check for dropped commits, the code doing so in the latter is removed to reduce duplication. `edit_todo_list_advice' is removed from sequencer.c as it is no longer used there. This changes when a backup of the todo list is made. Until now, it was saved only once, before the initial edit. Now, it is also made if the original todo list has no errors or no dropped commits. Thus, the backup should be error-free. Without this, sequencer_continue() (`rebase --continue') could only compare the current todo list against the original, unedited list. Before this change, this file was only used by edit_todo_list() and `rebase -p' to create the backup before the initial edit, and check_todo_list_from_file(), only used by `rebase -p' to check for dropped commits after its own initial edit. If the edited list has an error, a file, `dropped', is created to report the issue. Otherwise, it is deleted. Usually, the edited list is compared against the list before editing, but if this file exists, it will be compared to the backup. Also, if the file exists, sequencer_continue() checks the list for dropped commits. If the check was performed every time, it would fail when resuming a rebase after resolving a conflict, as the backup will contain commits that were picked, but they will not be in the new list. It's safe to ignore this check if `dropped' does not exist, because that means that no errors were found at the last edition, so any missing commits here have already been picked. Five tests are added to t3404. The tests for `rebase.missingCommitsCheck = warn' and `rebase.missingCommitsCheck = error' have a similar structure. First, we start a rebase with an incorrect command on the first line. Then, we edit the todo list, removing the first and the last lines. This demonstrates that `--edit-todo' notices dropped commits, but not when the command is incorrect. Then, we restore the original todo list, and edit it to remove the last line. This demonstrates that if we add a commit after the initial edit, then remove it, `--edit-todo' will notice that it has been dropped. Then, the actual rebase takes place. In the third test, it is also checked that `--continue' will refuse to resume the rebase if commits were dropped. The fourth test checks that no errors are raised when resuming a rebase after resolving a conflict, the fifth checks that no errors are raised when editing the todo list after pausing the rebase. Signed-off-by: Alban Gruin <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-01-28sequencer: move check_todo_list_from_file() to rebase-interactive.cLibravatar Alban Gruin1-1/+0
The message contained in `edit_todo_list_advice' (sequencer.c) is printed after the initial edit of the todo list if it can't be parsed or if commits were dropped. This is done either in complete_action() for `rebase -i', or in check_todo_list_from_file() for `rebase -p'. Since we want to add this check when editing the list, we also want to use this message from edit_todo_list() (rebase-interactive.c). To this end, check_todo_list_from_file() is moved to rebase-interactive.c, and `edit_todo_list_advice' is copied there. In the next commit, complete_action() will stop using it, and `edit_todo_list_advice' will be removed from sequencer.c. Signed-off-by: Alban Gruin <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-01-24rebase -i: stop checking out the tip of the branch to rebaseLibravatar Alban Gruin1-3/+0
One of the first things done when using a sequencer-based rebase (ie. `rebase -i', `rebase -r', or `rebase -m') is to make a todo list. This requires knowledge of the commit range to rebase. To get the oid of the last commit of the range, the tip of the branch to rebase is checked out with prepare_branch_to_be_rebased(), then the oid of the head is read. After this, the tip of the branch is not even modified. The `am' backend, on the other hand, does not check out the branch. On big repositories, it's a performance penalty: with `rebase -i', the user may have to wait before editing the todo list while git is extracting the branch silently, and "quiet" rebases will be slower than `am'. Since we already have the oid of the tip of the branch in `opts->orig_head', it's useless to switch to this commit. This removes the call to prepare_branch_to_be_rebased() in do_interactive_rebase(), and adds a `orig_head' parameter to get_revision_ranges(). prepare_branch_to_be_rebased() is removed as it is no longer used. This introduces a visible change: as we do not switch on the tip of the branch to rebase, no reflog entry is created at the beginning of the rebase for it. Unscientific performance measurements, performed on linux.git, are as follow: Before this patch: $ time git rebase -m --onto v4.18 463fa44eec2fef50~ 463fa44eec2fef50 real 0m8,940s user 0m6,830s sys 0m2,121s After this patch: $ time git rebase -m --onto v4.18 463fa44eec2fef50~ 463fa44eec2fef50 real 0m1,834s user 0m0,916s sys 0m0,206s Reported-by: SZEDER Gábor <szeder.dev@gmail.com> Signed-off-by: Alban Gruin <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-01-12Revert "Merge branch 'ra/rebase-i-more-options'"Libravatar Junio C Hamano1-2/+0
This reverts commit 5d9324e0f4210bb7d52bcb79efe3935703083f72, reversing changes made to c58ae96fc4bb11916b62a96940bb70bb85ea5992. The topic turns out to be too buggy for real use. cf. <f2fe7437-8a48-3315-4d3f-8d51fe4bb8f1@gmail.com>
2019-12-10Merge branch 'ra/rebase-i-more-options'Libravatar Junio C Hamano1-0/+2
"git rebase -i" learned a few options that are known by "git rebase" proper. * ra/rebase-i-more-options: rebase -i: finishing touches to --reset-author-date rebase: add --reset-author-date rebase -i: support --ignore-date sequencer: rename amend_author to author_to_rename rebase -i: support --committer-date-is-author-date sequencer: allow callers of read_author_script() to ignore fields rebase -i: add --ignore-whitespace flag
2019-12-06commit: encapsulate determine_whence() for sequencerLibravatar Phillip Wood1-1/+2
Working out which command wants to create a commit requires detailed knowledge of the sequencer internals and that knowledge is going to increase in subsequent commits. With that in mind lets encapsulate that knowledge in sequencer.c rather than spreading it into builtin/commit.c. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-11-10Merge branch 'pw/post-commit-from-sequencer'Libravatar Junio C Hamano1-2/+1
"rebase -i" ceased to run post-commit hook by mistake in an earlier update, which has been corrected. * pw/post-commit-from-sequencer: sequencer: run post-commit hook move run_commit_hook() to libgit and use it there sequencer.h fix placement of #endif t3404: remove uneeded calls to set_fake_editor t3404: set $EDITOR in subshell t3404: remove unnecessary subshell
2019-11-02rebase -i: support --ignore-dateLibravatar Rohit Ashiwal1-0/+1
rebase am already has this flag to "lie" about the author date by changing it to the committer (current) date. Let's add the same for interactive machinery. Signed-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-11-02rebase -i: support --committer-date-is-author-dateLibravatar Rohit Ashiwal1-0/+1
rebase am already has this flag to "lie" about the committer date by changing it to the author date. Let's add the same for interactive machinery. Signed-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-10-16sequencer.h fix placement of #endifLibravatar Phillip Wood1-2/+1
Commit 65850686cf ("rebase -i: rewrite write_basic_state() in C", 2018-08-28) accidentially added new function declarations after the #endif at the end of the include guard. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-09-18Merge branch 'js/rebase-r-strategy'Libravatar Junio C Hamano1-0/+6
"git rebase --rebase-merges" learned to drive different merge strategies and pass strategy specific options to them. * js/rebase-r-strategy: t3427: accelerate this test by using fast-export and fast-import rebase -r: do not (re-)generate root commits with `--root` *and* `--onto` t3418: test `rebase -r` with merge strategies t/lib-rebase: prepare for testing `git rebase --rebase-merges` rebase -r: support merge strategies other than `recursive` t3427: fix another incorrect assumption t3427: accommodate for the `rebase --merge` backend having been replaced t3427: fix erroneous assumption t3427: condense the unnecessarily repetitive test cases into three t3427: move the `filter-branch` invocation into the `setup` case t3427: simplify the `setup` test case significantly t3427: add a clarifying comment rebase: fold git-rebase--common into the -p backend sequencer: the `am` and `rebase--interactive` scripts are gone .gitignore: there is no longer a built-in `git-rebase--interactive` t3400: stop referring to the scripted rebase Drop unused git-rebase--am.sh
2019-07-31rebase -r: do not (re-)generate root commits with `--root` *and* `--onto`Libravatar Johannes Schindelin1-0/+6
When rebasing a complete commit history onto a given commit, it is pretty obvious that the root commits should be rebased on top of said given commit. To test this, let's kill two birds with one stone and add a test case to t3427-rebase-subtree.sh that not only demonstrates that this works, but also that `git rebase -r` works with merge strategies now. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-07-19Merge branch 'ra/cherry-pick-revert-skip'Libravatar Junio C Hamano1-0/+1
"git cherry-pick/revert" learned a new "--skip" action. * ra/cherry-pick-revert-skip: cherry-pick/revert: advise using --skip cherry-pick/revert: add --skip option sequencer: use argv_array in reset_merge sequencer: rename reset_for_rollback to reset_merge sequencer: add advice for revert
2019-07-09Merge branch 'nd/switch-and-restore'Libravatar Junio C Hamano1-1/+1
Two new commands "git switch" and "git restore" are introduced to split "checking out a branch to work on advancing its history" and "checking out paths out of the index and/or a tree-ish to work on advancing the current history" out of the single "git checkout" command. * nd/switch-and-restore: (46 commits) completion: disable dwim on "git switch -d" switch: allow to switch in the middle of bisect t2027: use test_must_be_empty Declare both git-switch and git-restore experimental help: move git-diff and git-reset to different groups doc: promote "git restore" user-manual.txt: prefer 'merge --abort' over 'reset --hard' completion: support restore t: add tests for restore restore: support --patch restore: replace --force with --ignore-unmerged restore: default to --source=HEAD when only --staged is specified restore: reject invalid combinations with --staged restore: add --worktree and --staged checkout: factor out worktree checkout code restore: disable overlay mode by default restore: make pathspec mandatory restore: take tree-ish from --source option instead checkout: split part of it to new command 'restore' doc: promote "git switch" ...
2019-07-02cherry-pick/revert: add --skip optionLibravatar Rohit Ashiwal1-0/+1
git am or rebase have a --skip flag to skip the current commit if the user wishes to do so. During a cherry-pick or revert a user could likewise skip a commit, but needs to use 'git reset' (or in the case of conflicts 'git reset --merge'), followed by 'git (cherry-pick | revert) --continue' to skip the commit. This is more annoying and sometimes confusing on the users' part. Add a `--skip` option to make skipping commits easier for the user and to make the commands more consistent. In the next commit, we will change the advice messages hence finishing the process of teaching revert and cherry-pick "how to skip commits". Signed-off-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-05-13Merge branch 'pw/clean-sequencer-state-upon-final-commit'Libravatar Junio C Hamano1-0/+3
"git chery-pick" (and "revert" that shares the same runtime engine) that deals with multiple commits got confused when the final step gets stopped with a conflict and the user concluded the sequence with "git commit". Attempt to fix it by cleaning up the state files used by these commands in such a situation. * pw/clean-sequencer-state-upon-final-commit: fix cherry-pick/revert status after commit commit/reset: try to clean up sequencer state
2019-05-13Merge branch 'pw/rebase-i-internal'Libravatar Junio C Hamano1-3/+4
The internal implementation of "git rebase -i" has been updated to avoid forking a separate "rebase--interactive" process. * pw/rebase-i-internal: rebase -i: run without forking rebase--interactive rebase: use a common action enum rebase -i: use struct rebase_options in do_interactive_rebase() rebase -i: use struct rebase_options to parse args rebase -i: use struct object_id for squash_onto rebase -i: use struct commit when parsing options rebase -i: remove duplication rebase -i: combine rebase--interactive.c with rebase.c rebase: use OPT_RERERE_AUTOUPDATE() rebase: rename write_basic_state() rebase: don't translate trace strings sequencer: always discard index after checkout
2019-05-09Merge branch 'dl/merge-cleanup-scissors-fix'Libravatar Junio C Hamano1-1/+8
The list of conflicted paths shown in the editor while concluding a conflicted merge was shown above the scissors line when the clean-up mode is set to "scissors", even though it was commented out just like the list of updated paths and other information to help the user explain the merge better. * dl/merge-cleanup-scissors-fix: cherry-pick/revert: add scissors line on merge conflict sequencer.c: save and restore cleanup mode merge: add scissors line on merge conflict merge: cleanup messages like commit parse-options.h: extract common --cleanup option commit: extract cleanup_mode functions to sequencer t7502: clean up style t7604: clean up style t3507: clean up style t7600: clean up style
2019-05-09Merge branch 'pw/sequencer-cleanup-with-signoff-x-fix'Libravatar Junio C Hamano1-0/+1
"git cherry-pick" run with the "-x" or the "--signoff" option used to (and more importantly, ought to) clean up the commit log message with the --cleanup=space option by default, but this has been broken since late 2017. This has been fixed. * pw/sequencer-cleanup-with-signoff-x-fix: sequencer: fix cleanup with --signoff and -x
2019-04-25Merge branch 'ag/sequencer-reduce-rewriting-todo'Libravatar Junio C Hamano1-17/+64
The scripted version of "git rebase -i" wrote and rewrote the todo list many times during a single step of its operation, and the recent C-rewrite made a faithful conversion of the logic to C. The implementation has been updated to carry necessary information around in-core to avoid rewriting the same file over and over unnecessarily. * ag/sequencer-reduce-rewriting-todo: rebase--interactive: move transform_todo_file() sequencer: use edit_todo_list() in complete_action() rebase-interactive: rewrite edit_todo_list() to handle the initial edit rebase-interactive: append_todo_help() changes rebase-interactive: use todo_list_write_to_file() in edit_todo_list() sequencer: refactor skip_unnecessary_picks() to work on a todo_list rebase--interactive: move rearrange_squash_in_todo_file() rebase--interactive: move sequencer_add_exec_commands() sequencer: change complete_action() to use the refactored functions sequencer: make sequencer_make_script() write its script to a strbuf sequencer: refactor rearrange_squash() to work on a todo_list sequencer: refactor sequencer_add_exec_commands() to work on a todo_list sequencer: refactor check_todo_list() to work on a todo_list sequencer: introduce todo_list_write_to_file() sequencer: refactor transform_todos() to work on a todo_list sequencer: remove the 'arg' field from todo_item sequencer: make the todo_list structure public sequencer: changes in parse_insn_buffer()
2019-04-19rebase -i: use struct commit when parsing optionsLibravatar Phillip Wood1-2/+2
This is in preparation for using `struct rebase_options` when parsing options in cmd_rebase__interactive(). Using a string for onto, restrict_revision and upstream, was a hangover from the scripted version of rebase. The functions that use these variables are updated to take a `struct commit`. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-19sequencer: always discard index after checkoutLibravatar Phillip Wood1-1/+2
As the checkout runs in a separate process our index will be out of date so it should be discarded. The existing callers are not doing this consistently so do it here to avoid the callers having to worry about it. This fixes some test failures that happen if do_interactive_rebase() is called without forking rebase--interactive which we will implement shortly. Running git rebase -i master topic starting on master created empty todo lists because all the commits in topic were marked as cherry-picks. After topic was checked out in prepare_branch_to_be_rebased() the working tree contained the contents from topic but the index contained master and the cache entries were still valid. This meant that diff_populate_filespec() which loads the blobs when calculating patch-id's ended up reading the contents for master from the working tree which actually contained topic. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-19Merge branch 'ag/sequencer-reduce-rewriting-todo' into pw/rebase-i-internalLibravatar Junio C Hamano1-17/+64
* ag/sequencer-reduce-rewriting-todo: rebase--interactive: move transform_todo_file() sequencer: use edit_todo_list() in complete_action() rebase-interactive: rewrite edit_todo_list() to handle the initial edit rebase-interactive: append_todo_help() changes rebase-interactive: use todo_list_write_to_file() in edit_todo_list() sequencer: refactor skip_unnecessary_picks() to work on a todo_list rebase--interactive: move rearrange_squash_in_todo_file() rebase--interactive: move sequencer_add_exec_commands() sequencer: change complete_action() to use the refactored functions sequencer: make sequencer_make_script() write its script to a strbuf sequencer: refactor rearrange_squash() to work on a todo_list sequencer: refactor sequencer_add_exec_commands() to work on a todo_list sequencer: refactor check_todo_list() to work on a todo_list sequencer: introduce todo_list_write_to_file() sequencer: refactor transform_todos() to work on a todo_list sequencer: remove the 'arg' field from todo_item sequencer: make the todo_list structure public sequencer: changes in parse_insn_buffer()
2019-04-19cherry-pick/revert: add scissors line on merge conflictLibravatar Denton Liu1-1/+2
Fix a bug where the scissors line is placed after the Conflicts: section, in the case where a merge conflict occurs and commit.cleanup = scissors. Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Denton Liu <liu.denton@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-18commit: extract cleanup_mode functions to sequencerLibravatar Denton Liu1-0/+6
Signed-off-by: Denton Liu <liu.denton@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-18sequencer: fix cleanup with --signoff and -xLibravatar Phillip Wood1-0/+1
Before commit 356ee4659b ("sequencer: try to commit without forking 'git commit'", 2017-11-24) when --signoff or -x were given on the command line the commit message was cleaned up with --cleanup=space or commit.cleanup if it was set. Unfortunately this behavior was lost when I implemented committing without forking. Fix this and add some tests to catch future regressions. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-17fix cherry-pick/revert status after commitLibravatar Phillip Wood1-0/+2
If the user commits a conflict resolution using `git commit` in the middle of a sequence of cherry-picks/reverts then `git status` missed the fact that a cherry-pick/revert is still in progress. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-04-17commit/reset: try to clean up sequencer stateLibravatar Phillip Wood1-0/+1
When cherry-picking or reverting a sequence of commits and if the final pick/revert has conflicts and the user uses `git commit` to commit the conflict resolution and does not run `git cherry-pick --continue` then the sequencer state is left behind. This can cause problems later. In my case I cherry-picked a sequence of commits the last one of which I committed with `git commit` after resolving some conflicts, then a while later, on a different branch I aborted a revert which rewound my HEAD to the end of the cherry-pick sequence on the previous branch. Avoid this potential problem by removing the sequencer state if we're committing or resetting the final pick in a sequence. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07rebase--interactive: move transform_todo_file()Libravatar Alban Gruin1-1/+0
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 <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07rebase-interactive: rewrite edit_todo_list() to handle the initial editLibravatar Alban Gruin1-0/+1
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 <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07rebase-interactive: use todo_list_write_to_file() in edit_todo_list()Libravatar Alban Gruin1-3/+0
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 <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07rebase--interactive: move rearrange_squash_in_todo_file()Libravatar Alban Gruin1-1/+1
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 <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07rebase--interactive: move sequencer_add_exec_commands()Libravatar Alban Gruin1-2/+2
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 <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07sequencer: change complete_action() to use the refactored functionsLibravatar Alban Gruin1-1/+1
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 <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07sequencer: make sequencer_make_script() write its script to a strbufLibravatar Alban Gruin1-3/+2
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 <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07sequencer: refactor rearrange_squash() to work on a todo_listLibravatar Alban Gruin1-1/+1
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 <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-03-07sequencer: refactor sequencer_add_exec_commands() to work on a todo_listLibravatar Alban Gruin1-2/+3
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 <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-02-13Merge branch 'rj/sequencer-sign-off-header-static'Libravatar Junio C Hamano1-2/+0
Code clean-up. * rj/sequencer-sign-off-header-static: sequencer: make sign_off_header a file local symbol
2019-02-11sequencer: make sign_off_header a file local symbolLibravatar Ramsay Jones1-2/+0
Commit d0aaa46fd3 ("commit: move empty message checks to libgit", 2017-11-10) removes the last use of 'sign_off_header' outside of the "sequencer.c" source file. Remove the extern declaration from the header file and mark the definition of the symbol with the static keyword. Signed-off-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-02-06Merge branch 'nd/the-index-final'Libravatar Junio C Hamano1-1/+2
The assumption to work on the single "in-core index" instance has been reduced from the library-ish part of the codebase. * nd/the-index-final: cache.h: flip NO_THE_INDEX_COMPATIBILITY_MACROS switch read-cache.c: remove the_* from index_has_changes() merge-recursive.c: remove implicit dependency on the_repository merge-recursive.c: remove implicit dependency on the_index sha1-name.c: remove implicit dependency on the_index read-cache.c: replace update_index_if_able with repo_& read-cache.c: kill read_index() checkout: avoid the_index when possible repository.c: replace hold_locked_index() with repo_hold_locked_index() notes-utils.c: remove the_repository references grep: use grep_opt->repo instead of explict repo argument
2019-02-06Merge branch 'en/rebase-merge-on-sequencer'Libravatar Junio C Hamano1-0/+1
"git rebase --merge" as been reimplemented by reusing the internal machinery used for "git rebase -i". * en/rebase-merge-on-sequencer: rebase: implement --merge via the interactive machinery rebase: define linearization ordering and enforce it git-legacy-rebase: simplify unnecessary triply-nested if git-rebase, sequencer: extend --quiet option for the interactive machinery am, rebase--merge: do not overlook --skip'ed commits with post-rewrite t5407: add a test demonstrating how interactive handles --skip differently rebase: fix incompatible options error message rebase: make builtin and legacy script error messages the same
2019-01-29Merge branch 'js/rebase-i-redo-exec'Libravatar Junio C Hamano1-0/+1
"git rebase -i" learned to re-execute a command given with 'exec' to run after it failed the last time. * js/rebase-i-redo-exec: rebase: introduce a shortcut for --reschedule-failed-exec rebase: add a config option to default to --reschedule-failed-exec rebase: introduce --reschedule-failed-exec
2019-01-29sequencer: refactor check_todo_list() to work on a todo_listLibravatar Alban Gruin1-8/+1
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 <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-01-29sequencer: introduce todo_list_write_to_file()Libravatar Alban Gruin1-4/+7
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 <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>