summaryrefslogtreecommitdiff
path: root/sequencer.h
AgeCommit message (Collapse)AuthorFilesLines
2018-05-30Merge branch 'js/sequencer-and-root-commits'Libravatar Junio C Hamano1-0/+4
The implementation of "git rebase -i --root" has been updated to use the sequencer machinery more. * js/sequencer-and-root-commits: rebase --rebase-merges: root commits can be cousins, too rebase --rebase-merges: a "merge" into a new root is a fast-forward sequencer: allow introducing new root commits rebase -i --root: let the sequencer handle even the initial part sequencer: learn about the special "fake root commit" handling sequencer: extract helper to update active_cache_tree
2018-05-23Merge branch 'js/rebase-recreate-merge'Libravatar Junio C Hamano1-0/+7
"git rebase" learned "--rebase-merges" to transplant the whole topology of commit graph elsewhere. * js/rebase-recreate-merge: rebase -i --rebase-merges: add a section to the man page rebase -i: introduce --rebase-merges=[no-]rebase-cousins pull: accept --rebase=merges to recreate the branch topology rebase --rebase-merges: avoid "empty merges" sequencer: handle post-rewrite for merge commands sequencer: make refs generated by the `label` command worktree-local rebase --rebase-merges: add test for --keep-empty rebase: introduce the --rebase-merges option rebase-helper --make-script: introduce a flag to rebase merges sequencer: fast-forward `merge` commands, if possible sequencer: introduce the `merge` command sequencer: introduce new commands to reset the revision git-rebase--interactive: clarify arguments sequencer: offer helpful advice when a command was rescheduled sequencer: refactor how original todo list lines are accessed sequencer: make rearrange_squash() a bit more obvious sequencer: avoid using errno clobbered by rollback_lock_file()
2018-05-06sequencer: learn about the special "fake root commit" handlingLibravatar Johannes Schindelin1-0/+4
When an interactive rebase wants to recreate a root commit, it - first creates a new, empty root commit, - checks it out, - converts the next `pick` command so that it amends the empty root commit Introduce support in the sequencer to handle such an empty root commit, by looking for the file <GIT_DIR>/rebase-merge/squash-onto; if it exists and contains a commit name, the sequencer will compare the HEAD to said root commit, and if identical, a new root commit will be created. While converting scripted code into proper, portable C, we also do away with the old "amend with an empty commit message, then cherry-pick without committing, then amend again" dance and replace it with code that uses the internal API properly to do exactly what we want: create a new root commit. To keep the implementation simple, we always spawn `git commit` to create new root commits. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-05-02rebase -i: Handle "combination of <n> commits" with GETTEXT_POISONLibravatar Johannes Schindelin1-1/+5
We previously relied on the localized versions of # This is a combination of <N> commits (which we write into the commit messages during fixup/squash chains) to contain <N> encoded in ASCII. This is not true in general, and certainly not true when compiled with GETTEXT_POISON=TryToKillMe, as demonstrated by the regression test we just introduced in t3418. So let's decouple keeping track of the count from the (localized) commit messages by introducing a new file called 'current-fixups' that keeps track of the current fixup/squash chain. This file contains a bit more than just the count (it contains a list of "fixup <commit>"/"squash <commit>" lines). This is done on purpose, as it will come in handy for a fix for the bug where `git rebase --skip` on a final fixup/squash will leave the commit message in limbo. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-26rebase -i: introduce --rebase-merges=[no-]rebase-cousinsLibravatar Johannes Schindelin1-0/+6
When running `git rebase --rebase-merges` non-interactively with an ancestor of HEAD as <upstream> (or leaving the todo list unmodified), we would ideally recreate the exact same commits as before the rebase. However, if there are commits in the commit range <upstream>.. that do not have <upstream> as direct ancestor (i.e. if `git log <upstream>..` would show commits that are omitted by `git log --ancestry-path <upstream>..`), this is currently not the case: we would turn them into commits that have <upstream> as direct ancestor. Let's illustrate that with a diagram: C / \ A - B - E - F \ / D Currently, after running `git rebase -i --rebase-merges B`, the new branch structure would be (pay particular attention to the commit `D`): --- C' -- / \ A - B ------ E' - F' \ / D' This is not really preserving the branch topology from before! The reason is that the commit `D` does not have `B` as ancestor, and therefore it gets rebased onto `B`. This is unintuitive behavior. Even worse, when recreating branch structure, most use cases would appear to want cousins *not* to be rebased onto the new base commit. For example, Git for Windows (the heaviest user of the Git garden shears, which served as the blueprint for --rebase-merges) frequently merges branches from `next` early, and these branches certainly do *not* want to be rebased. In the example above, the desired outcome would look like this: --- C' -- / \ A - B ------ E' - F' \ / -- D' -- Let's introduce the term "cousins" for such commits ("D" in the example), and let's not rebase them by default. For hypothetical use cases where cousins *do* need to be rebased, `git rebase --rebase=merges=rebase-cousins` needs to be used. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-26rebase-helper --make-script: introduce a flag to rebase mergesLibravatar Johannes Schindelin1-0/+1
The sequencer just learned new commands intended to recreate branch structure (similar in spirit to --preserve-merges, but with a substantially less-broken design). Let's allow the rebase--helper to generate todo lists making use of these commands, triggered by the new --rebase-merges option. For a commit topology like this (where the HEAD points to C): - A - B - C \ / D the generated todo list would look like this: # branch D pick 0123 A label branch-point pick 1234 D label D reset branch-point pick 2345 B merge -C 3456 D # C To keep things simple, we first only implement support for merge commits with exactly two parents, leaving support for octopus merges to a later patch series. All merge-rebasing todo lists start with a hard-coded `label onto` line. This makes it convenient to refer later on to the revision onto which everything is rebased, e.g. as starting point for branches other than the very first one. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-02-13Merge branch 'pw/sequencer-in-process-commit'Libravatar Junio C Hamano1-0/+25
The sequencer infrastructure is shared across "git cherry-pick", "git rebase -i", etc., and has always spawned "git commit" when it needs to create a commit. It has been taught to do so internally, when able, by reusing the codepath "git commit" itself uses, which gives performance boost for a few tens of percents in some sample scenarios. * pw/sequencer-in-process-commit: sequencer: run 'prepare-commit-msg' hook t7505: add tests for cherry-pick and rebase -i/-p t7505: style fixes sequencer: assign only free()able strings to gpg_sign sequencer: improve config handling t3512/t3513: remove KNOWN_FAILURE_CHERRY_PICK_SEES_EMPTY_COMMIT=1 sequencer: try to commit without forking 'git commit' sequencer: load commit related config sequencer: simplify adding Signed-off-by: trailer commit: move print_commit_summary() to libgit commit: move post-rewrite code to libgit Add a function to update HEAD after creating a commit commit: move empty message checks to libgit t3404: check intermediate squash messages
2018-01-24sequencer: run 'prepare-commit-msg' hookLibravatar Phillip Wood1-0/+1
Commit 356ee4659b ("sequencer: try to commit without forking 'git commit'", 2017-11-24) forgot to run the 'prepare-commit-msg' hook when creating the commit. Fix this by writing the commit message to a different file and running the hook. Using a different file means that if the commit is cancelled the original message file is unchanged. Also move the checks for an empty commit so the order matches 'git commit'. Reported-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> Helped-by: Ramsay Jones <ramsay@ramsayjones.plus.com> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-13sequencer: improve config handlingLibravatar Phillip Wood1-9/+10
The previous config handling relied on global variables, called git_default_config() even when the key had already been handled by git_sequencer_config() and did not initialize the diff configuration variables. Improve this by: i) loading the default values for message cleanup and gpg signing of commits into struct replay_opts; ii) restructuring the code to return immediately once a key is handled; and iii) calling git_diff_basic_config(). Note that unfortunately it is not possible to return early if the key is handled by git_gpg_config() as it does not indicate to the caller if the key has been handled or not. The sequencer should probably have been calling git_diff_basic_config() before as it creates a patch when there are conflicts. The shell version uses 'diff-tree' to create the patch so calling git_diff_basic_config() should match that. Although 'git commit' calls git_diff_ui_config() I don't think the output of print_commit_summary() is affected by anything that is loaded by that as print_commit_summary() always turns on rename detection so would ignore the value in the user's configuration anyway. The other values loaded by git_diff_ui_config() are about the formatting of patches so are not relevant to print_commit_summary(). Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-05rebase -i: learn to abbreviate command namesLibravatar Liam Beguin1-0/+1
`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 <johannes.schindelin@gmx.de> Signed-off-by: Liam Beguin <liambeguin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-05rebase -i -x: add exec commands via the rebase--helperLibravatar Liam Beguin1-0/+1
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 <liambeguin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-05rebase -i: update functions to use a flags parameterLibravatar Liam Beguin1-3/+5
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 <liambeguin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-12-05rebase -i: refactor transform_todo_idsLibravatar Liam Beguin1-1/+1
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 <liambeguin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-11-24sequencer: load commit related configLibravatar Phillip Wood1-0/+1
Load default values for message cleanup and gpg signing of commits in preparation for committing without forking 'git commit'. Note that we interpret commit.cleanup=scissors to mean COMMIT_MSG_CLEANUP_SPACE to be consistent with 'git commit' Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-11-24commit: move print_commit_summary() to libgitLibravatar Phillip Wood1-0/+5
Move print_commit_summary() from builtin/commit.c to sequencer.c so it can be shared with other commands. The function is modified by changing the last argument to a flag so callers can specify whether they want to show the author date in addition to specifying if this is an initial commit. If the sequencer dies in print_commit_summary() (which can only happen when cherry-picking or reverting) then neither the todo list nor the abort safety file are updated to reflect the commit that was just made. print_commit_summary() can die if: - The commit that was just created cannot be found or parsed. - HEAD cannot be resolved either because some other process is updating it (which is bad news in the middle of a cherry-pick) or because it is corrupt. - log_tree_commit() cannot read some objects. In all those cases dying will leave the sequencer in a sane state for aborting; 'git cherry-pick --abort' will rewind HEAD to the last successful commit before there was a problem with HEAD or the object database. If the user somehow fixes the problem and runs 'git cherry-pick --continue' then the sequencer will try and pick the same commit again which may or may not be what the user wants depending on what caused print_commit_summary() to die. If print_commit_summary() returned an error instead then update_abort_safety_file() would try to resolve HEAD which may or may not be successful. If it is successful then running 'git rebase --abort' would not rewind HEAD to the last successful commit which is not what we want. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-11-18commit: move post-rewrite code to libgitLibravatar Phillip Wood1-0/+2
Move run_rewrite_hook() from bulitin/commit.c to sequencer.c so it can be shared with other commands and add a new function commit_post_rewrite() based on the code in builtin/commit.c that encapsulates rewriting notes and running the post-rewrite hook. Once the sequencer learns how to create commits without forking 'git commit' these functions will be used when squashing commits. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-11-18Add a function to update HEAD after creating a commitLibravatar Phillip Wood1-0/+4
Add update_head_with_reflog() based on the code that updates HEAD after committing in builtin/commit.c that can be called by 'git commit' and other commands. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-11-11commit: move empty message checks to libgitLibravatar Phillip Wood1-0/+11
Move the functions that check for empty messages from bulitin/commit.c to sequencer.c so they can be shared with other commands. The functions are refactored to take an explicit cleanup mode and template filename passed by the caller. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-27rebase -i: rearrange fixup/squash lines using the rebase--helperLibravatar Johannes Schindelin1-0/+1
This operation has quadratic complexity, which is especially painful on Windows, where shell scripts are *already* slow (mainly due to the overhead of the POSIX emulation layer). Let's reimplement this with linear complexity (using a hash map to match the commits' subject lines) for the common case; Sadly, the fixup/squash feature's design neglected performance considerations, allowing arbitrary prefixes (read: `fixup! hell` will match the commit subject `hello world`), which means that we are stuck with quadratic performance in the worst case. The reimplemented logic also happens to fix a bug where commented-out lines (representing empty patches) were dropped by the previous code. While at it, clarify how the fixup/squash feature works in `git rebase -i`'s man page. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-27rebase -i: skip unnecessary picks using the rebase--helperLibravatar Johannes Schindelin1-0/+1
In particular on Windows, where shell scripts are even more expensive than on MacOSX or Linux, it makes sense to move a loop that forks Git at least once for every line in the todo list into a builtin. Note: The original code did not try to skip unnecessary picks of root commits but punts instead (probably --root was not considered common enough of a use case to bother optimizing). We do the same, for now. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-27rebase -i: check for missing commits in the rebase--helperLibravatar Johannes Schindelin1-0/+1
In particular on Windows, where shell scripts are even more expensive than on MacOSX or Linux, it makes sense to move a loop that forks Git at least once for every line in the todo list into a builtin. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-27rebase -i: also expand/collapse the SHA-1s via the rebase--helperLibravatar Johannes Schindelin1-0/+2
This is crucial to improve performance on Windows, as the speed is now mostly dominated by the SHA-1 transformation (because it spawns a new rev-parse process for *every* line, and spawning processes is pretty slow from Git for Windows' MSYS2 Bash). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-07-27rebase -i: generate the script via rebase--helperLibravatar Johannes Schindelin1-0/+3
The first step of an interactive rebase is to generate the so-called "todo script", to be stored in the state directory as "git-rebase-todo" and to be edited by the user. Originally, we adjusted the output of `git log <options>` using a simple sed script. Over the course of the years, the code became more complicated. We now use shell scripting to edit the output of `git log` conditionally, depending whether to keep "empty" commits (i.e. commits that do not change any files). On platforms where shell scripting is not native, this can be a serious drag. And it opens the door for incompatibilities between platforms when it comes to shell scripting or to Unix-y commands. Let's just re-implement the todo script generation in plain C, using the revision machinery directly. This is substantially faster, improving the speed relative to the shell script version of the interactive rebase from 2x to 3x on Windows. Note that the rearrange_squash() function in git-rebase--interactive relied on the fact that we set the "format" variable to the config setting rebase.instructionFormat. Relying on a side effect like this is no good, hence we explicitly perform that assignment (possibly again) in rearrange_squash(). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-09sequencer (rebase -i): learn about the 'verbose' modeLibravatar Johannes Schindelin1-0/+1
When calling `git rebase -i -v`, the user wants to see some statistics after the commits were rebased. Let's show some. The strbuf we use to perform that task will be used for other things in subsequent commits, hence it is declared and initialized in a wider scope than strictly needed here. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2017-01-09sequencer: support a new action: 'interactive rebase'Libravatar Johannes Schindelin1-1/+2
This patch introduces a new action for the sequencer. It really does not do a whole lot of its own right now, but lays the ground work for patches to come. The intention, of course, is to finally make the sequencer the work horse of the interactive rebase (the original idea behind the "sequencer" concept). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-10-21sequencer: get rid of the subcommand fieldLibravatar Johannes Schindelin1-9/+4
The subcommands are used exactly once, at the very beginning of sequencer_pick_revisions(), to determine what to do. This is an unnecessary level of indirection: we can simply call the correct function to begin with. So let's do that. While at it, ensure that the subcommands return an error code so that they do not have to die() all over the place (bad practice for library functions...). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-10-21sequencer: plug memory leaks for the option valuesLibravatar Johannes Schindelin1-3/+3
The sequencer is our attempt to lib-ify cherry-pick. Yet it behaves like a one-shot command when it reads its configuration: memory is allocated and released only when the command exits. This is kind of okay for git-cherry-pick, which *is* a one-shot command. All the work to make the sequencer its work horse was done to allow using the functionality as a library function, though, including proper clean-up after use. To remedy that, take custody of the option values in question, allocating and duping literal constants as needed and freeing them at end. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-10-17sequencer: use memoized sequencer directory pathLibravatar Johannes Schindelin1-4/+1
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-10-17sequencer: use static initializers for replay_optsLibravatar Johannes Schindelin1-0/+1
This change is not completely faithful: instead of initializing all fields to 0, we choose to initialize command and subcommand to -1 (instead of defaulting to REPLAY_REVERT and REPLAY_NONE, respectively). Practically, it makes no difference at all, but future-proofs the code to require explicit assignments for both fields. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-11-10Merge branch 'jc/conflict-hint' into cc/interpret-trailers-moreLibravatar Junio C Hamano1-0/+1
* jc/conflict-hint: merge & sequencer: turn "Conflicts:" hint into a comment builtin/commit.c: extract ignore_non_trailer() helper function merge & sequencer: unify codepaths that write "Conflicts:" hint builtin/merge.c: drop a parameter that is never used git-tag.txt: Add a missing hyphen to `-s`
2014-10-24merge & sequencer: unify codepaths that write "Conflicts:" hintLibravatar Junio C Hamano1-0/+1
Two identical loops in suggest_conflicts() in merge, and do_recursive_merge() in sequencer, can use a single helper function extracted from the latter that prepares the "Conflicts:" hint that is meant to remind the user the paths for which merge conflicts had to be resolved to write a better commit log message. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2014-01-27cherry-pick, revert: add the --gpg-sign optionLibravatar Nicolas Vigier1-0/+2
Signed-off-by: Nicolas Vigier <boklm@mars-attacks.org> Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2013-02-12sequencer.c: teach append_signoff how to detect duplicate s-o-bLibravatar Brandon Casey1-1/+3
Teach append_signoff how to detect a duplicate s-o-b in the commit footer. This is in preparation to unify the append_signoff implementations in log-tree.c and sequencer.c. Fixes test in t3511. Signed-off-by: Brandon Casey <bcasey@nvidia.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-09-18Merge branch 'jc/make-static'Libravatar Junio C Hamano1-3/+0
Turn many file-scope private symbols to static to reduce the global namespace contamination. * jc/make-static: sequencer.c: mark a private file-scope symbol as static ident.c: mark private file-scope symbols as static trace.c: mark a private file-scope symbol as static wt-status.c: mark a private file-scope symbol as static read-cache.c: mark a private file-scope symbol as static strbuf.c: mark a private file-scope symbol as static sha1-array.c: mark a private file-scope symbol as static symlinks.c: mark private file-scope symbols as static notes.c: mark a private file-scope symbol as static rerere.c: mark private file-scope symbols as static graph.c: mark private file-scope symbols as static diff.c: mark a private file-scope symbol as static commit.c: mark a file-scope private symbol as static builtin/notes.c: mark file-scope private symbols as static
2012-09-15sequencer.c: mark a private file-scope symbol as staticLibravatar Junio C Hamano1-3/+0
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-09-14cherry-pick: don't forget -s on failureLibravatar Miklos Vajna1-0/+4
In case 'git cherry-pick -s <commit>' failed, the user had to use 'git commit -s' (i.e. state the -s option again), which is easy to forget about. Instead, write the signed-off-by line early, so plain 'git commit' will have the same result. Also update 'git commit -s', so that in case there is already a relevant Signed-off-by line before the Conflicts: line, it won't add one more at the end of the message. If there is no such line, then add it before the the Conflicts: line. Signed-off-by: Miklos Vajna <vmiklos@suse.cz> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-08-06cherry-pick: add --allow-empty-message optionLibravatar Chris Webb1-0/+1
Scripts such as "git rebase -i" cannot currently cherry-pick commits which have an empty commit message, as git cherry-pick calls git commit without the --allow-empty-message option. Add an --allow-empty-message option to git cherry-pick which is passed through to git commit, so this behaviour can be overridden. Signed-off-by: Chris Webb <chris@arachsys.com> Reviewed-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-24git-cherry-pick: Add keep-redundant-commits optionLibravatar Neil Horman1-0/+1
The git-cherry-pick --allow-empty command by default only preserves empty commits that were originally empty, i.e only those commits for which <commit>^{tree} and <commit>^^{tree} are equal. By default commits which are non-empty, but were made empty by the inclusion of a prior commit on the current history are filtered out. This option allows us to override that behavior and include redundant commits as empty commits in the change history. Note that this patch changes the default behavior of git cherry-pick slightly. Prior to this patch all commits in a cherry-pick sequence were applied and git commit was run. The implication here was that, if a commit was redundant, and the commit did not trigger the fast forward logic, the git commit operation, and therefore the git cherry-pick operation would fail, displaying the cherry pick advice (i.e. run git commit --allow-empty). With this patch however, such redundant commits are automatically skipped without stopping, unless --keep-redundant-commits is specified, in which case, they are automatically applied as empty commits. Signed-off-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-04-11git-cherry-pick: add allow-empty optionLibravatar Neil Horman1-0/+1
git cherry-pick fails when picking a non-ff commit that is empty. The advice given with the failure is that a git-commit --allow-empty should be issued to explicitly add the empty commit during the cherry pick. This option allows a user to specify before hand that they want to keep the empty commit. This eliminates the need to issue both a cherry pick and a commit operation. Signed-off-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2012-01-11sequencer: factor code out of revert builtinLibravatar Ramkumar Ramachandra1-0/+37
Expose the cherry-picking machinery through a public sequencer_pick_revisions() (renamed from pick_revisions() in builtin/revert.c), so that cherry-picking and reverting are special cases of a general sequencer operation. The cherry-pick builtin is now a thin wrapper that does command-line argument parsing before calling into sequencer_pick_revisions(). In the future, we can write a new "foo" builtin that calls into the sequencer like: memset(&opts, 0, sizeof(opts)); opts.action = REPLAY_FOO; opts.revisions = xmalloc(sizeof(*opts.revs)); parse_args_populate_opts(argc, argv, &opts); init_revisions(opts.revs); sequencer_pick_revisions(&opts); This patch does not intend to make any functional changes. Check with: $ git blame -s -C HEAD^..HEAD -- sequencer.c | grep -C3 '^[^^]' Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-12-12revert: stop creating and removing sequencer-old directoryLibravatar Jonathan Nieder1-10/+2
Now that "git reset" no longer implicitly removes .git/sequencer that the operator may or may not have wanted to keep, the logic to write a backup copy of .git/sequencer and remove it when stale is not needed any more. Simplify the sequencer API and repository layout by dropping it. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-11-22revert: rename --reset option to --quitLibravatar Jonathan Nieder1-1/+1
The option to "git cherry-pick" and "git revert" to discard the sequencer state introduced by v1.7.8-rc0~141^2~6 (revert: Introduce --reset to remove sequencer state, 2011-08-04) has a confusing name. Change it now, while we still have the time. The new name for "cherry-pick, please get out of my way, since I've long forgotten about the sequence of commits I was cherry-picking when you wrote that old .git/sequencer directory" is --quit. Mnemonic: this is analagous to quiting a program the user is no longer using --- we just want to get out of the multiple-command cherry-pick procedure and not to reset HEAD or rewind any other old state. The "--reset" option is kept as a synonym to minimize the impact. We might consider dropping it for simplicity in a separate patch, though. Adjust documentation and tests to use the newly preferred name (--quit) instead of --reset. While at it, let's clarify the short descriptions of these operations in "-h" output. Before: --reset forget the current operation --continue continue the current operation After: --quit end revert or cherry-pick sequence --continue resume revert or cherry-pick sequence Noticed-by: Phil Hord <phil.hord@gmail.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-08-04revert: Introduce --reset to remove sequencer stateLibravatar Ramkumar Ramachandra1-0/+20
To explicitly remove the sequencer state for a fresh cherry-pick or revert invocation, introduce a new subcommand called "--reset" to remove the sequencer state. Take the opportunity to publicly expose the sequencer paths, and a generic function called "remove_sequencer_state" that various git programs can use to remove the sequencer state in a uniform manner; "git reset" uses it later in this series. Introducing this public API is also in line with our long-term goal of eventually factoring out functions from revert.c into a generic commit sequencer. Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>