#define PATH_MAX 4096
#endif
+ #ifndef NAME_MAX
+ #define NAME_MAX 255
+ #endif
+
typedef uintmax_t timestamp_t;
#define PRItime PRIuMAX
#define parse_timestamp strtoumax
#endif
#ifndef platform_core_config
+struct config_context;
static inline int noop_core_config(const char *var UNUSED,
const char *value UNUSED,
+ const struct config_context *ctx UNUSED,
void *cb UNUSED)
{
return 0;
#include "compat/bswap.h"
-#include "wildmatch.h"
-
-struct strbuf;
+#include "wrapper.h"
/* General helper functions */
NORETURN void usage(const char *err);
report_fn get_warn_routine(void);
void set_die_is_recursing_routine(int (*routine)(void));
-int starts_with(const char *str, const char *prefix);
-int istarts_with(const char *str, const char *prefix);
-
/*
* If the string "str" begins with the string found in "prefix", return 1.
* The "out" parameter is set to "str + strlen(prefix)" (i.e., to the point in
return 0;
}
-/*
- * If the string "str" is the same as the string in "prefix", then the "arg"
- * parameter is set to the "def" parameter and 1 is returned.
- * If the string "str" begins with the string found in "prefix" and then a
- * "=" sign, then the "arg" parameter is set to "str + strlen(prefix) + 1"
- * (i.e., to the point in the string right after the prefix and the "=" sign),
- * and 1 is returned.
- *
- * Otherwise, return 0 and leave "arg" untouched.
- *
- * When we accept both a "--key" and a "--key=<val>" option, this function
- * can be used instead of !strcmp(arg, "--key") and then
- * skip_prefix(arg, "--key=", &arg) to parse such an option.
- */
-int skip_to_optional_arg_default(const char *str, const char *prefix,
- const char **arg, const char *def);
-
-static inline int skip_to_optional_arg(const char *str, const char *prefix,
- const char **arg)
-{
- return skip_to_optional_arg_default(str, prefix, arg, "");
-}
-
/*
* Like skip_prefix, but promises never to read past "len" bytes of the input
* buffer, and returns the remaining number of bytes in "out" via "outlen".
return strip_suffix_mem(str, len, suffix);
}
-static inline int ends_with(const char *str, const char *suffix)
-{
- size_t len;
- return strip_suffix(str, suffix, &len);
-}
-
#define SWAP(a, b) do { \
void *_swap_a_ptr = &(a); \
void *_swap_b_ptr = &(b); \
# define xalloca(size) (xmalloc(size))
# define xalloca_free(p) (free(p))
#endif
-char *xstrdup(const char *str);
-void *xmalloc(size_t size);
-void *xmallocz(size_t size);
-void *xmallocz_gently(size_t size);
-void *xmemdupz(const void *data, size_t len);
-char *xstrndup(const char *str, size_t len);
-void *xrealloc(void *ptr, size_t size);
-void *xcalloc(size_t nmemb, size_t size);
-void xsetenv(const char *name, const char *value, int overwrite);
-void *xmmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
-const char *mmap_os_err(void);
-void *xmmap_gently(void *start, size_t length, int prot, int flags, int fd, off_t offset);
-int xopen(const char *path, int flags, ...);
-ssize_t xread(int fd, void *buf, size_t len);
-ssize_t xwrite(int fd, const void *buf, size_t len);
-ssize_t xpread(int fd, void *buf, size_t len, off_t offset);
-int xdup(int fd);
-FILE *xfopen(const char *path, const char *mode);
-FILE *xfdopen(int fd, const char *mode);
-int xmkstemp(char *temp_filename);
-int xmkstemp_mode(char *temp_filename, int mode);
-char *xgetcwd(void);
-FILE *fopen_for_writing(const char *path);
-FILE *fopen_or_warn(const char *path, const char *mode);
-
-/*
- * Like strncmp, but only return zero if s is NUL-terminated and exactly len
- * characters long. If it is not, consider it greater than t.
- */
-int xstrncmpz(const char *s, const char *t, size_t len);
/*
* FREE_AND_NULL(ptr) is like free(ptr) followed by ptr = NULL. Note
#define FLEXPTR_ALLOC_STR(x, ptrname, str) \
FLEXPTR_ALLOC_MEM((x), ptrname, (str), strlen(str))
+#define alloc_nr(x) (((x)+16)*3/2)
+
+/**
+ * Dynamically growing an array using realloc() is error prone and boring.
+ *
+ * Define your array with:
+ *
+ * - a pointer (`item`) that points at the array, initialized to `NULL`
+ * (although please name the variable based on its contents, not on its
+ * type);
+ *
+ * - an integer variable (`alloc`) that keeps track of how big the current
+ * allocation is, initialized to `0`;
+ *
+ * - another integer variable (`nr`) to keep track of how many elements the
+ * array currently has, initialized to `0`.
+ *
+ * Then before adding `n`th element to the item, call `ALLOC_GROW(item, n,
+ * alloc)`. This ensures that the array can hold at least `n` elements by
+ * calling `realloc(3)` and adjusting `alloc` variable.
+ *
+ * ------------
+ * sometype *item;
+ * size_t nr;
+ * size_t alloc
+ *
+ * for (i = 0; i < nr; i++)
+ * if (we like item[i] already)
+ * return;
+ *
+ * // we did not like any existing one, so add one
+ * ALLOC_GROW(item, nr + 1, alloc);
+ * item[nr++] = value you like;
+ * ------------
+ *
+ * You are responsible for updating the `nr` variable.
+ *
+ * If you need to specify the number of elements to allocate explicitly
+ * then use the macro `REALLOC_ARRAY(item, alloc)` instead of `ALLOC_GROW`.
+ *
+ * Consider using ALLOC_GROW_BY instead of ALLOC_GROW as it has some
+ * added niceties.
+ *
+ * DO NOT USE any expression with side-effect for 'x', 'nr', or 'alloc'.
+ */
+#define ALLOC_GROW(x, nr, alloc) \
+ do { \
+ if ((nr) > alloc) { \
+ if (alloc_nr(alloc) < (nr)) \
+ alloc = (nr); \
+ else \
+ alloc = alloc_nr(alloc); \
+ REALLOC_ARRAY(x, alloc); \
+ } \
+ } while (0)
+
+/*
+ * Similar to ALLOC_GROW but handles updating of the nr value and
+ * zeroing the bytes of the newly-grown array elements.
+ *
+ * DO NOT USE any expression with side-effect for any of the
+ * arguments.
+ */
+#define ALLOC_GROW_BY(x, nr, increase, alloc) \
+ do { \
+ if (increase) { \
+ size_t new_nr = nr + (increase); \
+ if (new_nr < nr) \
+ BUG("negative growth in ALLOC_GROW_BY"); \
+ ALLOC_GROW(x, new_nr, alloc); \
+ memset((x) + nr, 0, sizeof(*(x)) * (increase)); \
+ nr = new_nr; \
+ } \
+ } while (0)
+
static inline char *xstrdup_or_null(const char *str)
{
return str ? xstrdup(str) : NULL;
return (size_t) len;
}
-__attribute__((format (printf, 3, 4)))
-int xsnprintf(char *dst, size_t max, const char *fmt, ...);
-
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 256
#endif
-int xgethostname(char *buf, size_t len);
-
-/* in ctype.c, for kwset users */
-extern const unsigned char tolower_trans_tbl[256];
-
-/* Sane ctype - no locale, and works with signed chars */
-#undef isascii
-#undef isspace
-#undef isdigit
-#undef isalpha
-#undef isalnum
-#undef isprint
-#undef islower
-#undef isupper
-#undef tolower
-#undef toupper
-#undef iscntrl
-#undef ispunct
-#undef isxdigit
-
-extern const unsigned char sane_ctype[256];
-extern const signed char hexval_table[256];
-#define GIT_SPACE 0x01
-#define GIT_DIGIT 0x02
-#define GIT_ALPHA 0x04
-#define GIT_GLOB_SPECIAL 0x08
-#define GIT_REGEX_SPECIAL 0x10
-#define GIT_PATHSPEC_MAGIC 0x20
-#define GIT_CNTRL 0x40
-#define GIT_PUNCT 0x80
-#define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)] & (mask)) != 0)
-#define isascii(x) (((x) & ~0x7f) == 0)
-#define isspace(x) sane_istest(x,GIT_SPACE)
-#define isdigit(x) sane_istest(x,GIT_DIGIT)
-#define isalpha(x) sane_istest(x,GIT_ALPHA)
-#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
-#define isprint(x) ((x) >= 0x20 && (x) <= 0x7e)
-#define islower(x) sane_iscase(x, 1)
-#define isupper(x) sane_iscase(x, 0)
-#define is_glob_special(x) sane_istest(x,GIT_GLOB_SPECIAL)
-#define is_regex_special(x) sane_istest(x,GIT_GLOB_SPECIAL | GIT_REGEX_SPECIAL)
-#define iscntrl(x) (sane_istest(x,GIT_CNTRL))
-#define ispunct(x) sane_istest(x, GIT_PUNCT | GIT_REGEX_SPECIAL | \
- GIT_GLOB_SPECIAL | GIT_PATHSPEC_MAGIC)
-#define isxdigit(x) (hexval_table[(unsigned char)(x)] != -1)
-#define tolower(x) sane_case((unsigned char)(x), 0x20)
-#define toupper(x) sane_case((unsigned char)(x), 0)
-#define is_pathspec_magic(x) sane_istest(x,GIT_PATHSPEC_MAGIC)
-
-static inline int sane_case(int x, int high)
-{
- if (sane_istest(x, GIT_ALPHA))
- x = (x & ~0x20) | high;
- return x;
-}
-
-static inline int sane_iscase(int x, int is_lower)
-{
- if (!sane_istest(x, GIT_ALPHA))
- return 0;
-
- if (is_lower)
- return (x & 0x20) != 0;
- else
- return (x & 0x20) == 0;
-}
+#include "sane-ctype.h"
/*
* Like skip_prefix, but compare case-insensitively. Note that the comparison
#endif
#endif
-enum fsync_action {
- FSYNC_WRITEOUT_ONLY,
- FSYNC_HARDWARE_FLUSH
-};
-
-/*
- * Issues an fsync against the specified file according to the specified mode.
- *
- * FSYNC_WRITEOUT_ONLY attempts to use interfaces available on some operating
- * systems to flush the OS cache without issuing a flush command to the storage
- * controller. If those interfaces are unavailable, the function fails with
- * ENOSYS.
- *
- * FSYNC_HARDWARE_FLUSH does an OS writeout and hardware flush to ensure that
- * changes are durable. It is not expected to fail.
- */
-int git_fsync(int fd, enum fsync_action action);
-
-/*
- * Writes out trace statistics for fsync using the trace2 API.
- */
-void trace_git_fsync_stats(void);
-
-/*
- * Preserves errno, prints a message, but gives no warning for ENOENT.
- * Returns 0 on success, which includes trying to unlink an object that does
- * not exist.
- */
-int unlink_or_warn(const char *path);
- /*
- * Tries to unlink file. Returns 0 if unlink succeeded
- * or the file already didn't exist. Returns -1 and
- * appends a message to err suitable for
- * 'error("%s", err->buf)' on error.
- */
-int unlink_or_msg(const char *file, struct strbuf *err);
-/*
- * Preserves errno, prints a message, but gives no warning for ENOENT.
- * Returns 0 on success, which includes trying to remove a directory that does
- * not exist.
- */
-int rmdir_or_warn(const char *path);
-/*
- * Calls the correct function out of {unlink,rmdir}_or_warn based on
- * the supplied file mode.
- */
-int remove_or_warn(unsigned int mode, const char *path);
-
-/*
- * Call access(2), but warn for any error except "missing file"
- * (ENOENT or ENOTDIR).
- */
-#define ACCESS_EACCES_OK (1U << 0)
-int access_or_warn(const char *path, int mode, unsigned flag);
-int access_or_die(const char *path, int mode, unsigned flag);
-
-/* Warn on an inaccessible file if errno indicates this is an error */
-int warn_on_fopen_errors(const char *path);
-
-/*
- * Open with O_NOFOLLOW, or equivalent. Note that the fallback equivalent
- * may be racy. Do not use this as protection against an attacker who can
- * simultaneously create paths.
- */
-int open_nofollow(const char *path, int flags);
-
#ifndef SHELL_PATH
# define SHELL_PATH "/bin/sh"
#endif
((uintptr_t)&(ptr)->member - (uintptr_t)(ptr))
#endif /* !__GNUC__ */
-void sleep_millisec(int millisec);
-
-/*
- * Generate len bytes from the system cryptographically secure PRNG.
- * Returns 0 on success and -1 on error, setting errno. The inability to
- * satisfy the full request is an error.
- */
-int csprng_bytes(void *buf, size_t len);
-
#endif
-#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"
#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 ";
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)
}
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++;
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');
}
/*
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);
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;
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? */
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);
_(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);
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;
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;
* 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;
}
}
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-");
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);