mirror of
https://github.com/git/git.git
synced 2024-11-27 12:03:55 +08:00
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
This commit is contained in:
commit
0da2ba4880
@ -2736,36 +2736,7 @@ push.recurseSubmodules::
|
|||||||
is retained. You may override this configuration at time of push by
|
is retained. You may override this configuration at time of push by
|
||||||
specifying '--recurse-submodules=check|on-demand|no'.
|
specifying '--recurse-submodules=check|on-demand|no'.
|
||||||
|
|
||||||
rebase.stat::
|
include::rebase-config.txt[]
|
||||||
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.
|
|
||||||
|
|
||||||
receive.advertiseAtomic::
|
receive.advertiseAtomic::
|
||||||
By default, git-receive-pack will advertise the atomic push
|
By default, git-receive-pack will advertise the atomic push
|
||||||
|
@ -203,24 +203,7 @@ Alternatively, you can undo the 'git rebase' with
|
|||||||
CONFIGURATION
|
CONFIGURATION
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
rebase.stat::
|
include::rebase-config.txt[]
|
||||||
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::
|
|
||||||
If set to true enable `--autostash` option by default.
|
|
||||||
|
|
||||||
rebase.missingCommitsCheck::
|
|
||||||
If set to "warn", print warnings about removed commits in
|
|
||||||
interactive mode. If set to "error", print the warnings and
|
|
||||||
stop the rebase. If set to "ignore", no checking is
|
|
||||||
done. "ignore" by default.
|
|
||||||
|
|
||||||
rebase.instructionFormat::
|
|
||||||
Custom commit list format to use during an `--interactive` rebase.
|
|
||||||
|
|
||||||
OPTIONS
|
OPTIONS
|
||||||
-------
|
-------
|
||||||
|
52
Documentation/rebase-config.txt
Normal file
52
Documentation/rebase-config.txt
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
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.
|
||||||
|
This option can be overridden by the `--no-autostash` and
|
||||||
|
`--autostash` options of linkgit:git-rebase[1].
|
||||||
|
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
|
||||||
|
todo list during an interactive rebase. The format will
|
||||||
|
automatically have the long commit hash prepended to the format.
|
||||||
|
|
||||||
|
rebase.abbreviateCommands::
|
||||||
|
If set to true, `git rebase` will use abbreviated command names in the
|
||||||
|
todo list resulting in something like this:
|
||||||
|
+
|
||||||
|
-------------------------------------------
|
||||||
|
p deadbee The oneline of the commit
|
||||||
|
p fa1afe1 The oneline of the next commit
|
||||||
|
...
|
||||||
|
-------------------------------------------
|
||||||
|
+
|
||||||
|
instead of:
|
||||||
|
+
|
||||||
|
-------------------------------------------
|
||||||
|
pick deadbee The oneline of the commit
|
||||||
|
pick fa1afe1 The oneline of the next commit
|
||||||
|
...
|
||||||
|
-------------------------------------------
|
||||||
|
+
|
||||||
|
Defaults to false.
|
@ -12,10 +12,12 @@ static const char * const builtin_rebase_helper_usage[] = {
|
|||||||
int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
|
int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
struct replay_opts opts = REPLAY_OPTS_INIT;
|
struct replay_opts opts = REPLAY_OPTS_INIT;
|
||||||
int keep_empty = 0;
|
unsigned flags = 0, keep_empty = 0;
|
||||||
|
int abbreviate_commands = 0;
|
||||||
enum {
|
enum {
|
||||||
CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_SHA1S, EXPAND_SHA1S,
|
CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_OIDS, EXPAND_OIDS,
|
||||||
CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH
|
CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH,
|
||||||
|
ADD_EXEC
|
||||||
} command = 0;
|
} command = 0;
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")),
|
OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")),
|
||||||
@ -27,19 +29,22 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
|
|||||||
OPT_CMDMODE(0, "make-script", &command,
|
OPT_CMDMODE(0, "make-script", &command,
|
||||||
N_("make rebase script"), MAKE_SCRIPT),
|
N_("make rebase script"), MAKE_SCRIPT),
|
||||||
OPT_CMDMODE(0, "shorten-ids", &command,
|
OPT_CMDMODE(0, "shorten-ids", &command,
|
||||||
N_("shorten SHA-1s in the todo list"), SHORTEN_SHA1S),
|
N_("shorten commit ids in the todo list"), SHORTEN_OIDS),
|
||||||
OPT_CMDMODE(0, "expand-ids", &command,
|
OPT_CMDMODE(0, "expand-ids", &command,
|
||||||
N_("expand SHA-1s in the todo list"), EXPAND_SHA1S),
|
N_("expand commit ids in the todo list"), EXPAND_OIDS),
|
||||||
OPT_CMDMODE(0, "check-todo-list", &command,
|
OPT_CMDMODE(0, "check-todo-list", &command,
|
||||||
N_("check the todo list"), CHECK_TODO_LIST),
|
N_("check the todo list"), CHECK_TODO_LIST),
|
||||||
OPT_CMDMODE(0, "skip-unnecessary-picks", &command,
|
OPT_CMDMODE(0, "skip-unnecessary-picks", &command,
|
||||||
N_("skip unnecessary picks"), SKIP_UNNECESSARY_PICKS),
|
N_("skip unnecessary picks"), SKIP_UNNECESSARY_PICKS),
|
||||||
OPT_CMDMODE(0, "rearrange-squash", &command,
|
OPT_CMDMODE(0, "rearrange-squash", &command,
|
||||||
N_("rearrange fixup/squash lines"), REARRANGE_SQUASH),
|
N_("rearrange fixup/squash lines"), REARRANGE_SQUASH),
|
||||||
|
OPT_CMDMODE(0, "add-exec-commands", &command,
|
||||||
|
N_("insert exec commands in todo list"), ADD_EXEC),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
git_config(git_default_config, NULL);
|
git_config(git_default_config, NULL);
|
||||||
|
git_config_get_bool("rebase.abbreviatecommands", &abbreviate_commands);
|
||||||
|
|
||||||
opts.action = REPLAY_INTERACTIVE_REBASE;
|
opts.action = REPLAY_INTERACTIVE_REBASE;
|
||||||
opts.allow_ff = 1;
|
opts.allow_ff = 1;
|
||||||
@ -48,21 +53,25 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
|
|||||||
argc = parse_options(argc, argv, NULL, options,
|
argc = parse_options(argc, argv, NULL, options,
|
||||||
builtin_rebase_helper_usage, PARSE_OPT_KEEP_ARGV0);
|
builtin_rebase_helper_usage, PARSE_OPT_KEEP_ARGV0);
|
||||||
|
|
||||||
|
flags |= keep_empty ? TODO_LIST_KEEP_EMPTY : 0;
|
||||||
|
flags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0;
|
||||||
|
flags |= command == SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;
|
||||||
|
|
||||||
if (command == CONTINUE && argc == 1)
|
if (command == CONTINUE && argc == 1)
|
||||||
return !!sequencer_continue(&opts);
|
return !!sequencer_continue(&opts);
|
||||||
if (command == ABORT && argc == 1)
|
if (command == ABORT && argc == 1)
|
||||||
return !!sequencer_remove_state(&opts);
|
return !!sequencer_remove_state(&opts);
|
||||||
if (command == MAKE_SCRIPT && argc > 1)
|
if (command == MAKE_SCRIPT && argc > 1)
|
||||||
return !!sequencer_make_script(keep_empty, stdout, argc, argv);
|
return !!sequencer_make_script(stdout, argc, argv, flags);
|
||||||
if (command == SHORTEN_SHA1S && argc == 1)
|
if ((command == SHORTEN_OIDS || command == EXPAND_OIDS) && argc == 1)
|
||||||
return !!transform_todo_ids(1);
|
return !!transform_todos(flags);
|
||||||
if (command == EXPAND_SHA1S && argc == 1)
|
|
||||||
return !!transform_todo_ids(0);
|
|
||||||
if (command == CHECK_TODO_LIST && argc == 1)
|
if (command == CHECK_TODO_LIST && argc == 1)
|
||||||
return !!check_todo_list();
|
return !!check_todo_list();
|
||||||
if (command == SKIP_UNNECESSARY_PICKS && argc == 1)
|
if (command == SKIP_UNNECESSARY_PICKS && argc == 1)
|
||||||
return !!skip_unnecessary_picks();
|
return !!skip_unnecessary_picks();
|
||||||
if (command == REARRANGE_SQUASH && argc == 1)
|
if (command == REARRANGE_SQUASH && argc == 1)
|
||||||
return !!rearrange_squash();
|
return !!rearrange_squash();
|
||||||
|
if (command == ADD_EXEC && argc == 2)
|
||||||
|
return !!sequencer_add_exec_commands(argv[1]);
|
||||||
usage_with_options(builtin_rebase_helper_usage, options);
|
usage_with_options(builtin_rebase_helper_usage, options);
|
||||||
}
|
}
|
||||||
|
@ -722,27 +722,6 @@ collapse_todo_ids() {
|
|||||||
git rebase--helper --shorten-ids
|
git rebase--helper --shorten-ids
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add commands after a pick or after a squash/fixup series
|
|
||||||
# in the todo list.
|
|
||||||
add_exec_commands () {
|
|
||||||
{
|
|
||||||
first=t
|
|
||||||
while read -r insn rest
|
|
||||||
do
|
|
||||||
case $insn in
|
|
||||||
pick)
|
|
||||||
test -n "$first" ||
|
|
||||||
printf "%s" "$cmd"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
printf "%s %s\n" "$insn" "$rest"
|
|
||||||
first=
|
|
||||||
done
|
|
||||||
printf "%s" "$cmd"
|
|
||||||
} <"$1" >"$1.new" &&
|
|
||||||
mv "$1.new" "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Switch to the branch in $into and notify it in the reflog
|
# Switch to the branch in $into and notify it in the reflog
|
||||||
checkout_onto () {
|
checkout_onto () {
|
||||||
GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name"
|
GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $onto_name"
|
||||||
@ -982,7 +961,7 @@ fi
|
|||||||
|
|
||||||
test -s "$todo" || echo noop >> "$todo"
|
test -s "$todo" || echo noop >> "$todo"
|
||||||
test -z "$autosquash" || git rebase--helper --rearrange-squash || exit
|
test -z "$autosquash" || git rebase--helper --rearrange-squash || exit
|
||||||
test -n "$cmd" && add_exec_commands "$todo"
|
test -n "$cmd" && git rebase--helper --add-exec-commands "$cmd"
|
||||||
|
|
||||||
todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
|
todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
|
||||||
todocount=${todocount##* }
|
todocount=${todocount##* }
|
||||||
|
130
sequencer.c
130
sequencer.c
@ -797,6 +797,13 @@ static const char *command_to_string(const enum todo_command command)
|
|||||||
die("Unknown command: %d", command);
|
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)
|
static int is_noop(const enum todo_command command)
|
||||||
{
|
{
|
||||||
return TODO_NOOP <= command;
|
return TODO_NOOP <= command;
|
||||||
@ -1270,6 +1277,7 @@ static int parse_insn_line(struct todo_item *item, const char *bol, char *eol)
|
|||||||
bol += padding;
|
bol += padding;
|
||||||
|
|
||||||
if (item->command == TODO_EXEC) {
|
if (item->command == TODO_EXEC) {
|
||||||
|
item->commit = NULL;
|
||||||
item->arg = bol;
|
item->arg = bol;
|
||||||
item->arg_len = (int)(eol - bol);
|
item->arg_len = (int)(eol - bol);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2445,14 +2453,16 @@ void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
|
|||||||
strbuf_release(&sob);
|
strbuf_release(&sob);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sequencer_make_script(int keep_empty, FILE *out,
|
int sequencer_make_script(FILE *out, int argc, const char **argv,
|
||||||
int argc, const char **argv)
|
unsigned flags)
|
||||||
{
|
{
|
||||||
char *format = NULL;
|
char *format = NULL;
|
||||||
struct pretty_print_context pp = {0};
|
struct pretty_print_context pp = {0};
|
||||||
struct strbuf buf = STRBUF_INIT;
|
struct strbuf buf = STRBUF_INIT;
|
||||||
struct rev_info revs;
|
struct rev_info revs;
|
||||||
struct commit *commit;
|
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);
|
init_revisions(&revs, NULL);
|
||||||
revs.verbose_header = 1;
|
revs.verbose_header = 1;
|
||||||
@ -2485,7 +2495,8 @@ int sequencer_make_script(int keep_empty, FILE *out,
|
|||||||
strbuf_reset(&buf);
|
strbuf_reset(&buf);
|
||||||
if (!keep_empty && is_original_commit_empty(commit))
|
if (!keep_empty && is_original_commit_empty(commit))
|
||||||
strbuf_addf(&buf, "%c ", comment_line_char);
|
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);
|
pretty_print_commit(&pp, commit, &buf);
|
||||||
strbuf_addch(&buf, '\n');
|
strbuf_addch(&buf, '\n');
|
||||||
fputs(buf.buf, out);
|
fputs(buf.buf, out);
|
||||||
@ -2494,61 +2505,90 @@ int sequencer_make_script(int keep_empty, FILE *out,
|
|||||||
return 0;
|
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();
|
const char *todo_file = rebase_path_todo();
|
||||||
struct todo_list todo_list = TODO_LIST_INIT;
|
struct todo_list todo_list = TODO_LIST_INIT;
|
||||||
int fd, res, i;
|
struct todo_item *item;
|
||||||
FILE *out;
|
struct strbuf *buf = &todo_list.buf;
|
||||||
|
size_t offset = 0, commands_len = strlen(commands);
|
||||||
|
int i, first;
|
||||||
|
|
||||||
strbuf_reset(&todo_list.buf);
|
if (strbuf_read_file(&todo_list.buf, todo_file, 0) < 0)
|
||||||
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);
|
|
||||||
return error(_("could not read '%s'."), todo_file);
|
return error(_("could not read '%s'."), todo_file);
|
||||||
}
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
res = parse_insn_buffer(todo_list.buf.buf, &todo_list);
|
if (parse_insn_buffer(todo_list.buf.buf, &todo_list)) {
|
||||||
if (res) {
|
|
||||||
todo_list_release(&todo_list);
|
todo_list_release(&todo_list);
|
||||||
return error(_("unusable todo list: '%s'"), todo_file);
|
return error(_("unusable todo list: '%s'"), todo_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
out = fopen(todo_file, "w");
|
first = 1;
|
||||||
if (!out) {
|
/* insert <commands> before every pick except the first one */
|
||||||
todo_list_release(&todo_list);
|
for (item = todo_list.items, i = 0; i < todo_list.nr; i++, item++) {
|
||||||
return error(_("unable to open '%s' for writing"), todo_file);
|
if (item->command == TODO_PICK && !first) {
|
||||||
}
|
strbuf_insert(buf, item->offset_in_buf + offset,
|
||||||
for (i = 0; i < todo_list.nr; i++) {
|
commands, commands_len);
|
||||||
struct todo_item *item = todo_list.items + i;
|
offset += commands_len;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
first = 0;
|
||||||
}
|
}
|
||||||
fclose(out);
|
|
||||||
|
/* append final <commands> */
|
||||||
|
strbuf_add(buf, commands, commands_len);
|
||||||
|
|
||||||
|
i = write_message(buf->buf, buf->len, todo_file, 0);
|
||||||
todo_list_release(&todo_list);
|
todo_list_release(&todo_list);
|
||||||
return 0;
|
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(_("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);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = write_message(buf.buf, buf.len, todo_file, 0);
|
||||||
|
todo_list_release(&todo_list);
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum check_level {
|
enum check_level {
|
||||||
|
10
sequencer.h
10
sequencer.h
@ -45,10 +45,14 @@ int sequencer_continue(struct replay_opts *opts);
|
|||||||
int sequencer_rollback(struct replay_opts *opts);
|
int sequencer_rollback(struct replay_opts *opts);
|
||||||
int sequencer_remove_state(struct replay_opts *opts);
|
int sequencer_remove_state(struct replay_opts *opts);
|
||||||
|
|
||||||
int sequencer_make_script(int keep_empty, FILE *out,
|
#define TODO_LIST_KEEP_EMPTY (1U << 0)
|
||||||
int argc, const char **argv);
|
#define TODO_LIST_SHORTEN_IDS (1U << 1)
|
||||||
|
#define TODO_LIST_ABBREVIATE_CMDS (1U << 2)
|
||||||
|
int sequencer_make_script(FILE *out, int argc, const char **argv,
|
||||||
|
unsigned flags);
|
||||||
|
|
||||||
int transform_todo_ids(int shorten_ids);
|
int sequencer_add_exec_commands(const char *command);
|
||||||
|
int transform_todos(unsigned flags);
|
||||||
int check_todo_list(void);
|
int check_todo_list(void);
|
||||||
int skip_unnecessary_picks(void);
|
int skip_unnecessary_picks(void);
|
||||||
int rearrange_squash(void);
|
int rearrange_squash(void);
|
||||||
|
@ -1260,6 +1260,28 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = error' '
|
|||||||
test B = $(git cat-file commit HEAD^ | sed -ne \$p)
|
test B = $(git cat-file commit HEAD^ | sed -ne \$p)
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'respects rebase.abbreviateCommands with fixup, squash and exec' '
|
||||||
|
rebase_setup_and_clean abbrevcmd &&
|
||||||
|
test_commit "first" file1.txt "first line" first &&
|
||||||
|
test_commit "second" file1.txt "another line" second &&
|
||||||
|
test_commit "fixup! first" file2.txt "first line again" first_fixup &&
|
||||||
|
test_commit "squash! second" file1.txt "another line here" second_squash &&
|
||||||
|
cat >expected <<-EOF &&
|
||||||
|
p $(git rev-list --abbrev-commit -1 first) first
|
||||||
|
f $(git rev-list --abbrev-commit -1 first_fixup) fixup! first
|
||||||
|
x git show HEAD
|
||||||
|
p $(git rev-list --abbrev-commit -1 second) second
|
||||||
|
s $(git rev-list --abbrev-commit -1 second_squash) squash! second
|
||||||
|
x git show HEAD
|
||||||
|
EOF
|
||||||
|
git checkout abbrevcmd &&
|
||||||
|
set_cat_todo_editor &&
|
||||||
|
test_config rebase.abbreviateCommands true &&
|
||||||
|
test_must_fail git rebase -i --exec "git show HEAD" \
|
||||||
|
--autosquash master >actual &&
|
||||||
|
test_cmp expected actual
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'static check of bad command' '
|
test_expect_success 'static check of bad command' '
|
||||||
rebase_setup_and_clean bad-cmd &&
|
rebase_setup_and_clean bad-cmd &&
|
||||||
set_fake_editor &&
|
set_fake_editor &&
|
||||||
|
Loading…
Reference in New Issue
Block a user