summaryrefslogtreecommitdiff
path: root/sequencer.c
AgeCommit message (Collapse)AuthorFilesLines
2020-11-21Merge branch 'en/strmap'Libravatar Junio C Hamano1-2/+2
A specialization of hashmap that uses a string as key has been introduced. Hopefully it will see wider use over time. * en/strmap: shortlog: use strset from strmap.h Use new HASHMAP_INIT macro to simplify hashmap initialization strmap: take advantage of FLEXPTR_ALLOC_STR when relevant strmap: enable allocations to come from a mem_pool strmap: add a strset sub-type strmap: split create_entry() out of strmap_put() strmap: add functions facilitating use as a string->int map strmap: enable faster clearing and reusing of strmaps strmap: add more utility functions strmap: new utility functions hashmap: provide deallocation function names hashmap: introduce a new hashmap_partial_clear() hashmap: allow re-use after hashmap_free() hashmap: adjust spacing to fix argument alignment hashmap: add usage documentation explaining hashmap_free[_entries]()
2020-11-18Merge branch 'en/merge-ort-api-null-impl'Libravatar Junio C Hamano1-11/+61
Preparation for a new merge strategy. * en/merge-ort-api-null-impl: merge,rebase,revert: select ort or recursive by config or environment fast-rebase: demonstrate merge-ort's API via new test-tool command merge-ort-wrappers: new convience wrappers to mimic the old merge API merge-ort: barebones API of new merge strategy with empty implementation
2020-11-18Merge branch 'pw/rebase-i-orig-head'Libravatar Junio C Hamano1-9/+6
"git rebase -i" did not store ORIG_HEAD correctly. * pw/rebase-i-orig-head: rebase -i: simplify get_revision_ranges() rebase -i: use struct object_id when writing state rebase -i: use struct object_id rather than looking up commit rebase -i: stop overwriting ORIG_HEAD buffer
2020-11-11Merge branch 'jc/sequencer-stopped-sha-simplify'Libravatar Junio C Hamano1-1/+1
Recently the format of an internal state file "rebase -i" uses has been tightened up for consistency, which would hurt those who start "rebase -i" with old git and then continue with new git. Loosen the reader side a bit (which we may want to tighten again in a year or so). * jc/sequencer-stopped-sha-simplify: sequencer: tolerate abbreviated stopped-sha file
2020-11-09Merge branch 'jk/committer-date-is-author-date-fix-simplify'Libravatar Junio C Hamano1-26/+2
Code simplification. * jk/committer-date-is-author-date-fix-simplify: am, sequencer: stop parsing our own committer ident
2020-11-04rebase -i: use struct object_id when writing stateLibravatar Phillip Wood1-2/+3
Rather than passing a string around pass the struct object_id that the string was created from call oid_hex() when we write the file. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-04rebase -i: use struct object_id rather than looking up commitLibravatar Phillip Wood1-7/+3
We already have a struct object_id containing the oid that we want to set ORIG_HEAD to so use that rather than converting it to a string and then calling get_oid() on that string. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-02merge,rebase,revert: select ort or recursive by config or environmentLibravatar Elijah Newren1-11/+61
Allow the testsuite to run where it treats requests for "recursive" or the default merge algorithm via consulting the environment variable GIT_TEST_MERGE_ALGORITHM which is expected to either be "recursive" (the old traditional algorithm) or "ort" (the new algorithm). Also, allow folks to pick the new algorithm via config setting. It turns out builtin/merge.c already had a way to allow users to specify a different default merge algorithm: pull.twohead. Rather odd configuration name (especially to be in the 'pull' namespace rather than 'merge') but it's there. Add that same configuration to rebase, cherry-pick, and revert. This required updating the various callsites that called merge_trees() or merge_recursive() to conditionally call the new API, so this serves as another demonstration of what the new API looks and feels like. There are almost certainly some callsites that have not yet been modified to work with the new merge algorithm, but this represents the ones that I have been testing with thus far. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-02Merge branch 'en/sequencer-rollback-lock-cleanup'Libravatar Junio C Hamano1-1/+0
Code clean-up. * en/sequencer-rollback-lock-cleanup: sequencer: remove duplicate rollback_lock_file() call
2020-11-02Merge branch 'sc/sequencer-gpg-octopus'Libravatar Junio C Hamano1-1/+3
"git rebase --rebase-merges" did not correctly pass --gpg-sign command line option to underlying "git merge" when replaying a merge using non-default merge strategy or when replaying an octopus merge (because replaying a two-head merge with the default strategy was done in a separate codepath, the problem did not trigger for most users), which has been corrected. * sc/sequencer-gpg-octopus: t3435: add tests for rebase -r GPG signing sequencer: pass explicit --no-gpg-sign to merge sequencer: fix gpg option passed to merge subcommand
2020-11-02hashmap: provide deallocation function namesLibravatar Elijah Newren1-2/+2
hashmap_free(), hashmap_free_entries(), and hashmap_free_() have existed for a while, but aren't necessarily the clearest names, especially with hashmap_partial_clear() being added to the mix and lazy-initialization now being supported. Peff suggested we adopt the following names[1]: - hashmap_clear() - remove all entries and de-allocate any hashmap-specific data, but be ready for reuse - hashmap_clear_and_free() - ditto, but free the entries themselves - hashmap_partial_clear() - remove all entries but don't deallocate table - hashmap_partial_clear_and_free() - ditto, but free the entries This patch provides the new names and converts all existing callers over to the new naming scheme. [1] https://lore.kernel.org/git/20201030125059.GA3277724@coredump.intra.peff.net/ Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-26Merge branch 'jk/committer-date-is-author-date-fix'Libravatar Junio C Hamano1-1/+1
In 2.29, "--committer-date-is-author-date" option of "rebase" and "am" subcommands lost the e-mail address by mistake, which has been corrected. * jk/committer-date-is-author-date-fix: rebase: fix broken email with --committer-date-is-author-date am: fix broken email with --committer-date-is-author-date t3436: check --committer-date-is-author-date result more carefully
2020-10-26am, sequencer: stop parsing our own committer identLibravatar Jeff King1-26/+2
For the --committer-date-is-author-date option of git-am and git-rebase, we format the committer ident, then re-parse it to find the name and email, and then feed those back to fmt_ident(). We can simplify this by handling it all at the time of the fmt_ident() call. We pass in the appropriate getenv() results, and if they're not present, then our WANT_COMMITTER_IDENT flag tells fmt_ident() to fill in the appropriate value from the config. Which is exactly what git_committer_ident() was doing under the hood. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-23rebase: fix broken email with --committer-date-is-author-dateLibravatar Jeff King1-1/+1
Commit 7573cec52c (rebase -i: support --committer-date-is-author-date, 2020-08-17) copied the committer ident-parsing code from builtin/am.c. And in doing so, it copied a bug in which we always set the email to an empty string. We fixed the version in git-am in the previous commit; this commit fixes the copied code. Reported-by: VenomVendor <info@venomvendor.com> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-21sequencer: tolerate abbreviated stopped-sha fileLibravatar Jonathan Tan1-1/+1
In 0512eabd91 ("sequencer: stop abbreviating stopped-sha file", 2020-09-25), Git was taught both to write full object names to the stopped-sha file and to require full object names when reading. However, a user would experience a problem if they started an interactive rebase using an old version of Git and then continued with a current version of Git (for example, if the system version of Git was updated in the meantime). Teach Git to allow object names of any length when reading. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-21sequencer: remove duplicate rollback_lock_file() callLibravatar Elijah Newren1-1/+0
Commit 2b6ad0f4bc ("rebase --rebase-merges: add support for octopus merges", 2017-12-21) introduced a case where rollback_lock_file() was unconditionally called twice in a row with no intervening commands. Remove the duplicate. Signed-off-by: Elijah Newren <newren@gmail.com> Reviewed-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-18sequencer: pass explicit --no-gpg-sign to mergeLibravatar Samuel Čavoj1-0/+2
The merge subcommand launched for merges with non-default strategy would use its own default behaviour to decide how to sign commits, regardless of what opts->gpg_sign was set to. For example the --no-gpg-sign flag given to rebase explicitly would get ignored, if commit.gpgsign was set to true. Fix the issue and add a test case excercising this behaviour. Signed-off-by: Samuel Čavoj <samuel@cavoj.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-18sequencer: fix gpg option passed to merge subcommandLibravatar Samuel Čavoj1-1/+1
When performing a rebase with --rebase-merges using either a custom strategy specified with -s or an octopus merge, and at the same time having gpgsign enabled (either rebase -S or config commit.gpgsign), the operation would fail on making the merge commit. Instead of "-S%s" with the key id substituted, only the bare key id would get passed to the underlying merge command, which tried to interpret it as a ref. Fix the issue and add test cases as suggested by Johannes Schindelin and Junio C Hamano. Signed-off-by: Samuel Čavoj <samuel@cavoj.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-10-05Merge branch 'jk/unused'Libravatar Junio C Hamano1-6/+14
Code cleanup. * jk/unused: dir.c: drop unused "untracked" from treat_path_fast() sequencer: handle ignore_footer when parsing trailers test-advise: check argument count with argc instead of argv sparse-checkout: fill in some options boilerplate sequencer: drop repository argument from run_git_commit() push: drop unused repo argument to do_push() assert PARSE_OPT_NONEG in parse-options callbacks env--helper: write to opt->value in parseopt helper drop unused argc parameters convert: drop unused crlf_action from check_global_conv_flags_eol()
2020-10-04Merge branch 'jc/sequencer-stopped-sha-simplify'Libravatar Junio C Hamano1-5/+6
Code simplification. * jc/sequencer-stopped-sha-simplify: sequencer: stop abbreviating stopped-sha file
2020-09-30sequencer: handle ignore_footer when parsing trailersLibravatar Jeff King1-0/+9
The append_signoff() function takes an "ignore_footer" argument, which specifies a number of bytes at the end of the message buffer which should not be considered (they cannot contain trailers, and the trailer is spliced in before them). But to find the existing trailers, it calls into has_conforming_trailer(). That function takes an ignore_footer parameter, but since 967dfd4d56 (sequencer: use trailer's trailer layout, 2016-11-02) the parameter is completely ignored. The trailer interface we're using takes a single string, with no option to tell it to use part of the string. However, since we have a mutable strbuf, we can work around this by simply overwriting (and later restoring) the boundary with a NUL. I'm not sure if this can actually trigger a bug in practice. It's easy to get a non-zero ignore_footer by doing something like this: git commit -F - --cleanup=verbatim <<-EOF subject body Signed-off-by: me # this looks like a comment, but is actually in the # message! That makes the earlier s-o-b fake. EOF git commit --amend -s There git-commit calls ignore_non_trailer() to count up the "#" cruft, which becomes the ignore_footer header. But it works even without this patch! That's because the trailer code _also_ calls ignore_non_trailer() and skips the cruft, too. So it happens to work because the only callers with a non-zero ignore_footer are using the exact same function that the trailer parser uses internally. And that seems true for all of the current callers, but there's nothing guaranteeing it. We're better off only feeding the correct buffer to the trailer code in the first place. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-09-30sequencer: drop repository argument from run_git_commit()Libravatar Jeff King1-6/+5
When we switched to using an external git-commit call in b0a3186140 (sequencer: simplify root commit creation, 2019-08-19), this function didn't need to care about the repository object any more. Arguably we could be passing along the repository path to the external git-commit by using "--git-dir=r->path" here. But for the most part the sequencer code relies on sub-process finding the same repository we're already in (using the same environment variables or discovery process we did). But we don't have a convenient interface for doing so, and there's no indication that we need to. Let's just drop the unused parameter for now. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-09-25sequencer: stop abbreviating stopped-sha fileLibravatar Junio C Hamano1-5/+6
The object name written to this file is not exposed to end-users and the only reader of this file immediately expands it back to a full object name. Stop abbreviating while writing, and expect a full object name while reading, which simplifies the code a bit. Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-09-03Merge branch 'pw/rebase-i-more-options'Libravatar Junio C Hamano1-4/+126
"git rebase -i" learns a bit more options. * pw/rebase-i-more-options: t3436: do not run git-merge-recursive in dashed form rebase: add --reset-author-date rebase -i: support --ignore-date rebase -i: support --committer-date-is-author-date am: stop exporting GIT_COMMITTER_DATE rebase -i: add --ignore-whitespace flag
2020-08-31Merge branch 'hn/refs-pseudorefs'Libravatar Junio C Hamano1-22/+34
Accesses to two pseudorefs have been updated to properly use ref API. * hn/refs-pseudorefs: sequencer: treat REVERT_HEAD as a pseudo ref builtin/commit: suggest update-ref for pseudoref removal sequencer: treat CHERRY_PICK_HEAD as a pseudo ref refs: make refs_ref_exists public
2020-08-21sequencer: treat REVERT_HEAD as a pseudo refLibravatar Han-Wen Nienhuys1-7/+9
Signed-off-by: Han-Wen Nienhuys <hanwen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-08-21sequencer: treat CHERRY_PICK_HEAD as a pseudo refLibravatar Han-Wen Nienhuys1-16/+26
Check for existence and delete CHERRY_PICK_HEAD through ref functions. This will help cherry-pick work with alternate ref storage backends. Signed-off-by: Han-Wen Nienhuys <hanwen@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-08-19Merge branch 'ak/sequencer-fix-find-uniq-abbrev'Libravatar Junio C Hamano1-2/+3
Ring buffer with size 4 used for bin-hex translation resulted in a wrong object name in the sequencer's todo output, which has been corrected. * ak/sequencer-fix-find-uniq-abbrev: rebase -i: fix possibly wrong onto hash in todo
2020-08-19Merge branch 'en/sequencer-merge-labels'Libravatar Junio C Hamano1-1/+1
The commit labels used to explain each side of conflicted hunks placed by the sequencer machinery have been made more readable by humans. * en/sequencer-merge-labels: sequencer: avoid garbled merge machinery messages due to commit labels
2020-08-19rebase -i: support --ignore-dateLibravatar Phillip Wood1-12/+54
Rebase is implemented with two different backends - 'apply' and 'merge' each of which support a different set of options. In particular the apply backend supports a number of options implemented by 'git am' that are not implemented in the merge backend. This means that the available options are different depending on which backend is used which is confusing. This patch adds support for the --ignore-date option to the merge backend. This option uses the current time as the author date rather than reusing the original author date when rewriting commits. We take care to handle the combination of --ignore-date and --committer-date-is-author-date in the same way as the apply backend. Original-patch-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-08-17rebase -i: support --committer-date-is-author-dateLibravatar Phillip Wood1-3/+83
Rebase is implemented with two different backends - 'apply' and 'merge' each of which support a different set of options. In particular the apply backend supports a number of options implemented by 'git am' that are not implemented in the merge backend. This means that the available options are different depending on which backend is used which is confusing. This patch adds support for the --committer-date-is-author-date option to the merge backend. This option uses the author date of the commit that is being rewritten as the committer date when the new commit is created. Original-patch-by: Rohit Ashiwal <rohit.ashiwal265@gmail.com> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-08-17am: stop exporting GIT_COMMITTER_DATELibravatar Phillip Wood1-2/+2
The implementation of --committer-date-is-author-date exports GIT_COMMITTER_DATE to override the default committer date but does not reset GIT_COMMITTER_DATE in the environment after creating the commit so it is set in the environment of any hooks that get run. We're about to add the same functionality to the sequencer and do not want to have GIT_COMMITTER_DATE set when running hooks or exec commands so lets update commit_tree_extended() to take an explicit committer so we override the default date without setting GIT_COMMITTER_DATE in the environment. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-08-14sequencer: avoid garbled merge machinery messages due to commit labelsLibravatar Elijah Newren1-1/+1
sequencer's get_message() exists to provide good labels on conflict hunks; see commits d68565402a ("revert: clarify label on conflict hunks", 2010-03-20) bf975d379d ("cherry-pick, revert: add a label for ancestor", 2010-03-20) 043a4492b3 ("sequencer: factor code out of revert builtin", 2012-01-11). for background on this function. These labels are of the form <commitID>... <commit summary> or parent of <commitID>... <commit summary> These labels are then passed as branch names to the merge machinery. However, these labels, as formatted, often also serve to confuse. For example, if we have a rename involved in a content merge, then it results in text such as the following: <<<<<<<< HEAD:foo.c int j; ======== int counter; >>>>>>>> b01dface... Removed unnecessary stuff:bar.c Or in various conflict messages, it can make it very difficult to read: CONFLICT (rename/delete): foo.c deleted in b01dface... Removed unnecessary stuff and renamed in HEAD. Version HEAD of foo.c left in tree. CONFLICT (file location): dir1/foo.c added in b01dface... Removed unnecessary stuff inside a directory that was renamed in HEAD, suggesting it should perhaps be moved to dir2/foo.c. Make a minor change to remove the ellipses and add parentheses around the commit summary; this makes all three examples much easier to read: <<<<<<<< HEAD:foo.c int j; ======== int counter; >>>>>>>> b01dface (Removed unnecessary stuff):bar.c CONFLICT (rename/delete): foo.c deleted in b01dface (Removed unnecessary stuff) and renamed in HEAD. Version HEAD of foo.c left in tree. CONFLICT (file location): dir1/foo.c added in b01dface (Removed unnecessary stuff) inside a directory that was renamed in HEAD, suggesting it should perhaps be moved to dir2/foo.c. Signed-off-by: Elijah Newren <newren@gmail.com> Reviewed-by: Taylor Blau <me@ttaylorr.com> Acked-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-08-13rebase -i: fix possibly wrong onto hash in todoLibravatar Antti Keränen1-2/+3
'todo_list_write_to_file' may overwrite the static buffer, originating from 'find_unique_abbrev', that was used to store the short commit hash 'c' for "# Rebase a..b onto c" message in the todo editor. This is because the buffer that is returned from 'find_unique_abbrev' is valid until 4 more calls to `find_unique_abbrev` are made. As 'todo_list_write_to_file' calls 'find_unique_abbrev' for each rebased commit, the hash for 'c' is overwritten if there are 4 or more commits in the rebase. This behavior has been broken since its introduction. Fix by storing the short onto commit hash in a different buffer that remains valid, before calling 'todo_list_write_to_file'. Found-by: Jussi Keränen <jussike@gmail.com> Signed-off-by: Antti Keränen <detegr@rbx.email> Acked-by: Alban Gruin <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-07-30strvec: rename struct fieldsLibravatar Jeff King1-2/+2
The "argc" and "argv" names made sense when the struct was argv_array, but now they're just confusing. Let's rename them to "nr" (which we use for counts elsewhere) and "v" (which is rather terse, but reads well when combined with typical variable names like "args.v"). Note that we have to update all of the callers immediately. Playing tricks with the preprocessor is hard here, because we wouldn't want to rewrite unrelated tokens. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-07-28strvec: fix indentation in renamed callsLibravatar Jeff King1-4/+4
Code which split an argv_array call across multiple lines, like: argv_array_pushl(&args, "one argument", "another argument", "and more", NULL); was recently mechanically renamed to use strvec, which results in mis-matched indentation like: strvec_pushl(&args, "one argument", "another argument", "and more", NULL); Let's fix these up to align the arguments with the opening paren. I did this manually by sifting through the results of: git jump grep 'strvec_.*,$' and liberally applying my editor's auto-format. Most of the changes are of the form shown above, though I also normalized a few that had originally used a single-tab indentation (rather than our usual style of aligning with the open paren). I also rewrapped a couple of obvious cases (e.g., where previously too-long lines became short enough to fit on one), but I wasn't aggressive about it. In cases broken to three or more lines, the grouping of arguments is sometimes meaningful, and it wasn't worth my time or reviewer time to ponder each case individually. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-07-28strvec: convert remaining callers away from argv_array nameLibravatar Jeff King1-56/+56
We eventually want to drop the argv_array name and just use strvec consistently. There's no particular reason we have to do it all at once, or care about interactions between converted and unconverted bits. Because of our preprocessor compat layer, the names are interchangeable to the compiler (so even a definition and declaration using different names is OK). This patch converts all of the remaining files, as the resulting diff is reasonably sized. The conversion was done purely mechanically with: git ls-files '*.c' '*.h' | xargs perl -i -pe ' s/ARGV_ARRAY/STRVEC/g; s/argv_array/strvec/g; ' We'll deal with any indentation/style fallouts separately. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-07-28strvec: rename files from argv-array to strvecLibravatar Jeff King1-1/+1
This requires updating #include lines across the code-base, but that's all fairly mechanical, and was done with: git ls-files '*.c' '*.h' | xargs perl -i -pe 's/argv-array.h/strvec.h/' Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-05-14Merge branch 'js/rebase-autosquash-double-fixup-fix'Libravatar Junio C Hamano1-2/+5
"rebase -i" segfaulted when rearranging a sequence that has a fix-up that applies another fix-up (which may or may not be a fix-up of yet another step). * js/rebase-autosquash-double-fixup-fix: rebase --autosquash: fix a potential segfault
2020-05-09rebase --autosquash: fix a potential segfaultLibravatar Johannes Schindelin1-2/+5
When rearranging the todo list so that the fixups/squashes are reordered just after the commits they intend to fix up, we use two arrays to maintain that list: `next` and `tail`. The idea is that `next[i]`, if set to a non-negative value, contains the index of the item that should be rearranged just after the `i`th item. To avoid having to walk the entire `next` chain when appending another fixup/squash, we also store the end of the `next` chain in `tail[i]`. The logic we currently use to update these array items is based on the assumption that given a fixup/squash item at index `i`, we just found the index `i2` indicating the first item in that fixup chain. However, as reported by Paul Ganssle, that need not be true: the special form `fixup! <commit-hash>` is allowed to point to _another_ fixup commit in the middle of the fixup chain. Example: * 0192a To fixup * 02f12 fixup! To fixup * 03763 fixup! To fixup * 04ecb fixup! 02f12 Note how the fourth commit targets the second commit, which is already a fixup that targets the first commit. Previously, we would update `next` and `tail` under our assumption that every `fixup!` commit would find the start of the `fixup!`/`squash!` chain. This would lead to a segmentation fault because we would actually end up with a `next[i]` pointing to a `fixup!` but the corresponding `tail[i]` pointing nowhere, which would the lead to a segmentation fault. Let's fix this by _inserting_, rather than _appending_, the item. In other words, if we make a given line successor of another line, we do not simply forget any previously set successor of the latter, but make it a successor of the former. In the above example, at the point when we insert 04ecb just after 02f12, 03763 would already be recorded as a successor of 04ecb, and we now "squeeze in" 04ecb. To complete the idea, we now no longer assume that `next[i]` pointing to a line means that `last[i]` points to a line, too. Instead, we extend the concept of `last` to cover also partial `fixup!`/`squash!` chains, i.e. chains starting in the middle of a larger such chain. In the above example, after processing all lines, `last[0]` (corresponding to 0192a) would point to 03763, which indeed is the end of the overall `fixup!` chain, and `last[1]` (corresponding to 02f12) would point to 04ecb (which is the last `fixup!` targeting 02f12, but it has 03763 as successor, i.e. it is not the end of overall `fixup!` chain). Reported-by: Paul Ganssle <paul@ganssle.io> Helped-by: Jeff King <peff@peff.net> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-29Merge branch 'dl/merge-autostash'Libravatar Junio C Hamano1-47/+129
"git merge" learns the "--autostash" option. * dl/merge-autostash: (22 commits) pull: pass --autostash to merge t5520: make test_pull_autostash() accept expect_parent_num merge: teach --autostash option sequencer: implement apply_autostash_oid() sequencer: implement save_autostash() sequencer: unlink autostash in apply_autostash() sequencer: extract perform_autostash() from rebase rebase: generify create_autostash() rebase: extract create_autostash() reset: extract reset_head() from rebase rebase: generify reset_head() rebase: use apply_autostash() from sequencer.c sequencer: rename stash_sha1 to stash_oid sequencer: make apply_autostash() accept a path rebase: use read_oneliner() sequencer: make read_oneliner() extern sequencer: configurably warn on non-existent files sequencer: make read_oneliner() accept flags sequencer: make file exists check more efficient sequencer: stop leaking buf ...
2020-04-22Merge branch 'jt/rebase-allow-duplicate'Libravatar Junio C Hamano1-1/+2
Allow "git rebase" to reapply all local commits, even if the may be already in the upstream, without checking first. * jt/rebase-allow-duplicate: rebase --merge: optionally skip upstreamed commits
2020-04-22Merge branch 'en/rebase-no-keep-empty'Libravatar Junio C Hamano1-0/+11
"git rebase" (again) learns to honor "--no-keep-empty", which lets the user to discard commits that are empty from the beginning (as opposed to the ones that become empty because of rebasing). The interactive rebase also marks commits that are empty in the todo. * en/rebase-no-keep-empty: rebase: fix an incompatible-options error message rebase: reinstate --no-keep-empty rebase -i: mark commits that begin empty in todo editor
2020-04-22Merge branch 'dd/no-gpg-sign'Libravatar Junio C Hamano1-0/+2
"git rebase" learned the "--no-gpg-sign" option to countermand commit.gpgSign the user may have. * dd/no-gpg-sign: Documentation: document merge option --no-gpg-sign Documentation: merge commit-tree --[no-]gpg-sign Documentation: reword commit --no-gpg-sign Documentation: document am --no-gpg-sign cherry-pick/revert: honour --no-gpg-sign in all case rebase.c: honour --no-gpg-sign
2020-04-22Merge branch 'en/sequencer-reflog-action'Libravatar Junio C Hamano1-2/+8
"git rebase -i" did not leave the reflog entries correctly. * en/sequencer-reflog-action: sequencer: honor GIT_REFLOG_ACTION
2020-04-22Merge branch 'ag/rebase-merge-allow-ff-under-abbrev-command'Libravatar Junio C Hamano1-3/+6
"git rebase" with the merge backend did not work well when the rebase.abbreviateCommands configuration was set. * ag/rebase-merge-allow-ff-under-abbrev-command: t3432: test `--merge' with `rebase.abbreviateCommands = true', too sequencer: don't abbreviate a command if it doesn't have a short form
2020-04-11rebase --merge: optionally skip upstreamed commitsLibravatar Jonathan Tan1-1/+2
When rebasing against an upstream that has had many commits since the original branch was created: O -- O -- ... -- O -- O (upstream) \ -- O (my-dev-branch) it must read the contents of every novel upstream commit, in addition to the tip of the upstream and the merge base, because "git rebase" attempts to exclude commits that are duplicates of upstream ones. This can be a significant performance hit, especially in a partial clone, wherein a read of an object may end up being a fetch. Add a flag to "git rebase" to allow suppression of this feature. This flag only works when using the "merge" backend. This flag changes the behavior of sequencer_make_script(), called from do_interactive_rebase() <- run_rebase_interactive() <- run_specific_rebase() <- cmd_rebase(). With this flag, limit_list() (indirectly called from sequencer_make_script() through prepare_revision_walk()) will no longer call cherry_pick_list(), and thus PATCHSAME is no longer set. Refraining from setting PATCHSAME both means that the intermediate commits in upstream are no longer read (as shown by the test) and means that no PATCHSAME-caused skipping of commits is done by sequencer_make_script(), either directly or through make_script_with_merges(). Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-11rebase: reinstate --no-keep-emptyLibravatar Elijah Newren1-0/+6
Commit d48e5e21da ("rebase (interactive-backend): make --keep-empty the default", 2020-02-15) turned --keep-empty (for keeping commits which start empty) into the default. The logic underpinning that commit was: 1) 'git commit' errors out on the creation of empty commits without an override flag 2) Once someone determines that the override is worthwhile, it's annoying and/or harmful to required them to take extra steps in order to keep such commits around (and to repeat such steps with every rebase). While the logic on which the decision was made is sound, the result was a bit of an overcorrection. Instead of jumping to having --keep-empty being the default, it jumped to making --keep-empty the only available behavior. There was a simple workaround, though, which was thought to be good enough at the time. People could still drop commits which started empty the same way the could drop any commits: by firing up an interactive rebase and picking out the commits they didn't want from the list. However, there are cases where external tools might create enough empty commits that picking all of them out is painful. As such, having a flag to automatically remove start-empty commits may be beneficial. Provide users a way to drop commits which start empty using a flag that existed for years: --no-keep-empty. Interpret --keep-empty as countermanding any previous --no-keep-empty, but otherwise leaving --keep-empty as the default. This might lead to some slight weirdness since commands like git rebase --empty=drop --keep-empty git rebase --empty=keep --no-keep-empty look really weird despite making perfect sense (the first will drop commits which become empty, but keep commits that started empty; the second will keep commits which become empty, but drop commits which started empty). However, --no-keep-empty was named years ago and we are predominantly keeping it for backward compatibility; also we suspect it will only be used rarely since folks already have a simple way to drop commits they don't want with an interactive rebase. Reported-by: Bryan Turner <bturner@atlassian.com> Reported-by: Sami Boukortt <sami@boukortt.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-11rebase -i: mark commits that begin empty in todo editorLibravatar Elijah Newren1-0/+5
While many users who intentionally create empty commits do not want them thrown away by a rebase, there are third-party tools that generate empty commits that a user might not want. In the past, users have used rebase to get rid of such commits (a side-effect of the fact that the --apply backend is not currently capable of keeping them). While such users could fire up an interactive rebase and just remove the lines corresponding to empty commits, that might be difficult if the third-party tool generates many of them. Simplify this task for users by marking such lines with a suffix of " # empty" in the todo list. Suggested-by: Sami Boukortt <sami@boukortt.com> Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-04-10sequencer: implement apply_autostash_oid()Libravatar Denton Liu1-12/+26
Split apply_save_autostash() into apply_autostash_oid() and apply_save_autostash() where the former operates on an OID string and the latter reads the OID from a file before passing it into apply_save_autostash_oid(). This function is required for a future commmit which will rely on being able to apply an autostash whose OID is stored as a string. Signed-off-by: Denton Liu <liu.denton@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>