Skip to content

Commit fe53c10

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 9438014 commit fe53c10

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
@@ -764,11 +764,11 @@ transform_todo_ids () {
764764
}
765765

766766
expand_todo_ids() {
767-
transform_todo_ids
767+
git rebase--helper --expand-sha1s
768768
}
769769

770770
collapse_todo_ids() {
771-
transform_todo_ids --short
771+
git rebase--helper --shorten-sha1s
772772
}
773773

774774
# 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
@@ -2391,3 +2391,62 @@ int sequencer_make_script(int keep_empty, FILE *out,
23912391
strbuf_release(&buf);
23922392
return 0;
23932393
}
2394+
2395+
2396+
int transform_todo_ids(int shorten_sha1s)
2397+
{
2398+
const char *todo_file = rebase_path_todo();
2399+
struct todo_list todo_list = TODO_LIST_INIT;
2400+
int fd, res, i;
2401+
FILE *out;
2402+
2403+
strbuf_reset(&todo_list.buf);
2404+
fd = open(todo_file, O_RDONLY);
2405+
if (fd < 0)
2406+
return error_errno(_("Could not open '%s'"), todo_file);
2407+
if (strbuf_read(&todo_list.buf, fd, 0) < 0) {
2408+
close(fd);
2409+
return error(_("Could not read %s."), todo_file);
2410+
}
2411+
close(fd);
2412+
2413+
res = parse_insn_buffer(todo_list.buf.buf, &todo_list);
2414+
if (res) {
2415+
todo_list_release(&todo_list);
2416+
return error(_("Unusable instruction sheet: %s"), todo_file);
2417+
}
2418+
2419+
out = fopen(todo_file, "w");
2420+
if (!out) {
2421+
todo_list_release(&todo_list);
2422+
return error(_("Unable to open '%s' for writing"), todo_file);
2423+
}
2424+
for (i = 0; i < todo_list.nr; i++) {
2425+
struct todo_item *item = todo_list.items + i;
2426+
int bol = item->offset_in_buf;
2427+
const char *p = todo_list.buf.buf + bol;
2428+
int eol = i + 1 < todo_list.nr ?
2429+
todo_list.items[i + 1].offset_in_buf :
2430+
todo_list.buf.len;
2431+
2432+
if (item->command >= TODO_EXEC && item->command != TODO_DROP)
2433+
fwrite(p, eol - bol, 1, out);
2434+
else {
2435+
int eoc = strcspn(p, " \t");
2436+
const char *sha1 = shorten_sha1s ?
2437+
short_commit_name(item->commit) :
2438+
oid_to_hex(&item->commit->object.oid);
2439+
2440+
if (!eoc) {
2441+
p += strspn(p, " \t");
2442+
eoc = strcspn(p, " \t");
2443+
}
2444+
2445+
fprintf(out, "%.*s %s %.*s\n",
2446+
eoc, p, sha1, item->arg_len, item->arg);
2447+
}
2448+
}
2449+
fclose(out);
2450+
todo_list_release(&todo_list);
2451+
return 0;
2452+
}

sequencer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ int sequencer_commit(const char *defmsg, struct replay_opts *opts,
6161
int sequencer_make_script(int keep_empty, FILE *out,
6262
int argc, const char **argv);
6363

64+
int transform_todo_ids(int shorten_sha1s);
65+
6466
extern const char sign_off_header[];
6567

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

0 commit comments

Comments
 (0)