From: Junio C Hamano Date: Wed, 27 Dec 2017 19:16:21 +0000 (-0800) Subject: Merge branch 'lb/rebase-i-short-command-names' X-Git-Tag: v2.16.0-rc0~35 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/0da2ba4880f971de2782f2d4cfcd68f9148d2860?ds=inline;hp=-c Merge branch 'lb/rebase-i-short-command-names' With a configuration variable rebase.abbreviateCommands set, "git rebase -i" produces the todo list with a single-letter command names. * lb/rebase-i-short-command-names: sequencer.c: drop 'const' from function return type t3404: add test case for abbreviated commands rebase -i: learn to abbreviate command names rebase -i -x: add exec commands via the rebase--helper rebase -i: update functions to use a flags parameter rebase -i: replace reference to sha1 with oid rebase -i: refactor transform_todo_ids rebase -i: set commit to null in exec commands Documentation: use preferred name for the 'todo list' script Documentation: move rebase.* configs to new file --- 0da2ba4880f971de2782f2d4cfcd68f9148d2860 diff --combined Documentation/config.txt index b18c0f97fe,e424b7de90..7814fb9044 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@@ -354,9 -354,6 +354,9 @@@ advice.*: ignoredHook:: Advice shown if an hook is ignored because the hook is not set as executable. + waitingForEditor:: + Print a message to the terminal whenever Git is waiting for + editor input from the user. -- core.fileMode:: @@@ -2111,40 -2108,15 +2111,40 @@@ matched against are those given directl visited as a result of a redirection do not participate in matching. ssh.variant:: - Depending on the value of the environment variables `GIT_SSH` or - `GIT_SSH_COMMAND`, or the config setting `core.sshCommand`, Git - auto-detects whether to adjust its command-line parameters for use - with plink or tortoiseplink, as opposed to the default (OpenSSH). + By default, Git determines the command line arguments to use + based on the basename of the configured SSH command (configured + using the environment variable `GIT_SSH` or `GIT_SSH_COMMAND` or + the config setting `core.sshCommand`). If the basename is + unrecognized, Git will attempt to detect support of OpenSSH + options by first invoking the configured SSH command with the + `-G` (print configuration) option and will subsequently use + OpenSSH options (if that is successful) or no options besides + the host and remote command (if it fails). ++ +The config variable `ssh.variant` can be set to override this detection. +Valid values are `ssh` (to use OpenSSH options), `plink`, `putty`, +`tortoiseplink`, `simple` (no options except the host and remote command). +The default auto-detection can be explicitly requested using the value +`auto`. Any other value is treated as `ssh`. This setting can also be +overridden via the environment variable `GIT_SSH_VARIANT`. ++ +The current command-line parameters used for each variant are as +follows: + -The config variable `ssh.variant` can be set to override this auto-detection; -valid values are `ssh`, `plink`, `putty` or `tortoiseplink`. Any other value -will be treated as normal ssh. This setting can be overridden via the -environment variable `GIT_SSH_VARIANT`. +-- + +* `ssh` - [-p port] [-4] [-6] [-o option] [username@]host command + +* `simple` - [username@]host command + +* `plink` or `putty` - [-P port] [-4] [-6] [username@]host command + +* `tortoiseplink` - [-P port] [-4] [-6] -batch [username@]host command + +-- ++ +Except for the `simple` variant, command-line parameters are likely to +change as git gains new features. i18n.commitEncoding:: Character encoding the commit messages are stored in; Git itself @@@ -2572,23 -2544,6 +2572,23 @@@ The protocol names currently used by gi `hg` to allow the `git-remote-hg` helper) -- +protocol.version:: + Experimental. If set, clients will attempt to communicate with a + server using the specified protocol version. If unset, no + attempt will be made by the client to communicate using a + particular protocol version, this results in protocol version 0 + being used. + Supported versions: ++ +-- + +* `0` - the original wire protocol. + +* `1` - the original wire protocol with the addition of a version string + in the initial response from the server. + +-- + pull.ff:: By default, Git does not create an extra merge commit when merging a commit that is a descendant of the current commit. Instead, the @@@ -2736,36 -2691,7 +2736,7 @@@ push.recurseSubmodules: is retained. You may override this configuration at time of push by specifying '--recurse-submodules=check|on-demand|no'. - rebase.stat:: - Whether to show a diffstat of what changed upstream since the last - rebase. False by default. - - rebase.autoSquash:: - If set to true enable `--autosquash` option by default. - - rebase.autoStash:: - When set to true, automatically create a temporary stash entry - before the operation begins, and apply it after the operation - ends. This means that you can run rebase on a dirty worktree. - However, use with care: the final stash application after a - successful rebase might result in non-trivial conflicts. - Defaults to false. - - rebase.missingCommitsCheck:: - If set to "warn", git rebase -i will print a warning if some - commits are removed (e.g. a line was deleted), however the - rebase will still proceed. If set to "error", it will print - the previous warning and stop the rebase, 'git rebase - --edit-todo' can then be used to correct the error. If set to - "ignore", no checking is done. - To drop a commit without warning or error, use the `drop` - command in the todo-list. - Defaults to "ignore". - - rebase.instructionFormat:: - A format string, as specified in linkgit:git-log[1], to be used for - the instruction list during an interactive rebase. The format will automatically - have the long commit hash prepended to the format. + include::rebase-config.txt[] receive.advertiseAtomic:: By default, git-receive-pack will advertise the atomic push @@@ -3471,13 -3397,3 +3442,13 @@@ web.browser: Specify a web browser that may be used by some commands. Currently only linkgit:git-instaweb[1] and linkgit:git-help[1] may use it. + +worktree.guessRemote:: + With `add`, if no branch argument, and neither of `-b` nor + `-B` nor `--detach` are given, the command defaults to + creating a new branch from HEAD. If `worktree.guessRemote` is + set to true, `worktree add` tries to find a remote-tracking + branch whose name uniquely matches the new branch name. If + such a branch exists, it is checked out and set as "upstream" + for the new branch. If no such match can be found, it falls + back to creating a new branch from the current HEAD. diff --combined sequencer.c index c8cb20c1eb,2a407cbe54..894d12ad72 --- a/sequencer.c +++ b/sequencer.c @@@ -347,7 -347,7 +347,7 @@@ static int read_oneliner(struct strbuf static struct tree *empty_tree(void) { - return lookup_tree(&empty_tree_oid); + return lookup_tree(the_hash_algo->empty_tree); } static int error_dirty_index(struct replay_opts *opts) @@@ -449,7 -449,6 +449,7 @@@ static int do_recursive_merge(struct co o.branch2 = next ? next_label : "(empty tree)"; if (is_rebase_i(opts)) o.buffer_output = 2; + o.show_rename_progress = 1; head_tree = parse_tree_indirect(head); next_tree = next ? next->tree : empty_tree(); @@@ -464,7 -463,6 +464,7 @@@ if (is_rebase_i(opts) && clean <= 0) fputs(o.obuf.buf, stdout); strbuf_release(&o.obuf); + diff_warn_rename_limit("merge.renamelimit", o.needed_rename_limit, 0); if (clean < 0) return clean; @@@ -708,7 -706,7 +708,7 @@@ static int is_original_commit_empty(str oid_to_hex(&parent->object.oid)); ptree_oid = &parent->tree->object.oid; } else { - ptree_oid = &empty_tree_oid; /* commit is root */ + ptree_oid = the_hash_algo->empty_tree; /* commit is root */ } return !oidcmp(ptree_oid, &commit->tree->object.oid); @@@ -797,6 -795,13 +797,13 @@@ static const char *command_to_string(co die("Unknown command: %d", command); } + static char command_to_char(const enum todo_command command) + { + if (command < TODO_COMMENT && todo_command_info[command].c) + return todo_command_info[command].c; + return comment_line_char; + } + static int is_noop(const enum todo_command command) { return TODO_NOOP <= command; @@@ -961,7 -966,7 +968,7 @@@ static int do_pick_commit(enum todo_com } else { unborn = get_oid("HEAD", &head); if (unborn) - oidcpy(&head, &empty_tree_oid); + oidcpy(&head, the_hash_algo->empty_tree); if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD", NULL, 0)) return error_dirty_index(opts); @@@ -1270,6 -1275,7 +1277,7 @@@ static int parse_insn_line(struct todo_ bol += padding; if (item->command == TODO_EXEC) { + item->commit = NULL; item->arg = bol; item->arg_len = (int)(eol - bol); return 0; @@@ -2445,14 -2451,16 +2453,16 @@@ void append_signoff(struct strbuf *msgb strbuf_release(&sob); } - int sequencer_make_script(int keep_empty, FILE *out, - int argc, const char **argv) + int sequencer_make_script(FILE *out, int argc, const char **argv, + unsigned flags) { char *format = NULL; struct pretty_print_context pp = {0}; struct strbuf buf = STRBUF_INIT; struct rev_info revs; struct commit *commit; + int keep_empty = flags & TODO_LIST_KEEP_EMPTY; + const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick"; init_revisions(&revs, NULL); revs.verbose_header = 1; @@@ -2485,7 -2493,8 +2495,8 @@@ strbuf_reset(&buf); if (!keep_empty && is_original_commit_empty(commit)) strbuf_addf(&buf, "%c ", comment_line_char); - strbuf_addf(&buf, "pick %s ", oid_to_hex(&commit->object.oid)); + strbuf_addf(&buf, "%s %s ", insn, + oid_to_hex(&commit->object.oid)); pretty_print_commit(&pp, commit, &buf); strbuf_addch(&buf, '\n'); fputs(buf.buf, out); @@@ -2494,61 -2503,90 +2505,90 @@@ return 0; } - - int transform_todo_ids(int shorten_ids) + /* + * Add commands after pick and (series of) squash/fixup commands + * in the todo list. + */ + int sequencer_add_exec_commands(const char *commands) { const char *todo_file = rebase_path_todo(); struct todo_list todo_list = TODO_LIST_INIT; - int fd, res, i; - FILE *out; + struct todo_item *item; + struct strbuf *buf = &todo_list.buf; + size_t offset = 0, commands_len = strlen(commands); + int i, first; - strbuf_reset(&todo_list.buf); - fd = open(todo_file, O_RDONLY); - if (fd < 0) - return error_errno(_("could not open '%s'"), todo_file); - if (strbuf_read(&todo_list.buf, fd, 0) < 0) { - close(fd); + if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0) return error(_("could not read '%s'."), todo_file); - } - close(fd); - res = parse_insn_buffer(todo_list.buf.buf, &todo_list); - if (res) { + if (parse_insn_buffer(todo_list.buf.buf, &todo_list)) { todo_list_release(&todo_list); return error(_("unusable todo list: '%s'"), todo_file); } - out = fopen(todo_file, "w"); - if (!out) { + first = 1; + /* insert before every pick except the first one */ + for (item = todo_list.items, i = 0; i < todo_list.nr; i++, item++) { + if (item->command == TODO_PICK && !first) { + strbuf_insert(buf, item->offset_in_buf + offset, + commands, commands_len); + offset += commands_len; + } + first = 0; + } + + /* append final */ + strbuf_add(buf, commands, commands_len); + + i = write_message(buf->buf, buf->len, todo_file, 0); + todo_list_release(&todo_list); + return i; + } + + int transform_todos(unsigned flags) + { + const char *todo_file = rebase_path_todo(); + struct todo_list todo_list = TODO_LIST_INIT; + struct strbuf buf = STRBUF_INIT; + struct todo_item *item; + int i; + + if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0) + return error(_("could not read '%s'."), todo_file); + + if (parse_insn_buffer(todo_list.buf.buf, &todo_list)) { todo_list_release(&todo_list); - return error(_("unable to open '%s' for writing"), todo_file); - } - for (i = 0; i < todo_list.nr; i++) { - struct todo_item *item = todo_list.items + i; - int bol = item->offset_in_buf; - const char *p = todo_list.buf.buf + bol; - int eol = i + 1 < todo_list.nr ? - todo_list.items[i + 1].offset_in_buf : - todo_list.buf.len; - - if (item->command >= TODO_EXEC && item->command != TODO_DROP) - fwrite(p, eol - bol, 1, out); - else { - const char *id = shorten_ids ? - short_commit_name(item->commit) : - oid_to_hex(&item->commit->object.oid); - int len; - - p += strspn(p, " \t"); /* left-trim command */ - len = strcspn(p, " \t"); /* length of command */ - - fprintf(out, "%.*s %s %.*s\n", - len, p, id, item->arg_len, item->arg); + return error(_("unusable todo list: '%s'"), todo_file); + } + + for (item = todo_list.items, i = 0; i < todo_list.nr; i++, item++) { + /* if the item is not a command write it and continue */ + if (item->command >= TODO_COMMENT) { + strbuf_addf(&buf, "%.*s\n", item->arg_len, item->arg); + continue; } + + /* add command to the buffer */ + if (flags & TODO_LIST_ABBREVIATE_CMDS) + strbuf_addch(&buf, command_to_char(item->command)); + else + strbuf_addstr(&buf, command_to_string(item->command)); + + /* add commit id */ + if (item->commit) { + const char *oid = flags & TODO_LIST_SHORTEN_IDS ? + short_commit_name(item->commit) : + oid_to_hex(&item->commit->object.oid); + + strbuf_addf(&buf, " %s", oid); + } + /* add all the rest */ + strbuf_addf(&buf, " %.*s\n", item->arg_len, item->arg); } - fclose(out); + + i = write_message(buf.buf, buf.len, todo_file, 0); todo_list_release(&todo_list); - return 0; + return i; } enum check_level {