]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'ob/sequencer-empty-hint-fix' into maint-2.42
authorJunio C Hamano <gitster@pobox.com>
Thu, 2 Nov 2023 07:53:16 +0000 (16:53 +0900)
committerJunio C Hamano <gitster@pobox.com>
Thu, 2 Nov 2023 07:53:16 +0000 (16:53 +0900)
The use of API between two calls to require_clean_work_tree() from
the sequencer code has been cleaned up for consistency.

* ob/sequencer-empty-hint-fix:
  sequencer: rectify empty hint in call of require_clean_work_tree()

1  2 
sequencer.c
wt-status.c

diff --combined sequencer.c
index 828efd589deff91a67804951176b689d63a4cf18,c01fb7bf5c011b7a75be1539b339ac1fca5ec48d..bc6b7b6a7680b20a7d80f9c1be9a9df9d2f4d0f5
@@@ -1,6 -1,7 +1,6 @@@
 -#include "cache.h"
 +#include "git-compat-util.h"
  #include "abspath.h"
  #include "advice.h"
 -#include "alloc.h"
  #include "config.h"
  #include "copy.h"
  #include "environment.h"
@@@ -10,7 -11,7 +10,7 @@@
  #include "dir.h"
  #include "object-file.h"
  #include "object-name.h"
 -#include "object-store.h"
 +#include "object-store-ll.h"
  #include "object.h"
  #include "pager.h"
  #include "commit.h"
  #include "utf8.h"
  #include "cache-tree.h"
  #include "diff.h"
 +#include "path.h"
  #include "revision.h"
  #include "rerere.h"
 +#include "merge.h"
  #include "merge-ort.h"
  #include "merge-ort-wrappers.h"
  #include "refs.h"
 +#include "sparse-index.h"
  #include "strvec.h"
  #include "quote.h"
  #include "trailer.h"
  #include "rebase-interactive.h"
  #include "reset.h"
  #include "branch.h"
 -#include "wrapper.h"
  
  #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
  
 +/*
 + * To accommodate common filesystem limitations, where the loose refs' file
 + * names must not exceed `NAME_MAX`, the labels generated by `git rebase
 + * --rebase-merges` need to be truncated if the corresponding commit subjects
 + * are too long.
 + * Add some margin to stay clear from reaching `NAME_MAX`.
 + */
 +#define GIT_MAX_LABEL_LENGTH ((NAME_MAX) - (LOCK_SUFFIX_LEN) - 16)
 +
  static const char sign_off_header[] = "Signed-off-by: ";
  static const char cherry_picked_prefix[] = "(cherry picked from commit ";
  
@@@ -229,8 -219,7 +229,8 @@@ static struct update_ref_record *init_u
        return rec;
  }
  
 -static int git_sequencer_config(const char *k, const char *v, void *cb)
 +static int git_sequencer_config(const char *k, const char *v,
 +                              const struct config_context *ctx, void *cb)
  {
        struct replay_opts *opts = cb;
        int status;
        if (opts->action == REPLAY_REVERT && !strcmp(k, "revert.reference"))
                opts->commit_use_reference = git_config_bool(k, v);
  
 -      return git_diff_basic_config(k, v, NULL);
 +      return git_diff_basic_config(k, v, ctx, NULL);
  }
  
  void sequencer_init_config(struct replay_opts *opts)
@@@ -671,12 -660,11 +671,12 @@@ void append_conflicts_hint(struct index
        }
  
        strbuf_addch(msgbuf, '\n');
 -      strbuf_commented_addf(msgbuf, "Conflicts:\n");
 +      strbuf_commented_addf(msgbuf, comment_line_char, "Conflicts:\n");
        for (i = 0; i < istate->cache_nr;) {
                const struct cache_entry *ce = istate->cache[i++];
                if (ce_stage(ce)) {
 -                      strbuf_commented_addf(msgbuf, "\t%s\n", ce->name);
 +                      strbuf_commented_addf(msgbuf, comment_line_char,
 +                                            "\t%s\n", ce->name);
                        while (i < istate->cache_nr &&
                               !strcmp(ce->name, istate->cache[i]->name))
                                i++;
@@@ -1155,8 -1143,7 +1155,8 @@@ void cleanup_message(struct strbuf *msg
            cleanup_mode == COMMIT_MSG_CLEANUP_SCISSORS)
                strbuf_setlen(msgbuf, wt_status_locate_end(msgbuf->buf, msgbuf->len));
        if (cleanup_mode != COMMIT_MSG_CLEANUP_NONE)
 -              strbuf_stripspace(msgbuf, cleanup_mode == COMMIT_MSG_CLEANUP_ALL);
 +              strbuf_stripspace(msgbuf,
 +                cleanup_mode == COMMIT_MSG_CLEANUP_ALL ? comment_line_char : '\0');
  }
  
  /*
@@@ -1187,8 -1174,7 +1187,8 @@@ int template_untouched(const struct str
        if (!template_file || strbuf_read_file(&tmpl, template_file, 0) <= 0)
                return 0;
  
 -      strbuf_stripspace(&tmpl, cleanup_mode == COMMIT_MSG_CLEANUP_ALL);
 +      strbuf_stripspace(&tmpl,
 +        cleanup_mode == COMMIT_MSG_CLEANUP_ALL ? comment_line_char : '\0');
        if (!skip_prefix(sb->buf, tmpl.buf, &start))
                start = sb->buf;
        strbuf_release(&tmpl);
@@@ -1560,8 -1546,7 +1560,8 @@@ static int try_to_commit(struct reposit
                cleanup = opts->default_msg_cleanup;
  
        if (cleanup != COMMIT_MSG_CLEANUP_NONE)
 -              strbuf_stripspace(msg, cleanup == COMMIT_MSG_CLEANUP_ALL);
 +              strbuf_stripspace(msg,
 +                cleanup == COMMIT_MSG_CLEANUP_ALL ? comment_line_char : '\0');
        if ((flags & EDIT_MSG) && message_is_empty(msg, cleanup)) {
                res = 1; /* run 'git commit' to display error message */
                goto out;
@@@ -1855,7 -1840,7 +1855,7 @@@ static void add_commented_lines(struct 
                s += count;
                len -= count;
        }
 -      strbuf_add_commented_lines(buf, s, len);
 +      strbuf_add_commented_lines(buf, s, len, comment_line_char);
  }
  
  /* Does the current fixup chain contain a squash command? */
@@@ -1954,7 -1939,7 +1954,7 @@@ static int append_squash_message(struc
        strbuf_addf(buf, _(nth_commit_msg_fmt),
                    ++opts->current_fixup_count + 1);
        strbuf_addstr(buf, "\n\n");
 -      strbuf_add_commented_lines(buf, body, commented_len);
 +      strbuf_add_commented_lines(buf, body, commented_len, comment_line_char);
        /* buf->buf may be reallocated so store an offset into the buffer */
        fixup_off = buf->len;
        strbuf_addstr(buf, body + commented_len);
@@@ -2044,8 -2029,7 +2044,8 @@@ static int update_squash_messages(struc
                              _(first_commit_msg_str));
                strbuf_addstr(&buf, "\n\n");
                if (is_fixup_flag(command, flag))
 -                      strbuf_add_commented_lines(&buf, body, strlen(body));
 +                      strbuf_add_commented_lines(&buf, body, strlen(body),
 +                                                 comment_line_char);
                else
                        strbuf_addstr(&buf, body);
  
                strbuf_addf(&buf, _(skip_nth_commit_msg_fmt),
                            ++opts->current_fixup_count + 1);
                strbuf_addstr(&buf, "\n\n");
 -              strbuf_add_commented_lines(&buf, body, strlen(body));
 +              strbuf_add_commented_lines(&buf, body, strlen(body),
 +                                         comment_line_char);
        } else
                return error(_("unknown command: %d"), command);
        repo_unuse_commit_buffer(r, commit, message);
@@@ -2711,7 -2694,7 +2711,7 @@@ int todo_list_parse_insn_buffer(struct 
                if (fixup_okay)
                        ; /* do nothing */
                else if (is_fixup(item->command))
 -                      return error(_("cannot '%s' without a previous commit"),
 +                      res = error(_("cannot '%s' without a previous commit"),
                                command_to_string(item->command));
                else if (!is_noop(item->command))
                        fixup_okay = 1;
@@@ -2898,9 -2881,7 +2898,9 @@@ static int git_config_string_dup(char *
        return 0;
  }
  
 -static int populate_opts_cb(const char *key, const char *value, void *data)
 +static int populate_opts_cb(const char *key, const char *value,
 +                          const struct config_context *ctx,
 +                          void *data)
  {
        struct replay_opts *opts = data;
        int error_flag = 1;
        if (!value)
                error_flag = 0;
        else if (!strcmp(key, "options.no-commit"))
 -              opts->no_commit = git_config_bool_or_int(key, value, &error_flag);
 +              opts->no_commit = git_config_bool_or_int(key, value, ctx->kvi, &error_flag);
        else if (!strcmp(key, "options.edit"))
 -              opts->edit = git_config_bool_or_int(key, value, &error_flag);
 +              opts->edit = git_config_bool_or_int(key, value, ctx->kvi, &error_flag);
        else if (!strcmp(key, "options.allow-empty"))
                opts->allow_empty =
 -                      git_config_bool_or_int(key, value, &error_flag);
 +                      git_config_bool_or_int(key, value, ctx->kvi, &error_flag);
        else if (!strcmp(key, "options.allow-empty-message"))
                opts->allow_empty_message =
 -                      git_config_bool_or_int(key, value, &error_flag);
 +                      git_config_bool_or_int(key, value, ctx->kvi, &error_flag);
        else if (!strcmp(key, "options.keep-redundant-commits"))
                opts->keep_redundant_commits =
 -                      git_config_bool_or_int(key, value, &error_flag);
 +                      git_config_bool_or_int(key, value, ctx->kvi, &error_flag);
        else if (!strcmp(key, "options.signoff"))
 -              opts->signoff = git_config_bool_or_int(key, value, &error_flag);
 +              opts->signoff = git_config_bool_or_int(key, value, ctx->kvi, &error_flag);
        else if (!strcmp(key, "options.record-origin"))
 -              opts->record_origin = git_config_bool_or_int(key, value, &error_flag);
 +              opts->record_origin = git_config_bool_or_int(key, value, ctx->kvi, &error_flag);
        else if (!strcmp(key, "options.allow-ff"))
 -              opts->allow_ff = git_config_bool_or_int(key, value, &error_flag);
 +              opts->allow_ff = git_config_bool_or_int(key, value, ctx->kvi, &error_flag);
        else if (!strcmp(key, "options.mainline"))
 -              opts->mainline = git_config_int(key, value);
 +              opts->mainline = git_config_int(key, value, ctx->kvi);
        else if (!strcmp(key, "options.strategy"))
                git_config_string_dup(&opts->strategy, key, value);
        else if (!strcmp(key, "options.gpg-sign"))
                strvec_push(&opts->xopts, value);
        } else if (!strcmp(key, "options.allow-rerere-auto"))
                opts->allow_rerere_auto =
 -                      git_config_bool_or_int(key, value, &error_flag) ?
 +                      git_config_bool_or_int(key, value, ctx->kvi, &error_flag) ?
                                RERERE_AUTOUPDATE : RERERE_NOAUTOUPDATE;
        else if (!strcmp(key, "options.default-msg-cleanup")) {
                opts->explicit_cleanup = 1;
@@@ -5057,31 -5038,19 +5057,31 @@@ static int commit_staged_changes(struc
                                 * We need to update the squash message to skip
                                 * the latest commit message.
                                 */
 +                              int res = 0;
                                struct commit *commit;
 +                              const char *msg;
                                const char *path = rebase_path_squash_msg();
                                const char *encoding = get_commit_output_encoding();
  
 -                              if (parse_head(r, &commit) ||
 -                                  !(p = repo_logmsg_reencode(r, commit, NULL, encoding)) ||
 -                                  write_message(p, strlen(p), path, 0)) {
 -                                      repo_unuse_commit_buffer(r, commit, p);
 -                                      return error(_("could not write file: "
 +                              if (parse_head(r, &commit))
 +                                      return error(_("could not parse HEAD"));
 +
 +                              p = repo_logmsg_reencode(r, commit, NULL, encoding);
 +                              if (!p)  {
 +                                      res = error(_("could not parse commit %s"),
 +                                                  oid_to_hex(&commit->object.oid));
 +                                      goto unuse_commit_buffer;
 +                              }
 +                              find_commit_subject(p, &msg);
 +                              if (write_message(msg, strlen(msg), path, 0)) {
 +                                      res = error(_("could not write file: "
                                                       "'%s'"), path);
 +                                      goto unuse_commit_buffer;
                                }
 -                              repo_unuse_commit_buffer(r,
 -                                                       commit, p);
 +                      unuse_commit_buffer:
 +                              repo_unuse_commit_buffer(r, commit, p);
 +                              if (res)
 +                                      return res;
                        }
                }
  
@@@ -5361,7 -5330,6 +5361,7 @@@ struct label_state 
        struct oidmap commit2label;
        struct hashmap labels;
        struct strbuf buf;
 +      int max_label_length;
  };
  
  static const char *label_oid(struct object_id *oid, const char *label,
                }
        } else {
                struct strbuf *buf = &state->buf;
 +              int label_is_utf8 = 1; /* start with this assumption */
 +              size_t max_len = buf->len + state->max_label_length;
  
                /*
                 * Sanitize labels by replacing non-alpha-numeric characters
                 *
                 * Note that we retain non-ASCII UTF-8 characters (identified
                 * via the most significant bit). They should be all acceptable
 -               * in file names. We do not validate the UTF-8 here, that's not
 -               * the job of this function.
 +               * in file names.
 +               *
 +               * As we will use the labels as names of (loose) refs, it is
 +               * vital that the name not be longer than the maximum component
 +               * size of the file system (`NAME_MAX`). We are careful to
 +               * truncate the label accordingly, allowing for the `.lock`
 +               * suffix and for the label to be UTF-8 encoded (i.e. we avoid
 +               * truncating in the middle of a character).
                 */
 -              for (; *label; label++)
 -                      if ((*label & 0x80) || isalnum(*label))
 +              for (; *label && buf->len + 1 < max_len; label++)
 +                      if (isalnum(*label) ||
 +                          (!label_is_utf8 && (*label & 0x80)))
                                strbuf_addch(buf, *label);
 +                      else if (*label & 0x80) {
 +                              const char *p = label;
 +
 +                              utf8_width(&p, NULL);
 +                              if (p) {
 +                                      if (buf->len + (p - label) > max_len)
 +                                              break;
 +                                      strbuf_add(buf, label, p - label);
 +                                      label = p - 1;
 +                              } else {
 +                                      label_is_utf8 = 0;
 +                                      strbuf_addch(buf, *label);
 +                              }
                        /* avoid leading dash and double-dashes */
 -                      else if (buf->len && buf->buf[buf->len - 1] != '-')
 +                      else if (buf->len && buf->buf[buf->len - 1] != '-')
                                strbuf_addch(buf, '-');
                if (!buf->len) {
                        strbuf_addstr(buf, "rev-");
@@@ -5517,8 -5463,7 +5517,8 @@@ static int make_script_with_merges(stru
        struct string_entry *entry;
        struct oidset interesting = OIDSET_INIT, child_seen = OIDSET_INIT,
                shown = OIDSET_INIT;
 -      struct label_state state = { OIDMAP_INIT, { NULL }, STRBUF_INIT };
 +      struct label_state state =
 +              { OIDMAP_INIT, { NULL }, STRBUF_INIT, GIT_MAX_LABEL_LENGTH };
  
        int abbr = flags & TODO_LIST_ABBREVIATE_CMDS;
        const char *cmd_pick = abbr ? "p" : "pick",
                *cmd_reset = abbr ? "t" : "reset",
                *cmd_merge = abbr ? "m" : "merge";
  
 +      git_config_get_int("rebase.maxlabellength", &state.max_label_length);
 +
        oidmap_init(&commit2todo, 0);
        oidmap_init(&state.commit2label, 0);
        hashmap_init(&state.labels, labels_cmp, NULL, 0);
@@@ -6229,7 -6172,7 +6229,7 @@@ int complete_action(struct repository *
        if (checkout_onto(r, opts, onto_name, &oid, orig_head))
                goto cleanup;
  
-       if (require_clean_work_tree(r, "rebase", "", 1, 1))
+       if (require_clean_work_tree(r, "rebase", NULL, 1, 1))
                goto cleanup;
  
        todo_list_write_total_nr(&new_todo);
diff --combined wt-status.c
index 5b1378965c9aa37505a23cf9c472f1abe4d8503e,d48ee467a153f6b2976dd97a6619769ca0908aa5..bdbcf73cbf482ad87ac974a6ef3b21cfc80c1411
@@@ -1,4 -1,4 +1,4 @@@
 -#include "cache.h"
 +#include "git-compat-util.h"
  #include "advice.h"
  #include "wt-status.h"
  #include "object.h"
@@@ -7,10 -7,8 +7,10 @@@
  #include "diff.h"
  #include "environment.h"
  #include "gettext.h"
 +#include "hash.h"
  #include "hex.h"
  #include "object-name.h"
 +#include "path.h"
  #include "revision.h"
  #include "diffcore.h"
  #include "quote.h"
@@@ -20,7 -18,6 +20,7 @@@
  #include "refs.h"
  #include "submodule.h"
  #include "column.h"
 +#include "read-cache.h"
  #include "setup.h"
  #include "strbuf.h"
  #include "trace.h"
@@@ -1027,7 -1024,7 +1027,7 @@@ static void wt_longstatus_print_submodu
        if (s->display_comment_prefix) {
                size_t len;
                summary_content = strbuf_detach(&summary, &len);
 -              strbuf_add_commented_lines(&summary, summary_content, len);
 +              strbuf_add_commented_lines(&summary, summary_content, len, comment_line_char);
                free(summary_content);
        }
  
@@@ -1102,8 -1099,8 +1102,8 @@@ void wt_status_append_cut_line(struct s
  {
        const char *explanation = _("Do not modify or remove the line above.\nEverything below it will be ignored.");
  
 -      strbuf_commented_addf(buf, "%s", cut_line);
 -      strbuf_add_commented_lines(buf, explanation, strlen(explanation));
 +      strbuf_commented_addf(buf, comment_line_char, "%s", cut_line);
 +      strbuf_add_commented_lines(buf, explanation, strlen(explanation), comment_line_char);
  }
  
  void wt_status_add_cut_line(FILE *fp)
@@@ -1186,8 -1183,7 +1186,8 @@@ static void wt_longstatus_print_trackin
  
        t_begin = getnanotime();
  
 -      if (!format_tracking_info(branch, &sb, s->ahead_behind_flags))
 +      if (!format_tracking_info(branch, &sb, s->ahead_behind_flags,
 +                                !s->commit_template))
                return;
  
        if (advice_enabled(ADVICE_STATUS_AHEAD_BEHIND_WARNING) &&
@@@ -1794,10 -1790,10 +1794,10 @@@ void wt_status_get_state(struct reposit
                oidcpy(&state->revert_head_oid, &oid);
        }
        if (!sequencer_get_last_command(r, &action)) {
 -              if (action == REPLAY_PICK) {
 +              if (action == REPLAY_PICK && !state->cherry_pick_in_progress) {
                        state->cherry_pick_in_progress = 1;
                        oidcpy(&state->cherry_pick_head_oid, null_oid());
 -              } else {
 +              } else if (action == REPLAY_REVERT && !state->revert_in_progress) {
                        state->revert_in_progress = 1;
                        oidcpy(&state->revert_head_oid, null_oid());
                }
@@@ -2655,8 -2651,12 +2655,12 @@@ int require_clean_work_tree(struct repo
        }
  
        if (err) {
-               if (hint)
+               if (hint) {
+                       if (!*hint)
+                               BUG("empty hint passed to require_clean_work_tree();"
+                                   " use NULL instead");
                        error("%s", hint);
+               }
                if (!gently)
                        exit(128);
        }