Skip to content

Commit df5263c

Browse files
committed
rebase -i: also expand/collapse the SHA-1s via the rebase--helper
This is crucial to improve performance on Windows, as the speed is now mostly dominated by the SHA-1 transformation (because it spawns a new rev-parse process for *every* line, and spawning processes is pretty slow from Git for Windows' MSYS2 Bash). Signed-off-by: Johannes Schindelin <[email protected]>
1 parent d82ccad commit df5263c

File tree

4 files changed

+72
-3
lines changed

4 files changed

+72
-3
lines changed

builtin/rebase--helper.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
1313
struct replay_opts opts = REPLAY_OPTS_INIT;
1414
int keep_empty = 0;
1515
enum {
16-
CONTINUE = 1, ABORT, MAKE_SCRIPT
16+
CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_SHA1S, EXPAND_SHA1S
1717
} command = 0;
1818
struct option options[] = {
1919
OPT_BOOL(0, "ff", &opts.allow_ff, N_("allow fast-forward")),
@@ -24,6 +24,10 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
2424
ABORT),
2525
OPT_CMDMODE(0, "make-script", &command,
2626
N_("make rebase script"), MAKE_SCRIPT),
27+
OPT_CMDMODE(0, "shorten-sha1s", &command,
28+
N_("shorten SHA-1s in the todo list"), SHORTEN_SHA1S),
29+
OPT_CMDMODE(0, "expand-sha1s", &command,
30+
N_("expand SHA-1s in the todo list"), EXPAND_SHA1S),
2731
OPT_END()
2832
};
2933

@@ -42,5 +46,9 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
4246
return !!sequencer_remove_state(&opts);
4347
if (command == MAKE_SCRIPT && argc > 1)
4448
return !!sequencer_make_script(keep_empty, stdout, argc, argv);
49+
if (command == SHORTEN_SHA1S && argc == 1)
50+
return !!transform_todo_ids(1);
51+
if (command == EXPAND_SHA1S && argc == 1)
52+
return !!transform_todo_ids(0);
4553
usage_with_options(builtin_rebase_helper_usage, options);
4654
}

git-rebase--interactive.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -774,11 +774,11 @@ transform_todo_ids () {
774774
}
775775

776776
expand_todo_ids() {
777-
transform_todo_ids
777+
git rebase--helper --expand-sha1s
778778
}
779779

780780
collapse_todo_ids() {
781-
transform_todo_ids --short
781+
git rebase--helper --shorten-sha1s
782782
}
783783

784784
# Rearrange the todo list that has both "pick sha1 msg" and

sequencer.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2433,3 +2433,62 @@ int sequencer_make_script(int keep_empty, FILE *out,
24332433
strbuf_release(&buf);
24342434
return 0;
24352435
}
2436+
2437+
2438+
int transform_todo_ids(int shorten_sha1s)
2439+
{
2440+
const char *todo_file = rebase_path_todo();
2441+
struct todo_list todo_list = TODO_LIST_INIT;
2442+
int fd, res, i;
2443+
FILE *out;
2444+
2445+
strbuf_reset(&todo_list.buf);
2446+
fd = open(todo_file, O_RDONLY);
2447+
if (fd < 0)
2448+
return error_errno(_("could not open '%s'"), todo_file);
2449+
if (strbuf_read(&todo_list.buf, fd, 0) < 0) {
2450+
close(fd);
2451+
return error(_("could not read '%s'."), todo_file);
2452+
}
2453+
close(fd);
2454+
2455+
res = parse_insn_buffer(todo_list.buf.buf, &todo_list);
2456+
if (res) {
2457+
todo_list_release(&todo_list);
2458+
return error(_("unusable instruction sheet: '%s'"), todo_file);
2459+
}
2460+
2461+
out = fopen(todo_file, "w");
2462+
if (!out) {
2463+
todo_list_release(&todo_list);
2464+
return error(_("unable to open '%s' for writing"), todo_file);
2465+
}
2466+
for (i = 0; i < todo_list.nr; i++) {
2467+
struct todo_item *item = todo_list.items + i;
2468+
int bol = item->offset_in_buf;
2469+
const char *p = todo_list.buf.buf + bol;
2470+
int eol = i + 1 < todo_list.nr ?
2471+
todo_list.items[i + 1].offset_in_buf :
2472+
todo_list.buf.len;
2473+
2474+
if (item->command >= TODO_EXEC && item->command != TODO_DROP)
2475+
fwrite(p, eol - bol, 1, out);
2476+
else {
2477+
int eoc = strcspn(p, " \t");
2478+
const char *sha1 = shorten_sha1s ?
2479+
short_commit_name(item->commit) :
2480+
oid_to_hex(&item->commit->object.oid);
2481+
2482+
if (!eoc) {
2483+
p += strspn(p, " \t");
2484+
eoc = strcspn(p, " \t");
2485+
}
2486+
2487+
fprintf(out, "%.*s %s %.*s\n",
2488+
eoc, p, sha1, item->arg_len, item->arg);
2489+
}
2490+
}
2491+
fclose(out);
2492+
todo_list_release(&todo_list);
2493+
return 0;
2494+
}

sequencer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ int sequencer_remove_state(struct replay_opts *opts);
4848
int sequencer_make_script(int keep_empty, FILE *out,
4949
int argc, const char **argv);
5050

51+
int transform_todo_ids(int shorten_sha1s);
52+
5153
extern const char sign_off_header[];
5254

5355
void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag);

0 commit comments

Comments
 (0)