From: Junio C Hamano Date: Fri, 2 Nov 2018 02:04:54 +0000 (+0900) Subject: Merge branch 'pk/rebase-in-c-3-acts' X-Git-Tag: v2.20.0-rc0~92 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/39f73315454d2553b2d3219a58f5110a60eba5a1?ds=inline;hp=-c Merge branch 'pk/rebase-in-c-3-acts' Rewrite "git rebase" in C. * pk/rebase-in-c-3-acts: builtin rebase: stop if `git am` is in progress builtin rebase: actions require a rebase in progress builtin rebase: support --edit-todo and --show-current-patch builtin rebase: support --quit builtin rebase: support --abort builtin rebase: support --skip builtin rebase: support --continue --- 39f73315454d2553b2d3219a58f5110a60eba5a1 diff --combined builtin/rebase.c index 71367c8530,2165656ae2..1308408277 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@@ -21,7 -21,7 +21,8 @@@ #include "diff.h" #include "wt-status.h" #include "revision.h" +#include "commit-reach.h" + #include "rerere.h" static char const * const builtin_rebase_usage[] = { N_("git rebase [-i] [options] [--exec ] [--onto ] " @@@ -92,6 -92,7 +93,7 @@@ struct rebase_options REBASE_INTERACTIVE_EXPLICIT = 1<<4, } flags; struct strbuf git_am_opt; + const char *action; }; static int is_interactive(struct rebase_options *opts) @@@ -116,6 -117,62 +118,62 @@@ static const char *state_dir_path(cons return path.buf; } + /* Read one file, then strip line endings */ + static int read_one(const char *path, struct strbuf *buf) + { + if (strbuf_read_file(buf, path, 0) < 0) + return error_errno(_("could not read '%s'"), path); + strbuf_trim_trailing_newline(buf); + return 0; + } + + /* Initialize the rebase options from the state directory. */ + static int read_basic_state(struct rebase_options *opts) + { + struct strbuf head_name = STRBUF_INIT; + struct strbuf buf = STRBUF_INIT; + struct object_id oid; + + if (read_one(state_dir_path("head-name", opts), &head_name) || + read_one(state_dir_path("onto", opts), &buf)) + return -1; + opts->head_name = starts_with(head_name.buf, "refs/") ? + xstrdup(head_name.buf) : NULL; + strbuf_release(&head_name); + if (get_oid(buf.buf, &oid)) + return error(_("could not get 'onto': '%s'"), buf.buf); + opts->onto = lookup_commit_or_die(&oid, buf.buf); + + /* + * We always write to orig-head, but interactive rebase used to write to + * head. Fall back to reading from head to cover for the case that the + * user upgraded git with an ongoing interactive rebase. + */ + strbuf_reset(&buf); + if (file_exists(state_dir_path("orig-head", opts))) { + if (read_one(state_dir_path("orig-head", opts), &buf)) + return -1; + } else if (read_one(state_dir_path("head", opts), &buf)) + return -1; + if (get_oid(buf.buf, &opts->orig_head)) + return error(_("invalid orig-head: '%s'"), buf.buf); + + strbuf_reset(&buf); + if (read_one(state_dir_path("quiet", opts), &buf)) + return -1; + if (buf.len) + opts->flags &= ~REBASE_NO_QUIET; + else + opts->flags |= REBASE_NO_QUIET; + + if (file_exists(state_dir_path("verbose", opts))) + opts->flags |= REBASE_VERBOSE; + + strbuf_release(&buf); + + return 0; + } + static int finish_rebase(struct rebase_options *opts) { struct strbuf dir = STRBUF_INIT; @@@ -169,12 -226,13 +227,13 @@@ static int run_specific_rebase(struct r add_var(&script_snippet, "state_dir", opts->state_dir); add_var(&script_snippet, "upstream_name", opts->upstream_name); - add_var(&script_snippet, "upstream", - oid_to_hex(&opts->upstream->object.oid)); + add_var(&script_snippet, "upstream", opts->upstream ? + oid_to_hex(&opts->upstream->object.oid) : NULL); add_var(&script_snippet, "head_name", opts->head_name ? opts->head_name : "detached HEAD"); add_var(&script_snippet, "orig_head", oid_to_hex(&opts->orig_head)); - add_var(&script_snippet, "onto", oid_to_hex(&opts->onto->object.oid)); + add_var(&script_snippet, "onto", opts->onto ? + oid_to_hex(&opts->onto->object.oid) : NULL); add_var(&script_snippet, "onto_name", opts->onto_name); add_var(&script_snippet, "revisions", opts->revisions); add_var(&script_snippet, "restrict_revision", opts->restrict_revision ? @@@ -190,6 -248,7 +249,7 @@@ opts->flags & REBASE_FORCE ? "t" : ""); if (opts->switch_to) add_var(&script_snippet, "switch_to", opts->switch_to); + add_var(&script_snippet, "action", opts->action ? opts->action : ""); switch (opts->type) { case REBASE_AM: @@@ -401,12 -460,21 +461,21 @@@ int cmd_rebase(int argc, const char **a .git_am_opt = STRBUF_INIT, }; const char *branch_name; - int ret, flags, in_progress = 0; + int ret, flags, total_argc, in_progress = 0; int ok_to_skip_pre_rebase = 0; struct strbuf msg = STRBUF_INIT; struct strbuf revisions = STRBUF_INIT; struct strbuf buf = STRBUF_INIT; struct object_id merge_base; + enum { + NO_ACTION, + ACTION_CONTINUE, + ACTION_SKIP, + ACTION_ABORT, + ACTION_QUIT, + ACTION_EDIT_TODO, + ACTION_SHOW_CURRENT_PATCH, + } action = NO_ACTION; struct option builtin_rebase_options[] = { OPT_STRING(0, "onto", &options.onto_name, N_("revision"), @@@ -428,6 -496,20 +497,20 @@@ OPT_BIT(0, "no-ff", &options.flags, N_("cherry-pick all commits, even if unchanged"), REBASE_FORCE), + OPT_CMDMODE(0, "continue", &action, N_("continue"), + ACTION_CONTINUE), + OPT_CMDMODE(0, "skip", &action, + N_("skip current patch and continue"), ACTION_SKIP), + OPT_CMDMODE(0, "abort", &action, + N_("abort and check out the original branch"), + ACTION_ABORT), + OPT_CMDMODE(0, "quit", &action, + N_("abort but keep HEAD where it is"), ACTION_QUIT), + OPT_CMDMODE(0, "edit-todo", &action, N_("edit the todo list " + "during an interactive rebase"), ACTION_EDIT_TODO), + OPT_CMDMODE(0, "show-current-patch", &action, + N_("show the patch file being applied or merged"), + ACTION_SHOW_CURRENT_PATCH), OPT_END(), }; @@@ -457,6 -539,11 +540,11 @@@ git_config(rebase_config, &options); + strbuf_reset(&buf); + strbuf_addf(&buf, "%s/applying", apply_dir()); + if(file_exists(buf.buf)) + die(_("It looks like 'git am' is in progress. Cannot rebase.")); + if (is_directory(apply_dir())) { options.type = REBASE_AM; options.state_dir = apply_dir(); @@@ -481,14 -568,110 +569,110 @@@ if (options.type != REBASE_UNSPECIFIED) in_progress = 1; + total_argc = argc; argc = parse_options(argc, argv, prefix, builtin_rebase_options, builtin_rebase_usage, 0); + if (action != NO_ACTION && total_argc != 2) { + usage_with_options(builtin_rebase_usage, + builtin_rebase_options); + } + if (argc > 2) usage_with_options(builtin_rebase_usage, builtin_rebase_options); + if (action != NO_ACTION && !in_progress) + die(_("No rebase in progress?")); + + if (action == ACTION_EDIT_TODO && !is_interactive(&options)) + die(_("The --edit-todo action can only be used during " + "interactive rebase.")); + + switch (action) { + case ACTION_CONTINUE: { + struct object_id head; + struct lock_file lock_file = LOCK_INIT; + int fd; + + options.action = "continue"; + + /* Sanity check */ + if (get_oid("HEAD", &head)) + die(_("Cannot read HEAD")); + + fd = hold_locked_index(&lock_file, 0); + if (read_index(the_repository->index) < 0) + die(_("could not read index")); + refresh_index(the_repository->index, REFRESH_QUIET, NULL, NULL, + NULL); + if (0 <= fd) + update_index_if_able(the_repository->index, + &lock_file); + rollback_lock_file(&lock_file); + + if (has_unstaged_changes(1)) { + puts(_("You must edit all merge conflicts and then\n" + "mark them as resolved using git add")); + exit(1); + } + if (read_basic_state(&options)) + exit(1); + goto run_rebase; + } + case ACTION_SKIP: { + struct string_list merge_rr = STRING_LIST_INIT_DUP; + + options.action = "skip"; + + rerere_clear(&merge_rr); + string_list_clear(&merge_rr, 1); + + if (reset_head(NULL, "reset", NULL, 0) < 0) + die(_("could not discard worktree changes")); + if (read_basic_state(&options)) + exit(1); + goto run_rebase; + } + case ACTION_ABORT: { + struct string_list merge_rr = STRING_LIST_INIT_DUP; + options.action = "abort"; + + rerere_clear(&merge_rr); + string_list_clear(&merge_rr, 1); + + if (read_basic_state(&options)) + exit(1); + if (reset_head(&options.orig_head, "reset", + options.head_name, 0) < 0) + die(_("could not move back to %s"), + oid_to_hex(&options.orig_head)); + ret = finish_rebase(&options); + goto cleanup; + } + case ACTION_QUIT: { + strbuf_reset(&buf); + strbuf_addstr(&buf, options.state_dir); + ret = !!remove_dir_recursively(&buf, 0); + if (ret) + die(_("could not remove '%s'"), options.state_dir); + goto cleanup; + } + case ACTION_EDIT_TODO: + options.action = "edit-todo"; + options.dont_finish_rebase = 1; + goto run_rebase; + case ACTION_SHOW_CURRENT_PATCH: + options.action = "show-current-patch"; + options.dont_finish_rebase = 1; + goto run_rebase; + case NO_ACTION: + break; + default: + BUG("action: %d", action); + } + /* Make sure no rebase is in progress */ if (in_progress) { const char *last_slash = strrchr(options.state_dir, '/'); @@@ -720,6 -903,7 +904,7 @@@ options.revisions = revisions.buf; + run_rebase: ret = !!run_specific_rebase(&options); cleanup: diff --combined strbuf.c index 64041c3c24,fdc0ffbafb..f6a6cf78b9 --- a/strbuf.c +++ b/strbuf.c @@@ -120,6 -120,15 +120,15 @@@ void strbuf_trim_trailing_dir_sep(struc sb->buf[sb->len] = '\0'; } + void strbuf_trim_trailing_newline(struct strbuf *sb) + { + if (sb->len > 0 && sb->buf[sb->len - 1] == '\n') { + if (--sb->len > 0 && sb->buf[sb->len - 1] == '\r') + --sb->len; + sb->buf[sb->len] = '\0'; + } + } + void strbuf_ltrim(struct strbuf *sb) { char *b = sb->buf; @@@ -134,7 -143,7 +143,7 @@@ int strbuf_reencode(struct strbuf *sb, const char *from, const char *to) { char *out; - int len; + size_t len; if (same_encoding(from, to)) return 0; @@@ -209,7 -218,7 +218,7 @@@ void strbuf_list_free(struct strbuf **s int strbuf_cmp(const struct strbuf *a, const struct strbuf *b) { - int len = a->len < b->len ? a->len: b->len; + size_t len = a->len < b->len ? a->len: b->len; int cmp = memcmp(a->buf, b->buf, len); if (cmp) return cmp; @@@ -389,7 -398,7 +398,7 @@@ size_t strbuf_expand_dict_cb(struct str void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src) { - int i, len = src->len; + size_t i, len = src->len; for (i = 0; i < len; i++) { if (src->buf[i] == '%') @@@ -469,7 -478,7 +478,7 @@@ int strbuf_readlink(struct strbuf *sb, hint = 32; while (hint < STRBUF_MAXLINK) { - int len; + ssize_t len; strbuf_grow(sb, hint); len = readlink(path, sb->buf, hint); @@@ -734,18 -743,18 +743,18 @@@ void strbuf_humanise_bytes(struct strbu { if (bytes > 1 << 30) { strbuf_addf(buf, "%u.%2.2u GiB", - (int)(bytes >> 30), - (int)(bytes & ((1 << 30) - 1)) / 10737419); + (unsigned)(bytes >> 30), + (unsigned)(bytes & ((1 << 30) - 1)) / 10737419); } else if (bytes > 1 << 20) { - int x = bytes + 5243; /* for rounding */ + unsigned x = bytes + 5243; /* for rounding */ strbuf_addf(buf, "%u.%2.2u MiB", x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20); } else if (bytes > 1 << 10) { - int x = bytes + 5; /* for rounding */ + unsigned x = bytes + 5; /* for rounding */ strbuf_addf(buf, "%u.%2.2u KiB", x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10); } else { - strbuf_addf(buf, "%u bytes", (int)bytes); + strbuf_addf(buf, "%u bytes", (unsigned)bytes); } } @@@ -960,7 -969,7 +969,7 @@@ static size_t cleanup(char *line, size_ */ void strbuf_stripspace(struct strbuf *sb, int skip_comments) { - int empties = 0; + size_t empties = 0; size_t i, j, len, newlen; char *eol; diff --combined strbuf.h index 9981f782b2,b7aea8a966..fc40873b65 --- a/strbuf.h +++ b/strbuf.h @@@ -87,7 -87,7 +87,7 @@@ struct object_id * Initialize the structure. The second parameter can be zero or a bigger * number to allocate memory, in case you want to prevent further reallocs. */ -extern void strbuf_init(struct strbuf *, size_t); +void strbuf_init(struct strbuf *sb, size_t alloc); /** * Release a string buffer and the memory it used. After this call, the @@@ -97,7 -97,7 +97,7 @@@ * To clear a strbuf in preparation for further use without the overhead * of free()ing and malloc()ing again, use strbuf_reset() instead. */ -extern void strbuf_release(struct strbuf *); +void strbuf_release(struct strbuf *sb); /** * Detach the string from the strbuf and returns it; you now own the @@@ -107,7 -107,7 +107,7 @@@ * The strbuf that previously held the string is reset to `STRBUF_INIT` so * it can be reused after calling this function. */ -extern char *strbuf_detach(struct strbuf *, size_t *); +char *strbuf_detach(struct strbuf *sb, size_t *sz); /** * Attach a string to a buffer. You should specify the string to attach, @@@ -117,7 -117,7 +117,7 @@@ * malloc()ed, and after attaching, the pointer cannot be relied upon * anymore, and neither be free()d directly. */ -extern void strbuf_attach(struct strbuf *, void *, size_t, size_t); +void strbuf_attach(struct strbuf *sb, void *str, size_t len, size_t mem); /** * Swap the contents of two string buffers. @@@ -148,7 -148,7 +148,7 @@@ static inline size_t strbuf_avail(cons * This is never a needed operation, but can be critical for performance in * some cases. */ -extern void strbuf_grow(struct strbuf *, size_t); +void strbuf_grow(struct strbuf *sb, size_t amount); /** * Set the length of the buffer to a given value. This function does *not* @@@ -183,30 -183,33 +183,33 @@@ static inline void strbuf_setlen(struc * Strip whitespace from the beginning (`ltrim`), end (`rtrim`), or both side * (`trim`) of a string. */ -extern void strbuf_trim(struct strbuf *); -extern void strbuf_rtrim(struct strbuf *); -extern void strbuf_ltrim(struct strbuf *); +void strbuf_trim(struct strbuf *sb); +void strbuf_rtrim(struct strbuf *sb); +void strbuf_ltrim(struct strbuf *sb); /* Strip trailing directory separators */ -extern void strbuf_trim_trailing_dir_sep(struct strbuf *); +void strbuf_trim_trailing_dir_sep(struct strbuf *sb); + /* Strip trailing LF or CR/LF */ -extern void strbuf_trim_trailing_newline(struct strbuf *sb); ++void strbuf_trim_trailing_newline(struct strbuf *sb); + /** * Replace the contents of the strbuf with a reencoded form. Returns -1 * on error, 0 on success. */ -extern int strbuf_reencode(struct strbuf *sb, const char *from, const char *to); +int strbuf_reencode(struct strbuf *sb, const char *from, const char *to); /** * Lowercase each character in the buffer using `tolower`. */ -extern void strbuf_tolower(struct strbuf *sb); +void strbuf_tolower(struct strbuf *sb); /** * Compare two buffers. Returns an integer less than, equal to, or greater * than zero if the first buffer is found, respectively, to be less than, * to match, or be greater than the second buffer. */ -extern int strbuf_cmp(const struct strbuf *, const struct strbuf *); +int strbuf_cmp(const struct strbuf *first, const struct strbuf *second); /** @@@ -233,38 -236,37 +236,38 @@@ static inline void strbuf_addch(struct /** * Add a character the specified number of times to the buffer. */ -extern void strbuf_addchars(struct strbuf *sb, int c, size_t n); +void strbuf_addchars(struct strbuf *sb, int c, size_t n); /** * Insert data to the given position of the buffer. The remaining contents * will be shifted, not overwritten. */ -extern void strbuf_insert(struct strbuf *, size_t pos, const void *, size_t); +void strbuf_insert(struct strbuf *sb, size_t pos, const void *, size_t); /** * Remove given amount of data from a given position of the buffer. */ -extern void strbuf_remove(struct strbuf *, size_t pos, size_t len); +void strbuf_remove(struct strbuf *sb, size_t pos, size_t len); /** * Remove the bytes between `pos..pos+len` and replace it with the given * data. */ -extern void strbuf_splice(struct strbuf *, size_t pos, size_t len, - const void *, size_t); +void strbuf_splice(struct strbuf *sb, size_t pos, size_t len, + const void *data, size_t data_len); /** * Add a NUL-terminated string to the buffer. Each line will be prepended * by a comment character and a blank. */ -extern void strbuf_add_commented_lines(struct strbuf *out, const char *buf, size_t size); +void strbuf_add_commented_lines(struct strbuf *out, + const char *buf, size_t size); /** * Add data of given length to the buffer. */ -extern void strbuf_add(struct strbuf *, const void *, size_t); +void strbuf_add(struct strbuf *sb, const void *data, size_t len); /** * Add a NUL-terminated string to the buffer. @@@ -283,7 -285,7 +286,7 @@@ static inline void strbuf_addstr(struc /** * Copy the contents of another buffer at the end of the current one. */ -extern void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2); +void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2); /** * This function can be used to expand a format string containing @@@ -309,13 -311,8 +312,13 @@@ * parameters to the callback, `strbuf_expand()` passes a context pointer, * which can be used by the programmer of the callback as she sees fit. */ -typedef size_t (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context); -extern void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, void *context); +typedef size_t (*expand_fn_t) (struct strbuf *sb, + const char *placeholder, + void *context); +void strbuf_expand(struct strbuf *sb, + const char *format, + expand_fn_t fn, + void *context); /** * Used as callback for `strbuf_expand()`, expects an array of @@@ -327,9 -324,7 +330,9 @@@ struct strbuf_expand_dict_entry const char *placeholder; const char *value; }; -extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context); +size_t strbuf_expand_dict_cb(struct strbuf *sb, + const char *placeholder, + void *context); /** * Append the contents of one strbuf to another, quoting any @@@ -337,29 -332,29 +340,29 @@@ * destination. This is useful for literal data to be fed to either * strbuf_expand or to the *printf family of functions. */ -extern void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src); +void strbuf_addbuf_percentquote(struct strbuf *dst, const struct strbuf *src); /** * Append the given byte size as a human-readable string (i.e. 12.23 KiB, * 3.50 MiB). */ -extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes); +void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes); /** * Add a formatted string to the buffer. */ __attribute__((format (printf,2,3))) -extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); +void strbuf_addf(struct strbuf *sb, const char *fmt, ...); /** * Add a formatted string prepended by a comment character and a * blank to the buffer. */ __attribute__((format (printf, 2, 3))) -extern void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...); +void strbuf_commented_addf(struct strbuf *sb, const char *fmt, ...); __attribute__((format (printf,2,0))) -extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap); +void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap); /** * Add the time specified by `tm`, as formatted by `strftime`. @@@ -369,9 -364,9 +372,9 @@@ * `suppress_tz_name`, when set, expands %Z internally to the empty * string rather than passing it to `strftime`. */ -extern void strbuf_addftime(struct strbuf *sb, const char *fmt, - const struct tm *tm, int tz_offset, - int suppress_tz_name); +void strbuf_addftime(struct strbuf *sb, const char *fmt, + const struct tm *tm, int tz_offset, + int suppress_tz_name); /** * Read a given size of data from a FILE* pointer to the buffer. @@@ -381,14 -376,14 +384,14 @@@ * `strbuf_read()`, `strbuf_read_file()` and `strbuf_getline_*()` * family of functions have the same behaviour as well. */ -extern size_t strbuf_fread(struct strbuf *, size_t, FILE *); +size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *file); /** * Read the contents of a given file descriptor. The third argument can be * used to give a hint about the file size, to avoid reallocs. If read fails, * any partial read is undone. */ -extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint); +ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint); /** * Read the contents of a given file descriptor partially by using only one @@@ -396,7 -391,7 +399,7 @@@ * file size, to avoid reallocs. Returns the number of new bytes appended to * the sb. */ -extern ssize_t strbuf_read_once(struct strbuf *, int fd, size_t hint); +ssize_t strbuf_read_once(struct strbuf *sb, int fd, size_t hint); /** * Read the contents of a file, specified by its path. The third argument @@@ -404,19 -399,19 +407,19 @@@ * Return the number of bytes read or a negative value if some error * occurred while opening or reading the file. */ -extern ssize_t strbuf_read_file(struct strbuf *sb, const char *path, size_t hint); +ssize_t strbuf_read_file(struct strbuf *sb, const char *path, size_t hint); /** * Read the target of a symbolic link, specified by its path. The third * argument can be used to give a hint about the size, to avoid reallocs. */ -extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint); +int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint); /** * Write the whole content of the strbuf to the stream not stopping at * NUL bytes. */ -extern ssize_t strbuf_write(struct strbuf *sb, FILE *stream); +ssize_t strbuf_write(struct strbuf *sb, FILE *stream); /** * Read a line from a FILE *, overwriting the existing contents of @@@ -430,10 -425,10 +433,10 @@@ typedef int (*strbuf_getline_fn)(struct strbuf *, FILE *); /* Uses LF as the line terminator */ -extern int strbuf_getline_lf(struct strbuf *sb, FILE *fp); +int strbuf_getline_lf(struct strbuf *sb, FILE *fp); /* Uses NUL as the line terminator */ -extern int strbuf_getline_nul(struct strbuf *sb, FILE *fp); +int strbuf_getline_nul(struct strbuf *sb, FILE *fp); /* * Similar to strbuf_getline_lf(), but additionally treats a CR that @@@ -442,14 -437,14 +445,14 @@@ * that can come from platforms whose native text format is CRLF * terminated. */ -extern int strbuf_getline(struct strbuf *, FILE *); +int strbuf_getline(struct strbuf *sb, FILE *file); /** * Like `strbuf_getline`, but keeps the trailing terminator (if * any) in the buffer. */ -extern int strbuf_getwholeline(struct strbuf *, FILE *, int); +int strbuf_getwholeline(struct strbuf *sb, FILE *file, int term); /** * Like `strbuf_getwholeline`, but operates on a file descriptor. @@@ -457,19 -452,19 +460,19 @@@ * use it unless you need the correct position in the file * descriptor. */ -extern int strbuf_getwholeline_fd(struct strbuf *, int, int); +int strbuf_getwholeline_fd(struct strbuf *sb, int fd, int term); /** * Set the buffer to the path of the current working directory. */ -extern int strbuf_getcwd(struct strbuf *sb); +int strbuf_getcwd(struct strbuf *sb); /** * Add a path to a buffer, converting a relative path to an * absolute one in the process. Symbolic links are not * resolved. */ -extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path); +void strbuf_add_absolute_path(struct strbuf *sb, const char *path); /** * Canonize `path` (make it absolute, resolve symlinks, remove extra @@@ -483,7 -478,7 +486,7 @@@ * Callers that don't mind links should use the more lightweight * strbuf_add_absolute_path() instead. */ -extern void strbuf_add_real_path(struct strbuf *sb, const char *path); +void strbuf_add_real_path(struct strbuf *sb, const char *path); /** @@@ -491,13 -486,13 +494,13 @@@ * normalize_path_copy() for details. If an error occurs, the contents of "sb" * are left untouched, and -1 is returned. */ -extern int strbuf_normalize_path(struct strbuf *sb); +int strbuf_normalize_path(struct strbuf *sb); /** * Strip whitespace from a buffer. The second parameter controls if * comments are considered contents to be removed or not. */ -extern void strbuf_stripspace(struct strbuf *buf, int skip_comments); +void strbuf_stripspace(struct strbuf *buf, int skip_comments); static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix) { @@@ -526,8 -521,8 +529,8 @@@ * For lighter-weight alternatives, see string_list_split() and * string_list_split_in_place(). */ -extern struct strbuf **strbuf_split_buf(const char *, size_t, - int terminator, int max); +struct strbuf **strbuf_split_buf(const char *str, size_t len, + int terminator, int max); static inline struct strbuf **strbuf_split_str(const char *str, int terminator, int max) @@@ -536,7 -531,7 +539,7 @@@ } static inline struct strbuf **strbuf_split_max(const struct strbuf *sb, - int terminator, int max) + int terminator, int max) { return strbuf_split_buf(sb->buf, sb->len, terminator, max); } @@@ -557,23 -552,23 +560,23 @@@ static inline struct strbuf **strbuf_sp * 'element1, element2, ..., elementN' * to str. If only one element, just write "element1" to str. */ -extern void strbuf_add_separated_string_list(struct strbuf *str, - const char *sep, - struct string_list *slist); +void strbuf_add_separated_string_list(struct strbuf *str, + const char *sep, + struct string_list *slist); /** * Free a NULL-terminated list of strbufs (for example, the return * values of the strbuf_split*() functions). */ -extern void strbuf_list_free(struct strbuf **); +void strbuf_list_free(struct strbuf **list); /** * Add the abbreviation, as generated by find_unique_abbrev, of `sha1` to * the strbuf `sb`. */ -extern void strbuf_add_unique_abbrev(struct strbuf *sb, - const struct object_id *oid, - int abbrev_len); +void strbuf_add_unique_abbrev(struct strbuf *sb, + const struct object_id *oid, + int abbrev_len); /** * Launch the user preferred editor to edit a file and fill the buffer @@@ -582,23 -577,15 +585,23 @@@ * run in. If the buffer is NULL the editor is launched as usual but the * file's contents are not read into the buffer upon completion. */ -extern int launch_editor(const char *path, struct strbuf *buffer, const char *const *env); +int launch_editor(const char *path, struct strbuf *buffer, + const char *const *env); + +int launch_sequence_editor(const char *path, struct strbuf *buffer, + const char *const *env); -extern void strbuf_add_lines(struct strbuf *sb, const char *prefix, const char *buf, size_t size); +void strbuf_add_lines(struct strbuf *sb, + const char *prefix, + const char *buf, + size_t size); /** * Append s to sb, with the characters '<', '>', '&' and '"' converted * into XML entities. */ -extern void strbuf_addstr_xml_quoted(struct strbuf *sb, const char *s); +void strbuf_addstr_xml_quoted(struct strbuf *sb, + const char *s); /** * "Complete" the contents of `sb` by ensuring that either it ends with the @@@ -628,8 -615,8 +631,8 @@@ static inline void strbuf_complete_line * If "allowed" is non-zero, restrict the set of allowed expansions. See * interpret_branch_name() for details. */ -extern void strbuf_branchname(struct strbuf *sb, const char *name, - unsigned allowed); +void strbuf_branchname(struct strbuf *sb, const char *name, + unsigned allowed); /* * Like strbuf_branchname() above, but confirm that the result is @@@ -637,15 -624,15 +640,15 @@@ * * The return value is "0" if the result is valid, and "-1" otherwise. */ -extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name); +int strbuf_check_branch_ref(struct strbuf *sb, const char *name); -extern void strbuf_addstr_urlencode(struct strbuf *, const char *, - int reserved); +void strbuf_addstr_urlencode(struct strbuf *sb, const char *name, + int reserved); __attribute__((format (printf,1,2))) -extern int printf_ln(const char *fmt, ...); +int printf_ln(const char *fmt, ...); __attribute__((format (printf,2,3))) -extern int fprintf_ln(FILE *fp, const char *fmt, ...); +int fprintf_ln(FILE *fp, const char *fmt, ...); char *xstrdup_tolower(const char *); char *xstrdup_toupper(const char *);