Skip to content

Commit b9ac07d

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 66d92fe commit b9ac07d

File tree

4 files changed

+68
-3
lines changed

4 files changed

+68
-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
@@ -759,11 +759,11 @@ transform_todo_ids () {
759759
}
760760

761761
expand_todo_ids() {
762-
transform_todo_ids
762+
git rebase--helper --expand-sha1s
763763
}
764764

765765
collapse_todo_ids() {
766-
transform_todo_ids --short
766+
git rebase--helper --shorten-sha1s
767767
}
768768

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

sequencer.c

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2384,3 +2384,58 @@ int sequencer_make_script(int keep_empty, FILE *out,
23842384
strbuf_release(&buf);
23852385
return 0;
23862386
}
2387+
2388+
2389+
int transform_todo_ids(int shorten_sha1s)
2390+
{
2391+
const char *todo_file = rebase_path_todo();
2392+
struct todo_list todo_list = TODO_LIST_INIT;
2393+
int fd, res, i;
2394+
FILE *out;
2395+
2396+
strbuf_reset(&todo_list.buf);
2397+
fd = open(todo_file, O_RDONLY);
2398+
if (fd < 0)
2399+
return error(_("Could not open %s (%s)"),
2400+
todo_file, strerror(errno));
2401+
if (strbuf_read(&todo_list.buf, fd, 0) < 0) {
2402+
close(fd);
2403+
return error(_("Could not read %s."), todo_file);
2404+
}
2405+
close(fd);
2406+
2407+
res = parse_insn_buffer(todo_list.buf.buf, &todo_list);
2408+
if (res)
2409+
return error(_("Unusable instruction sheet: %s"), todo_file);
2410+
2411+
out = fopen(todo_file, "w");
2412+
if (!out)
2413+
return error(_("Unable to open '%s' for writing"), todo_file);
2414+
for (i = 0; i < todo_list.nr; i++) {
2415+
struct todo_item *item = todo_list.items + i;
2416+
int bol = item->offset_in_buf;
2417+
const char *p = todo_list.buf.buf + bol;
2418+
int eol = i + 1 < todo_list.nr ?
2419+
todo_list.items[i + 1].offset_in_buf :
2420+
todo_list.buf.len;
2421+
2422+
if (item->command >= TODO_EXEC && item->command != TODO_DROP)
2423+
fwrite(p, eol - bol, 1, out);
2424+
else {
2425+
int eoc = strcspn(p, " \t");
2426+
const char *sha1 = shorten_sha1s ?
2427+
short_commit_name(item->commit) :
2428+
oid_to_hex(&item->commit->object.oid);
2429+
2430+
if (!eoc) {
2431+
p += strspn(p, " \t");
2432+
eoc = strcspn(p, " \t");
2433+
}
2434+
2435+
fprintf(out, "%.*s %s %.*s\n",
2436+
eoc, p, sha1, item->arg_len, item->arg);
2437+
}
2438+
}
2439+
fclose(out);
2440+
return 0;
2441+
}

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)