summaryrefslogtreecommitdiff
path: root/sequencer.c
AgeCommit message (Collapse)Author
2024-04-05Merge branch 'jk/core-comment-string'Junio C Hamano
core.commentChar used to be limited to a single byte, but has been updated to allow an arbitrary multi-byte sequence. * jk/core-comment-string: config: add core.commentString config: allow multi-byte core.commentChar environment: drop comment_line_char compatibility macro wt-status: drop custom comment-char stringification sequencer: handle multi-byte comment characters when writing todo list find multi-byte comment chars in unterminated buffers find multi-byte comment chars in NUL-terminated strings prefer comment_line_str to comment_line_char for printing strbuf: accept a comment string for strbuf_add_commented_lines() strbuf: accept a comment string for strbuf_commented_addf() strbuf: accept a comment string for strbuf_stripspace() environment: store comment_line_char as a string strbuf: avoid shadowing global comment_line_char name commit: refactor base-case of adjust_comment_line_char() strbuf: avoid static variables in strbuf_add_commented_lines() strbuf: simplify comment-handling in add_lines() helper config: forbid newline as core.commentChar
2024-04-05Merge branch 'rs/config-comment'Junio C Hamano
"git config" learned "--comment=<message>" option to leave a comment immediately after the "variable = value" on the same line in the configuration file. * rs/config-comment: config: allow tweaking whitespace between value and comment config: fix --comment formatting config: add --comment option to add a comment
2024-04-03Merge branch 'bl/cherry-pick-empty'Junio C Hamano
Allow git-cherry-pick(1) to automatically drop redundant commits via a new `--empty` option, similar to the `--empty` options for git-rebase(1) and git-am(1). Includes a soft deprecation of `--keep-redundant-commits` as well as some related docs changes and sequencer code cleanup. * bl/cherry-pick-empty: cherry-pick: add `--empty` for more robust redundant commit handling cherry-pick: enforce `--keep-redundant-commits` incompatibility sequencer: do not require `allow_empty` for redundant commit options sequencer: handle unborn branch with `--allow-empty` rebase: update `--empty=ask` to `--empty=stop` docs: clean up `--empty` formatting in git-rebase(1) and git-am(1) docs: address inaccurate `--empty` default with `--exec`
2024-04-01Merge branch 'pb/advice-merge-conflict'Junio C Hamano
Hints that suggest what to do after resolving conflicts can now be squelched by disabling advice.mergeConflict. Acked-by: Phillip Wood <phillip.wood123@gmail.com> cf. <e040c631-42d9-4501-a7b8-046f8dac6309@gmail.com> * pb/advice-merge-conflict: builtin/am: allow disabling conflict advice sequencer: allow disabling conflict advice
2024-03-25cherry-pick: add `--empty` for more robust redundant commit handlingBrian Lyles
As with git-rebase(1) and git-am(1), git-cherry-pick(1) can result in a commit being made redundant if the content from the picked commit is already present in the target history. However, git-cherry-pick(1) does not have the same options available that git-rebase(1) and git-am(1) have. There are three things that can be done with these redundant commits: drop them, keep them, or have the cherry-pick stop and wait for the user to take an action. git-rebase(1) has the `--empty` option added in commit e98c4269c8 (rebase (interactive-backend): fix handling of commits that become empty, 2020-02-15), which handles all three of these scenarios. Similarly, git-am(1) got its own `--empty` in 7c096b8d61 (am: support --empty=<option> to handle empty patches, 2021-12-09). git-cherry-pick(1), on the other hand, only supports two of the three possiblities: Keep the redundant commits via `--keep-redundant-commits`, or have the cherry-pick fail by not specifying that option. There is no way to automatically drop redundant commits. In order to bring git-cherry-pick(1) more in-line with git-rebase(1) and git-am(1), this commit adds an `--empty` option to git-cherry-pick(1). It has the same three options (keep, drop, and stop), and largely behaves the same. The notable difference is that for git-cherry-pick(1), the default will be `stop`, which maintains the current behavior when the option is not specified. Like the existing `--keep-redundant-commits`, `--empty=keep` will imply `--allow-empty`. The `--keep-redundant-commits` option will be documented as a deprecated synonym of `--empty=keep`, and will be supported for backwards compatibility for the time being. Signed-off-by: Brian Lyles <brianmlyles@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25sequencer: do not require `allow_empty` for redundant commit optionsBrian Lyles
A consumer of the sequencer that wishes to take advantage of either the `keep_redundant_commits` or `drop_redundant_commits` feature must also specify `allow_empty`. However, these refer to two distinct types of empty commits: - `allow_empty` refers specifically to commits which start empty - `keep_redundant_commits` refers specifically to commits that do not start empty, but become empty due to the content already existing in the target history Conceptually, there is no reason that the behavior for handling one of these should be entangled with the other. It is particularly unintuitive to require `allow_empty` in order for `drop_redundant_commits` to have an effect: in order to prevent redundant commits automatically, initially-empty commits would need to be kept automatically as well. Instead, rewrite the `allow_empty()` logic to remove the over-arching requirement that `allow_empty` be specified in order to reach any of the keep/drop behaviors. Only if the commit was originally empty will `allow_empty` have an effect. Note that no behavioral changes should result from this commit -- it merely sets the stage for future commits. In one such future commit, an `--empty` option will be added to git-cherry-pick(1), meaning that `drop_redundant_commits` will be used by that command. Signed-off-by: Brian Lyles <brianmlyles@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-25sequencer: handle unborn branch with `--allow-empty`Brian Lyles
When using git-cherry-pick(1) with `--allow-empty` while on an unborn branch, an error is thrown. This is inconsistent with the same cherry-pick when `--allow-empty` is not specified. Detect unborn branches in `is_index_unchanged`. When on an unborn branch, use the `empty_tree` as the tree to compare against. Add a new test to cover this scenario. While modelled off of the existing 'cherry-pick on unborn branch' test, some improvements can be made: - Use `git switch --orphan unborn` instead of `git checkout --orphan unborn` to avoid the need for a separate `rm -rf *` call - Avoid using `--quiet` in the `git diff` call to make debugging easier in the event of a failure. Use simply `--exit-code` instead. Make these improvements to the existing test as well as the new test. Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Brian Lyles <brianmlyles@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-18Merge branch 'pw/rebase-i-ignore-cherry-pick-help-environment'Junio C Hamano
Code simplification by getting rid of code that sets an environment variable that is no longer used. * pw/rebase-i-ignore-cherry-pick-help-environment: rebase -i: stop setting GIT_CHERRY_PICK_HELP
2024-03-18sequencer: allow disabling conflict advicePhilippe Blain
Allow disabling the advice shown when a squencer operation results in a merge conflict through a new config 'advice.mergeConflict', which is named generically such that it can be used by other commands eventually. Remove that final '\n' in the first hunk in sequencer.c to avoid an otherwise empty 'hint: ' line before the line 'hint: Disable this message with "git config advice.mergeConflict false"' which is automatically added by 'advise_if_enabled'. Note that we use 'advise_if_enabled' for each message in the second hunk in sequencer.c, instead of using 'if (show_hints && advice_enabled(...)', because the former instructs the user how to disable the advice, which is more user-friendly. Update the tests accordingly. Note that the body of the second test in t3507-cherry-pick-conflict.sh is enclosed in double quotes, so we must escape them in the added line. Note that t5520-pull.sh, which checks that we display the advice for 'git rebase' (via 'git pull --rebase') does not have to be updated because it only greps for a specific line in the advice message. Signed-off-by: Philippe Blain <levraiphilippeblain@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-15config: add --comment option to add a commentRalph Seichter
Introduce the ability to append comments to modifications made using git-config. Example usage: git config --comment "changed via script" \ --add safe.directory /home/alice/repo.git based on the proposed patch, the output produced is: [safe] directory = /home/alice/repo.git #changed via script Users need to be able to distinguish between config entries made using automation and entries made by a human. Automation can add comments containing a URL pointing to explanations for the change made, avoiding questions from users as to why their config file was changed by a third party. The implementation ensures that a # character is unconditionally prepended to the provided comment string, and that the comment text is appended as a suffix to the changed key-value-pair in the same line of text. Multi-line comments (i.e. comments containing linefeed) are rejected as errors, causing Git to exit without making changes. Comments are aimed at humans who inspect or change their Git config using a pager or editor. Comments are not meant to be read or displayed by git-config at a later time. Signed-off-by: Ralph Seichter <github@seichter.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-14Merge branch 'la/trailer-api'Junio C Hamano
Trailer API updates. Acked-by: Christian Couder <christian.couder@gmail.com> cf. <CAP8UFD1Zd+9q0z1JmfOf60S2vn5-sD3SafDvAJUzRFwHJKcb8A@mail.gmail.com> * la/trailer-api: format_trailers_from_commit(): indirectly call trailer_info_get() format_trailer_info(): move "fast path" to caller format_trailers(): use strbuf instead of FILE trailer_info_get(): reorder parameters trailer: move interpret_trailers() to interpret-trailers.c trailer: reorder format_trailers_from_commit() parameters trailer: rename functions to use 'trailer' shortlog: add test for de-duplicating folded trailers trailer: free trailer_info _after_ all related usage
2024-03-12sequencer: handle multi-byte comment characters when writing todo listJeff King
We already match multi-byte comment characters in parse_insn_line(), thanks to the previous commit, yielding a TODO_COMMENT entry. But in todo_list_to_strbuf(), we may call command_to_char() to convert that back into something we can output. We can't just return comment_line_char anymore, since it may require multiple bytes. Instead, we'll return "0" for this case, which is the same thing we'd return for a command which does not have a single-letter abbreviation (e.g., "revert" or "noop"). There is only a single caller of command_to_char(), and upon seeing "0" it falls back to outputting the full name via command_to_string(). So we can handle TODO_COMMENT there, returning the full string. Note that there are many other callers of command_to_string(), which will now behave differently if they pass TODO_COMMENT. But we would not expect that to happen; prior to this commit, the function just calls die() in this case. And looking at those callers, that makes sense; e.g., do_pick_commit() will only be called when servicing a pick command, and should never be called for a comment in the first place. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-12find multi-byte comment chars in unterminated buffersJeff King
As with the previous patch, we need to swap out single-byte matching for something like starts_with() to match all bytes of a multi-byte comment character. But for cases where the buffer is not NUL-terminated (and we instead have an explicit size or end pointer), it's not safe to use starts_with(), as it might walk off the end of the buffer. Let's introduce a new starts_with_mem() that does the same thing but also accepts the length of the "haystack" str and makes sure not to walk past it. Note that in most cases the existing code did not need a length check at all, since it was written in a way that knew we had at least one byte available (and that was all we checked). So I had to read each one to find the appropriate bounds. The one exception is sequencer.c's add_commented_lines(), where we can actually get rid of the length check. Just like starts_with(), our starts_with_mem() handles an empty haystack variable by not matching (assuming a non-empty prefix). A few notes on the implementation of starts_with_mem(): - it would be equally correct to take an "end" pointer (and indeed, many of the callers have this and have to subtract to come up with the length). I think taking a ptr/size combo is a more usual interface for our codebase, though, and has the added benefit that the function signature makes it harder to mix up the three parameters. - we could obviously build starts_with() on top of this by passing strlen(str) as the length. But it's possible that starts_with() is a relatively hot code path, and it should not pay that penalty (it can generally return an answer proportional to the size of the prefix, not the whole string). - it naively feels like xstrncmpz() should be able to do the same thing, but that's not quite true. If you pass the length of the haystack buffer, then strncmp() finds that a shorter prefix string is "less than" than the haystack, even if the haystack starts with the prefix. If you pass the length of the prefix, then you risk reading past the end of the haystack if it is shorter than the prefix. So I think we really do need a new function. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-12find multi-byte comment chars in NUL-terminated stringsJeff King
Several parts of the code need to identify lines that begin with the comment character, and do so with a simple byte equality check. As part of the transition to handling multi-byte characters, we need to match all of the bytes. For cases where we are looking in a NUL-terminated string, we can just use starts_with(), which checks all of the characters in comment_line_str. Note that we can drop the "line.len" check in wt-status.c's read_rebase_todolist(). The starts_with() function handles the case of an empty haystack buffer (it will always return false for a non-empty prefix). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-12prefer comment_line_str to comment_line_char for printingJeff King
As part of our transition to multi-byte comment characters, we should use the string variable rather than the historical character variable. All of the sites adjusted here are just swapping out "%c" for "%s" in format strings, or strbuf_addch() for strbuf_addstr(). The type system and printf-attribute give the compiler enough information to make sure our formats and variable changes all match (especially important for cases where the format string is defined far away from its use, like prepare_to_commit() in commit.c). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-12strbuf: accept a comment string for strbuf_add_commented_lines()Jeff King
As part of our transition to multi-byte comment characters, let's take a NUL-terminated string pointer for strbuf_add_commented_lines() rather than a single character. All of the callers have to be adjusted; most can just pass comment_line_str rather than comment_line_char. And now our "cheat" in strbuf_commented_addf() can go away, as we can take the full string from it. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-12strbuf: accept a comment string for strbuf_commented_addf()Jeff King
As part of our transition to multi-byte comment characters, let's take a NUL-terminated string pointer for strbuf_commented_addf() rather than a single character. All of the callers have to be adjusted, but they can just pass comment_line_str rather than comment_line_char. Note that we rely on strbuf_add_commented_lines() under the hood, so we'll cheat a bit to squeeze our string into a single character (for now the two are equivalent, and we'll address this TODO in the next patch). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-12strbuf: accept a comment string for strbuf_stripspace()Jeff King
As part of our transition to multi-byte comment characters, let's take a NUL-terminated string pointer for strbuf_stripspace(), rather than a single character. We can continue to support its feature of ignoring comments by accepting a NULL pointer (as opposed to the current behavior of a NUL byte). All of the callers have to be adjusted, but they can all just pass comment_line_str (or NULL). Inside the function we detect comments by comparing the first byte of a line to the comment character. We'll adjust that to use starts_with(), which will match multiple bytes (though for now, of course, we still only allow a single byte, so it's academic). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-03-11Merge branch 'js/merge-base-with-missing-commit'Junio C Hamano
Make sure failure return from merge_bases_many() is properly caught. * js/merge-base-with-missing-commit: merge-ort/merge-recursive: do report errors in `merge_submodule()` merge-recursive: prepare for `merge_submodule()` to report errors commit-reach(repo_get_merge_bases_many_dirty): pass on errors commit-reach(repo_get_merge_bases_many): pass on "missing commits" errors commit-reach(get_octopus_merge_bases): pass on "missing commits" errors commit-reach(repo_get_merge_bases): pass on "missing commits" errors commit-reach(get_merge_bases_many_0): pass on "missing commits" errors commit-reach(merge_bases_many): pass on "missing commits" errors commit-reach(paint_down_to_common): start reporting errors commit-reach(paint_down_to_common): prepare for handling shallow commits commit-reach(repo_in_merge_bases_many): report missing commits commit-reach(repo_in_merge_bases_many): optionally expect missing commits commit-reach(paint_down_to_common): plug two memory leaks
2024-03-07Merge branch 'js/merge-tree-3-trees'Junio C Hamano
"git merge-tree" has learned that the three trees involved in the 3-way merge only need to be trees, not necessarily commits. * js/merge-tree-3-trees: fill_tree_descriptor(): mark error message for translation cache-tree: avoid an unnecessary check Always check `parse_tree*()`'s return value t4301: verify that merge-tree fails on missing blob objects merge-ort: do check `parse_tree()`'s return value merge-tree: fail with a non-zero exit code on missing tree objects merge-tree: accept 3 trees as arguments
2024-03-01trailer_info_get(): reorder parametersLinus Arver
This is another preparatory refactor to unify the trailer formatters. Take const struct process_trailer_options *opts as the first parameter, because these options are required for parsing trailers (e.g., whether to treat "---" as the end of the log message). And take struct trailer_info *info last, because it's an "out parameter" (something that the caller wants to use as the output of this function). Signed-off-by: Linus Arver <linusa@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-02-29commit-reach(repo_get_merge_bases): pass on "missing commits" errorsJohannes Schindelin
The `merge_bases_many()` function was just taught to indicate parsing errors, and now the `repo_get_merge_bases()` function (which is also surfaced via the `repo_get_merge_bases()` macro) is aware of that, too. Naturally, there are a lot of callers that need to be adjusted now, too. Next step: adjust the callers of `get_octopus_merge_bases()`. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-02-27rebase -i: stop setting GIT_CHERRY_PICK_HELPPhillip Wood
Setting this environment variable causes the sequencer to display a custom message when it stops for the user to resolve conflicts and remove CHERRY_PICK_HEAD. Setting it in "git rebase" is a vestige of the scripted implementation, now that it is a builtin command we do not need to communicate with the sequencer machinery via environment variables. Move the conflicts advice to use when rebasing into sequencer.c so we do not need to pass it via the environment. Note that we retain the changes in e4301f73fff (sequencer: unset GIT_CHERRY_PICK_HELP for 'exec' commands, 2024-02-02) just in case GIT_CHERRY_PICK_HELP is set in the environment when "git rebase" is run. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-02-23Always check `parse_tree*()`'s return valueJohannes Schindelin
Otherwise we may easily run into serious crashes: For example, if we run `init_tree_desc()` directly after a failed `parse_tree()`, we are accessing uninitialized data or trying to dereference `NULL`. Note that the `parse_tree()` function already takes care of showing an error message. The `parse_tree_indirectly()` and `repo_get_commit_tree()` functions do not, therefore those latter call sites need to show a useful error message while the former do not. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-02-14Merge branch 'vn/rebase-with-cherry-pick-authorship'Junio C Hamano
"git cherry-pick" invoked during "git rebase -i" session lost the authorship information, which has been corrected. * vn/rebase-with-cherry-pick-authorship: sequencer: unset GIT_CHERRY_PICK_HELP for 'exec' commands
2024-02-08sequencer: unset GIT_CHERRY_PICK_HELP for 'exec' commandsVegard Nossum
Running "git cherry-pick" as an x-command in the rebase plan loses the original authorship information. To fix this, unset GIT_CHERRY_PICK_HELP for 'exec' commands. Helped-by: Phillip Wood <phillip.wood123@gmail.com> Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-01-19sequencer: introduce functions to handle autostashes via refsPatrick Steinhardt
We're about to convert the MERGE_AUTOSTASH ref to become non-special, using the refs API instead of direct filesystem access to both read and write the ref. The current interfaces to write autostashes is entirely path-based though, so we need to extend them to also support writes via the refs API instead. Ideally, we would be able to fully replace the old set of path-based interfaces. But the sequencer will continue to write state into "rebase-merge/autostash". This path is not considered to be a ref at all and will thus stay is-is for now, which requires us to keep both path- and refs-based interfaces to handle autostashes. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-01-19refs: convert AUTO_MERGE to become a normal pseudo-refPatrick Steinhardt
In 70c70de616 (refs: complete list of special refs, 2023-12-14) we have inrtoduced a new `is_special_ref()` function that classifies some refs as being special. The rule is that special refs are exclusively read and written via the filesystem directly, whereas normal refs exclucsively go via the refs API. The intent of that commit was to record the status quo so that we know to route reads of such special refs consistently. Eventually, the list should be reduced to its bare minimum of refs which really are special, namely FETCH_HEAD and MERGE_HEAD. Follow up on this promise and convert the AUTO_MERGE ref to become a normal pseudo-ref by using the refs API to both read and write it instead of accessing the filesystem directly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-01-19sequencer: delete REBASE_HEAD in correct repo when picking commitsPatrick Steinhardt
When picking commits, we delete some state before executing the next sequencer action on interactive rebases. But while we use the correct repository to calculate paths to state files that need deletion, we use the repo-less `delete_ref()` function to delete REBASE_HEAD. Thus, if the sequencer ran in a different repository than `the_repository`, we would end up deleting the ref in the wrong repository. Fix this by using `refs_delete_ref()` instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-01-19sequencer: clean up pseudo refs with REF_NO_DEREFPatrick Steinhardt
When cleaning up the state-tracking pseudorefs CHERRY_PICK_HEAD or REVERT_HEAD we do not set REF_NO_DEREF. In the unlikely case where those refs are a symref we would thus end up deleting the symref targets, and not the symrefs themselves. Harden the code to use REF_NO_DEREF to fix this. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-01-08Merge branch 'en/header-cleanup'Junio C Hamano
Remove unused header "#include". * en/header-cleanup: treewide: remove unnecessary includes in source files treewide: add direct includes currently only pulled in transitively trace2/tr2_tls.h: remove unnecessary include submodule-config.h: remove unnecessary include pkt-line.h: remove unnecessary include line-log.h: remove unnecessary include http.h: remove unnecessary include fsmonitor--daemon.h: remove unnecessary includes blame.h: remove unnecessary includes archive.h: remove unnecessary include treewide: remove unnecessary includes in source files treewide: remove unnecessary includes from header files
2024-01-02Merge branch 'la/trailer-cleanups'Junio C Hamano
Code clean-up. * la/trailer-cleanups: trailer: use offsets for trailer_start/trailer_end trailer: find the end of the log message commit: ignore_non_trailer computes number of bytes to ignore
2023-12-26treewide: remove unnecessary includes in source filesElijah Newren
Each of these were checked with gcc -E -I. ${SOURCE_FILE} | grep ${HEADER_FILE} to ensure that removing the direct inclusion of the header actually resulted in that header no longer being included at all (i.e. that no other header pulled it in transitively). ...except for a few cases where we verified that although the header was brought in transitively, nothing from it was directly used in that source file. These cases were: * builtin/credential-cache.c * builtin/pull.c * builtin/send-pack.c Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-12-20trailer: use offsets for trailer_start/trailer_endLinus Arver
Previously these fields in the trailer_info struct were of type "const char *" and pointed to positions in the input string directly (to the start and end positions of the trailer block). Use offsets to make the intended usage less ambiguous. We only need to reference the input string in format_trailer_info(), so update that function to take a pointer to the input. While we're at it, rename trailer_start to trailer_block_start to be more explicit about these offsets (that they are for the entire trailer block including other trailers). Ditto for trailer_end. Reported-by: Glen Choo <glencbz@gmail.com> Signed-off-by: Linus Arver <linusa@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-12-08sequencer: simplify away extra git_config_string() callJeff King
In our config callback, we call git_config_string() to copy the incoming value string into a local string. But we don't modify or store that string; we just look at it and then free it. We can make the code simpler by just looking at the value passed into the callback. Note that we do need to check for NULL, which is the one bit of logic git_config_string() did for us. And I could even see an argument that we are abstracting any error-checking of the value behind the git_config_string() layer. But in practice no other callbacks behave this way; it is standard to check for NULL and then just look at the string directly. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-09-20Merge branch 'ob/sequencer-remove-dead-code'Junio C Hamano
Code clean-up. * ob/sequencer-remove-dead-code: sequencer: remove unreachable exit condition in pick_commits()
2023-09-14Merge branch 'pw/rebase-i-after-failure'Junio C Hamano
Various fixes to the behaviour of "rebase -i" when the command got interrupted by conflicting changes. * pw/rebase-i-after-failure: rebase -i: fix adding failed command to the todo list rebase --continue: refuse to commit after failed command rebase: fix rewritten list for failed pick sequencer: factor out part of pick_commits() sequencer: use rebase_path_message() rebase -i: remove patch file after conflict resolution rebase -i: move unlink() calls
2023-09-14Merge branch 'ob/revert-of-revert-is-reapply'Junio C Hamano
The default log message created by "git revert", when reverting a commit that records a revert, has been tweaked. * ob/revert-of-revert-is-reapply: git-revert.txt: add discussion sequencer: beautify subject of reverts of reverts
2023-09-13Merge branch 'ob/sequencer-reword-error-message'Junio C Hamano
Update an error message (which would probably never been seen). * ob/sequencer-reword-error-message: sequencer: fix error message on failure to copy SQUASH_MSG
2023-09-13sequencer: remove unreachable exit condition in pick_commits()Oswald Buddenhagen
This was introduced by 56dc3ab04 ("sequencer (rebase -i): implement the 'edit' command", 2017-01-02), and was pointless from the get-go: all early exits from the loop above are returns, so todo_list->current == todo_list->nr is an invariant after the loop. Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Acked-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-09-07Merge branch 'jk/unused-post-2.42'Junio C Hamano
Unused parameters to functions are marked as such, and/or removed, in order to bring us closer to -Wunused-parameter clean. * jk/unused-post-2.42: (22 commits) update-ref: mark unused parameter in parser callbacks gc: mark unused descriptors in scheduler callbacks bundle-uri: mark unused parameters in callbacks fetch: mark unused parameter in ref_transaction callback credential: mark unused parameter in urlmatch callback grep: mark unused parmaeters in pcre fallbacks imap-send: mark unused parameters with NO_OPENSSL worktree: mark unused parameters in noop repair callback negotiator/noop: mark unused callback parameters add-interactive: mark unused callback parameters grep: mark unused parameter in output function test-trace2: mark unused argv/argc parameters trace2: mark unused config callback parameter trace2: mark unused us_elapsed_absolute parameters stash: mark unused parameter in diff callback ls-tree: mark unused parameter in callback commit-graph: mark unused data parameters in generation callbacks worktree: mark unused parameters in each_ref_fn callback pack-bitmap: mark unused parameters in show_object callback ref-filter: mark unused parameters in parser callbacks ...
2023-09-06rebase -i: fix adding failed command to the todo listPhillip Wood
When rebasing commands are moved from the todo list in "git-rebase-todo" to the "done" file (which is used by "git status" to show the recently executed commands) just before they are executed. This means that if a command fails because it would overwrite an untracked file it has to be added back into the todo list before the rebase stops for the user to fix the problem. Unfortunately when a failed command is added back into the todo list the command preceding it is erroneously appended to the "done" file. This means that when rebase stops after "pick B" fails the "done" file contains pick A pick B pick A instead of pick A pick B This happens because save_todo() updates the "done" file with the previous command whenever "git-rebase-todo" is updated. When we add the failed pick back into "git-rebase-todo" we do not want to update "done". Fix this by adding a "reschedule" parameter to save_todo() which prevents the "done" file from being updated when adding a failed command back into the "git-rebase-todo" file. A couple of the existing tests are modified to improve their coverage as none of them trigger this bug or check the "done" file. Reported-by: Stefan Haller <lists@haller-berlin.de> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-09-06rebase --continue: refuse to commit after failed commandPhillip Wood
If a commit cannot be picked because it would overwrite an untracked file then "git rebase --continue" should refuse to commit any staged changes as the commit was not picked. This is implemented by refusing to commit if the message file is missing. The message file is chosen for this check because it is only written when "git rebase" stops for the user to resolve merge conflicts. Existing commands that refuse to commit staged changes when continuing such as a failed "exec" rely on checking for the absence of the author script in run_git_commit(). This prevents the staged changes from being committed but prints error: could not open '.git/rebase-merge/author-script' for reading before the message about not being able to commit. This is confusing to users and so checking for the message file instead improves the user experience. The existing test for refusing to commit after a failed exec is updated to check that we do not print the error message about a missing author script anymore. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-09-06rebase: fix rewritten list for failed pickPhillip Wood
git rebase keeps a list that maps the OID of each commit before it was rebased to the OID of the equivalent commit after the rebase. This list is used to drive the "post-rewrite" hook that is called at the end of a successful rebase. When a rebase stops for the user to resolve merge conflicts the OID of the commit being picked is written to ".git/rebase-merge/stopped-sha". Then when the rebase is continued that OID is added to the list of rewritten commits. Unfortunately if a commit cannot be picked because it would overwrite an untracked file we still write the "stopped-sha1" file. This means that when the rebase is continued the commit is added into the list of rewritten commits even though it has not been picked yet. Fix this by not calling error_with_patch() for failed commands. The pick has failed so there is nothing to commit and therefore we do not want to set up the state files for committing staged changes when the rebase continues. This change means we no-longer write a patch for the failed command or display the error message printed by error_with_patch(). As the command has failed the patch isn't really useful and in any case the user can inspect the commit associated with the failed command by inspecting REBASE_HEAD. Unless the user has disabled it we already print an advice message that is more helpful than the message from error_with_patch() which the user will still see. Even if the advice is disabled the user will see the messages from the merge machinery detailing the problem. The code to add a failed command back into the todo list is duplicated between pick_one_commit() and the loop in pick_commits(). Both sites print advice about the command being rescheduled, decrement the current item and save the todo list. To avoid duplicating this code pick_one_commit() is modified to set a flag to indicate that the command should be rescheduled in the main loop. This simplifies things as only the remaining copy of the code needs to be modified to set REBASE_HEAD rather than calling error_with_patch(). Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-09-06sequencer: factor out part of pick_commits()Phillip Wood
This simplifies the next commit. If a pick fails we now return the error at the end of the loop body rather than returning early, a successful "edit" command continues to return early. There are three things to check to ensure that removing the early return for an error does not change the behavior of the code: (1) We could enter the block guarded by "if (reschedule)". This block is not entered because "reschedlue" is always zero when picking a commit. (2) We could enter the block guarded by "else if (is_rebase_i(opts) && check_todo && !res)". This block is not entered when returning an error because "res" is non-zero in that case. (3) todo_list->current could be incremented before returning. That is avoided by moving the increment which is of course a potential change in behavior itself. The move is safe because none of the callers look at todo_list after this function returns. Moving the increment makes it clear we only want to advance the current item if the command was successful. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-09-06sequencer: use rebase_path_message()Phillip Wood
Rather than constructing the path in a struct strbuf use the ready made function to get the path name instead. This was the last remaining use of the strbuf so remove it as well. As with the previous patch we now use a hard coded string rather than git_dir() when constructing the path. This is safe for the same reason (make_patch() is only called when rebasing) and is protected by the assertion added in the previous patch. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-09-06rebase -i: remove patch file after conflict resolutionPhillip Wood
When a rebase stops for the user to resolve conflicts it writes a patch for the conflicting commit to .git/rebase-merge/patch. This file has been written since the introduction of "git-rebase-interactive.sh" in 1b1dce4bae7 (Teach rebase an interactive mode, 2007-06-25). I assume the idea was to enable the user inspect the conflicting commit in the same way as they could for the patch based rebase. This file should be deleted when the rebase continues as if the rebase stops for a failed "exec" command or a "break" command it is confusing to the user if there is a stale patch lying around from an unrelated command. As the path is now used in two different places rebase_path_patch() is added and used to obtain the path for the patch. To construct the path write_patch() previously used get_dir() which returns different paths depending on whether we're rebasing or cherry-picking/reverting. As this function is only called when rebasing it is safe to use a hard coded string for the directory instead. An assertion is added to make sure we don't starting calling this function when cherry-picking in the future. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-09-06rebase -i: move unlink() callsPhillip Wood
At the start of each iteration the loop that picks commits removes the state files from the previous pick. However some of these files are only written if there are conflicts in which case we exit the loop before the end of the loop body. Therefore they only need to be removed when the rebase continues, not at the start of each iteration. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-09-05sequencer: fix error message on failure to copy SQUASH_MSGOswald Buddenhagen
The message talked about renaming, while the actual action is copying. This was introduced by 6e98de72c ("sequencer (rebase -i): add support for the 'fixup' and 'squash' commands", 2017-01-02). Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Acked-by: Phillip Wood <phillip.wood123@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2023-09-02sequencer: beautify subject of reverts of revertsOswald Buddenhagen
Instead of generating a silly-looking `Revert "Revert "foo""`, make it a more humane `Reapply "foo"`. This is done for two reasons: - To cover the actually common case of just a double revert. - To encourage people to rewrite summaries of recursive reverts by setting an example (a subsequent commit will also do this explicitly in the documentation). To achieve these goals, the mechanism does not need to be particularly sophisticated. Therefore, more complicated alternatives which would "compress more efficiently" have not been implemented. Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>