Skip to content

Commit 0bfd9cc

Browse files
committed
sequencer (rebase -i): implement the 'exec' command
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent 1b1fe47 commit 0bfd9cc

1 file changed

Lines changed: 54 additions & 0 deletions

File tree

sequencer.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "refs.h"
1717
#include "argv-array.h"
1818
#include "log-tree.h"
19+
#include "wt-status.h"
1920

2021
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
2122

@@ -504,13 +505,15 @@ enum todo_command {
504505
TODO_PICK,
505506
TODO_REVERT,
506507
TODO_EDIT,
508+
TODO_EXEC,
507509
TODO_NOOP
508510
};
509511

510512
static const char *todo_command_strings[] = {
511513
"pick",
512514
"revert",
513515
"edit",
516+
"exec",
514517
"noop"
515518
};
516519

@@ -798,6 +801,12 @@ static int parse_insn_line(struct todo_item *item,
798801
return -1;
799802
bol += padding;
800803

804+
if (item->command == TODO_EXEC) {
805+
item->arg = bol;
806+
item->arg_len = (int)(eol - bol);
807+
return 0;
808+
}
809+
801810
end_of_object_name = (char *) bol + strcspn(bol, " \t\n");
802811
saved = *end_of_object_name;
803812
*end_of_object_name = '\0';
@@ -1139,6 +1148,43 @@ static int error_with_patch(struct commit *commit,
11391148
return exit_code;
11401149
}
11411150

1151+
static int do_exec(const char *command_line)
1152+
{
1153+
const char *child_argv[] = { NULL, NULL };
1154+
int dirty, status;
1155+
1156+
child_argv[0] = command_line;
1157+
status = run_command_v_opt(child_argv, RUN_USING_SHELL);
1158+
1159+
discard_cache(); /* force re-reading of the cache */
1160+
dirty = require_clean_work_tree("rebase", NULL, 1);
1161+
1162+
if (status) {
1163+
warning("Execution failed: %s\n%s"
1164+
"You can fix the problem, and then run\n"
1165+
"\n"
1166+
" git rebase --continue\n"
1167+
"\n",
1168+
command_line,
1169+
dirty ? "and made changes to the index and/or the "
1170+
"working tree\n" : "");
1171+
if (status == 127)
1172+
/* command not found */
1173+
status = 1;
1174+
}
1175+
else if (dirty) {
1176+
warning("Execution succeeded: %s\nbut "
1177+
"left changes to the index and/or the working tree\n"
1178+
"Commit or stash your changes, and then run\n"
1179+
"\n"
1180+
" git rebase --continue\n"
1181+
"\n", command_line);
1182+
status = 1;
1183+
}
1184+
1185+
return status;
1186+
}
1187+
11421188
static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
11431189
{
11441190
int res = 0;
@@ -1166,6 +1212,14 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
11661212
return error_with_patch(commit, opts, res);
11671213
}
11681214
}
1215+
else if (item->command == TODO_EXEC) {
1216+
char *end_of_arg = (char *)(item->arg + item->arg_len);
1217+
int saved = *end_of_arg;
1218+
1219+
*end_of_arg = '\0';
1220+
res = do_exec(item->arg);
1221+
*end_of_arg = saved;
1222+
}
11691223
else if (item->command != TODO_NOOP)
11701224
return error("Unknown command %d", item->command);
11711225

0 commit comments

Comments
 (0)