git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 0/9] The final building block for a faster rebase -i

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Apr 25, 2017, 13:51 UTC
Message-ID
<cover.1493128210.git.johannes.schindelin@gmx.de>
In-Reply-To
<cover.1472833365.git.johannes.schindelin@gmx.de>

This patch series reimplements the expensive pre- and post-processing of the todo script in C.

And it concludes the work I did to accelerate rebase -i.
Changes since v1:
- rebased to the current `master` (which advanced quite a bit since v1
  was sent to the list on September 2nd, 2016)
- downcased error messages
- marked error messages for translation
- moved an "else" onto the same line as the preceding closing brace
- described the priorities of `fixup! <something>` in the man page, as
  suggested by Philip Oakley
Johannes Schindelin (9):
  rebase -i: generate the script via rebase--helper
  rebase -i: remove useless indentation
  rebase -i: do not invent onelines when expanding/collapsing SHA-1s
  rebase -i: also expand/collapse the SHA-1s via the rebase--helper
  t3404: relax rebase.missingCommitsCheck tests
  rebase -i: check for missing commits in the rebase--helper
  rebase -i: skip unnecessary picks using the rebase--helper
  t3415: test fixup with wrapped oneline
  rebase -i: rearrange fixup/squash lines using the rebase--helper
 Documentation/git-rebase.txt  |  16 +-
 builtin/rebase--helper.c      |  29 ++-
 git-rebase--interactive.sh    | 362 ++++-------------------------
 sequencer.c                   | 515 ++++++++++++++++++++++++++++++++++++++++++
 sequencer.h                   |   8 +
 t/t3404-rebase-interactive.sh |  22 +-
 t/t3415-rebase-autosquash.sh  |  16 +-
 7 files changed, 625 insertions(+), 343 deletions(-)
base-commit: e2cb6ab84c94f147f1259260961513b40c36108a
Based-On: rebase--helper at https://github.com/dscho/git
Fetch-Base-Via: git fetch https://github.com/dscho/git rebase--helper
Published-As: https://github.com/dscho/git/releases/tag/rebase-i-extra-v2
Fetch-It-Via: git fetch https://github.com/dscho/git rebase-i-extra-v2
Interdiff vs v1:
 diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
 index 67d48e68831..da79fbda5b3 100644
 --- a/Documentation/git-rebase.txt
 +++ b/Documentation/git-rebase.txt
 @@ -425,13 +425,15 @@ without an explicit `--interactive`.
  --autosquash::
  --no-autosquash::
  	When the commit log message begins with "squash! ..." (or
 -	"fixup! ..."), and there is a commit whose title begins with
 -	the same ..., automatically modify the todo list of rebase -i
 -	so that the commit marked for squashing comes right after the
 -	commit to be modified, and change the action of the moved
 -	commit from `pick` to `squash` (or `fixup`).  Ignores subsequent
 -	"fixup! " or "squash! " after the first, in case you referred to an
 -	earlier fixup/squash with `git commit --fixup/--squash`.
 +	"fixup! ..."), and there is already a commit in the todo list that
 +	matches the same `...`, automatically modify the todo list of rebase
 +	-i so that the commit marked for squashing comes right after the
 +	commit to be modified, and change the action of the moved commit
 +	from `pick` to `squash` (or `fixup`).  A commit matches the `...` if
 +	the commit subject matches, or if the `...` refers to the commit's
 +	hash. As a fall-back, partial matches of the commit subject work,
 +	too.  The recommended way to create fixup/squash commits is by using
 +	the `--fixup`/`--squash` options of linkgit:git-commit[1].
  +
  This option is only valid when the `--interactive` option is used.
  +
 diff --git a/sequencer.c b/sequencer.c
 index 5502b9006ed..2b07fb9e0ce 100644
 --- a/sequencer.c
 +++ b/sequencer.c
 @@ -2416,10 +2416,10 @@ int sequencer_make_script(int keep_empty, FILE *out,
  	pp.output_encoding = get_log_output_encoding();
  
  	if (setup_revisions(argc, argv, &revs, NULL) > 1)
 -		return error("make_script: unhandled options");
 +		return error(_("make_script: unhandled options"));
  
  	if (prepare_revision_walk(&revs) < 0)
 -		return error("make_script: error preparing revisions");
 +		return error(_("make_script: error preparing revisions"));
  
  	while ((commit = get_revision(&revs))) {
  		strbuf_reset(&buf);
 @@ -2445,23 +2445,23 @@ int transform_todo_ids(int shorten_sha1s)
  	strbuf_reset(&todo_list.buf);
  	fd = open(todo_file, O_RDONLY);
  	if (fd < 0)
 -		return error_errno(_("Could not open '%s'"), todo_file);
 +		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 (res) {
  		todo_list_release(&todo_list);
 -		return error(_("Unusable instruction sheet: %s"), todo_file);
 +		return error(_("unusable instruction sheet: '%s'"), todo_file);
  	}
  
  	out = fopen(todo_file, "w");
  	if (!out) {
  		todo_list_release(&todo_list);
 -		return error(_("Unable to open '%s' for writing"), todo_file);
 +		return error(_("unable to open '%s' for writing"), todo_file);
  	}
  	for (i = 0; i < todo_list.nr; i++) {
  		struct todo_item *item = todo_list.items + i;
 @@ -2508,8 +2508,8 @@ static enum check_level get_missing_commit_check_level(void)
  		return CHECK_WARN;
  	if (!strcasecmp("error", value))
  		return CHECK_ERROR;
 -	warning(_("Unrecognized setting $check_level for option"
 -			"rebase.missingCommitsCheck. Ignoring."));
 +	warning(_("unrecognized setting %s for option"
 +		  "rebase.missingCommitsCheck. Ignoring."), value);
  	return CHECK_IGNORE;
  }
  
 @@ -2530,12 +2530,12 @@ int check_todo_list(void)
  	strbuf_addstr(&todo_file, rebase_path_todo());
  	fd = open(todo_file.buf, O_RDONLY);
  	if (fd < 0) {
 -		res = error_errno(_("Could not open %s"), todo_file.buf);
 +		res = error_errno(_("could not open '%s'"), todo_file.buf);
  		goto leave_check;
  	}
  	if (strbuf_read(&todo_list.buf, fd, 0) < 0) {
  		close(fd);
 -		res = error(_("Could not read %s."), todo_file.buf);
 +		res = error(_("could not read '%s'."), todo_file.buf);
  		goto leave_check;
  	}
  	close(fd);
 @@ -2556,12 +2556,12 @@ int check_todo_list(void)
  	strbuf_addstr(&todo_file, ".backup");
  	fd = open(todo_file.buf, O_RDONLY);
  	if (fd < 0) {
 -		res = error_errno(_("Could not open %s"), todo_file.buf);
 +		res = error_errno(_("could not open '%s'"), todo_file.buf);
  		goto leave_check;
  	}
  	if (strbuf_read(&todo_list.buf, fd, 0) < 0) {
  		close(fd);
 -		res = error(_("Could not read %s."), todo_file.buf);
 +		res = error(_("could not read '%s'."), todo_file.buf);
  		goto leave_check;
  	}
  	close(fd);
 @@ -2610,9 +2610,10 @@ int check_todo_list(void)
  
  	if (raise_error)
  		fprintf(stderr,
 -			_("You can fix this with 'git rebase --edit-todo'.\n"
 -			"Or you can abort the rebase with 'git rebase"
 -			" --abort'.\n"));
 +			_("You can fix this with 'git rebase --edit-todo' "
 +			  "and then run 'git rebase --continue'.\n"
 +			  "Or you can abort the rebase with 'git rebase"
 +			  " --abort'.\n"));
  
  	return res;
  }
 @@ -2627,20 +2628,20 @@ int skip_unnecessary_picks(void)
  	int fd, i;
  
  	if (!read_oneliner(&buf, rebase_path_onto(), 0))
 -		return error("Could not read 'onto'");
 +		return error(_("could not read 'onto'"));
  	if (get_sha1(buf.buf, onto_oid.hash)) {
  		strbuf_release(&buf);
 -		return error("Need a HEAD to fixup");
 +		return error(_("need a HEAD to fixup"));
  	}
  	strbuf_release(&buf);
  
  	fd = open(todo_file, O_RDONLY);
  	if (fd < 0) {
 -		return error_errno(_("Could not open '%s'"), todo_file);
 +		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);
  	if (parse_insn_buffer(todo_list.buf.buf, &todo_list) < 0) {
 @@ -2657,7 +2658,7 @@ int skip_unnecessary_picks(void)
  			break;
  		if (parse_commit(item->commit)) {
  			todo_list_release(&todo_list);
 -			return error(_("Could not parse commit '%s'"),
 +			return error(_("could not parse commit '%s'"),
  				oid_to_hex(&item->commit->object.oid));
  		}
  		if (!item->commit->parents)
 @@ -2677,7 +2678,7 @@ int skip_unnecessary_picks(void)
  		fd = open(done_path, O_CREAT | O_WRONLY | O_APPEND, 0666);
  		if (write_in_full(fd, todo_list.buf.buf, offset) < 0) {
  			todo_list_release(&todo_list);
 -			return error_errno(_("Could not write to '%s'"),
 +			return error_errno(_("could not write to '%s'"),
  				done_path);
  		}
  		close(fd);
 @@ -2686,12 +2687,12 @@ int skip_unnecessary_picks(void)
  		if (write_in_full(fd, todo_list.buf.buf + offset,
  				todo_list.buf.len - offset) < 0) {
  			todo_list_release(&todo_list);
 -			return error_errno(_("Could not write to '%s'"),
 +			return error_errno(_("could not write to '%s'"),
  				rebase_path_todo());
  		}
  		if (ftruncate(fd, todo_list.buf.len - offset) < 0) {
  			todo_list_release(&todo_list);
 -			return error_errno(_("Could not truncate '%s'"),
 +			return error_errno(_("could not truncate '%s'"),
  				rebase_path_todo());
  		}
  		close(fd);
 @@ -2738,10 +2739,10 @@ int rearrange_squash(void)
  
  	fd = open(todo_file, O_RDONLY);
  	if (fd < 0)
 -		return error_errno(_("Could not open %s"), todo_file);
 +		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);
  	if (parse_insn_buffer(todo_list.buf.buf, &todo_list) < 0) {
 @@ -2778,7 +2779,7 @@ int rearrange_squash(void)
  
  		if (is_fixup(item->command)) {
  			todo_list_release(&todo_list);
 -			return error(_("The script was already rearranged."));
 +			return error(_("the script was already rearranged."));
  		}
  
  		item->commit->util = item;
 @@ -2832,8 +2833,7 @@ int rearrange_squash(void)
  			else
  				next[tail[i2]] = i;
  			tail[i2] = i;
 -		}
 -		else if (!hashmap_get_from_hash(&subject2item,
 +		} else if (!hashmap_get_from_hash(&subject2item,
  						strhash(subject), subject)) {
  			FLEX_ALLOC_MEM(entry, subject, buf.buf, buf.len);
  			entry->i = i;
 @@ -2883,11 +2883,12 @@ int rearrange_squash(void)
  
  		fd = open(todo_file, O_WRONLY);
  		if (fd < 0)
 -			res |= error_errno(_("Could not open %s"), todo_file);
 +			res = error_errno(_("could not open '%s'"), todo_file);
  		else if (write(fd, buf.buf, buf.len) < 0)
 -			res |= error_errno(_("Could not read %s."), todo_file);
 +			res = error_errno(_("could not read '%s'."), todo_file);
  		else if (ftruncate(fd, buf.len) < 0)
 -			res |= error_errno(_("Could not finish %s"), todo_file);
 +			res = error_errno(_("could not finish '%s'"),
 +					   todo_file);
  		close(fd);
  		strbuf_release(&buf);
  	}
-- 
2.12.2.windows.2.406.gd14a8f8640f
Previous: Johannes SchindelinNext: Johannes Schindelin
Message 16 of 100 in “The final building block for a faster rebase -i”
  1. 0/9 The final building block for a faster rebase -iJohannes Schindelin, Sep 2, 2016
  2. 1/9 rebase -i: generate the script via rebase--helperJohannes Schindelin, Sep 2, 2016
  3. 2/9 rebase -i: remove useless indentationJohannes Schindelin, Sep 2, 2016
  4. 3/9 rebase -i: do not invent onelines when expanding/collapsing SHA-1sJohannes Schindelin, Sep 2, 2016
  5. 4/9 rebase -i: also expand/collapse the SHA-1s via the rebase--helperJohannes Schindelin, Sep 2, 2016
  6. Dennis KaarsemakerSep 2, 2016
  7. Johannes SchindelinSep 3, 2016
  8. 5/9 t3404: relax rebase.missingCommitsCheck testsJohannes Schindelin, Sep 2, 2016
  9. 6/9 rebase -i: check for missing commits in the rebase--helperJohannes Schindelin, Sep 2, 2016
  10. Dennis KaarsemakerSep 2, 2016
  11. 8/9 t3415: test fixup with wrapped onelineJohannes Schindelin, Sep 2, 2016
  12. 7/9 rebase -i: skip unnecessary picks using the rebase--helperJohannes Schindelin, Sep 2, 2016
  13. 9/9 rebase -i: rearrange fixup/squash lines using the rebase--helperJohannes Schindelin, Sep 2, 2016
  14. Josh TriplettSep 3, 2016
  15. Johannes SchindelinSep 4, 2016
  16. 0/9 The final building block for a faster rebase -iJohannes Schindelin, Apr 25, 2017
  17. 3/9 rebase -i: do not invent onelines when expanding/collapsing SHA-1sJohannes Schindelin, Apr 25, 2017
  18. 1/9 rebase -i: generate the script via rebase--helperJohannes Schindelin, Apr 25, 2017
  19. Jeff KingApr 26, 2017
  20. Johannes SchindelinApr 26, 2017
  21. 2/9 rebase -i: remove useless indentationJohannes Schindelin, Apr 25, 2017
  22. 5/9 t3404: relax rebase.missingCommitsCheck testsJohannes Schindelin, Apr 25, 2017
  23. 4/9 rebase -i: also expand/collapse the SHA-1s via the rebase--helperJohannes Schindelin, Apr 25, 2017
  24. 8/9 t3415: test fixup with wrapped onelineJohannes Schindelin, Apr 25, 2017
  25. 6/9 rebase -i: check for missing commits in the rebase--helperJohannes Schindelin, Apr 25, 2017
  26. 9/9 rebase -i: rearrange fixup/squash lines using the rebase--helperJohannes Schindelin, Apr 25, 2017
  27. 7/9 rebase -i: skip unnecessary picks using the rebase--helperJohannes Schindelin, Apr 25, 2017
  28. Jeff KingApr 26, 2017
  29. Johannes SchindelinApr 26, 2017
  30. Junio C HamanoApr 26, 2017
  31. 0/9 The final building block for a faster rebase -iJohannes Schindelin, Apr 26, 2017
  32. 1/9 rebase -i: generate the script via rebase--helperJohannes Schindelin, Apr 26, 2017
  33. Junio C HamanoApr 27, 2017
  34. Johannes SchindelinApr 27, 2017
  35. Junio C HamanoApr 28, 2017
  36. Junio C HamanoApr 28, 2017
  37. Johannes SchindelinApr 28, 2017
  38. Junio C HamanoMay 1, 2017
  39. Johannes SchindelinMay 1, 2017
  40. Phillip WoodApr 28, 2017
  41. Johannes SchindelinApr 28, 2017
  42. Phillip WoodMay 1, 2017
  43. Johannes SchindelinMay 1, 2017
  44. Junio C HamanoMay 1, 2017
  45. Johannes SchindelinMay 1, 2017
  46. 2/9 rebase -i: remove useless indentationJohannes Schindelin, Apr 26, 2017
  47. 3/9 rebase -i: do not invent onelines when expanding/collapsing SHA-1sJohannes Schindelin, Apr 26, 2017
  48. 5/9 t3404: relax rebase.missingCommitsCheck testsJohannes Schindelin, Apr 26, 2017
  49. Junio C HamanoApr 27, 2017
  50. Johannes SchindelinApr 27, 2017
  51. 4/9 rebase -i: also expand/collapse the SHA-1s via the rebase--helperJohannes Schindelin, Apr 26, 2017
  52. Junio C HamanoApr 27, 2017
  53. Junio C HamanoApr 27, 2017
  54. Johannes SchindelinApr 27, 2017
  55. Junio C HamanoApr 28, 2017
  56. Johannes SchindelinApr 28, 2017
  57. 6/9 rebase -i: check for missing commits in the rebase--helperJohannes Schindelin, Apr 26, 2017
  58. Junio C HamanoApr 27, 2017
  59. Johannes SchindelinApr 28, 2017
  60. 7/9 rebase -i: skip unnecessary picks using the rebase--helperJohannes Schindelin, Apr 26, 2017
  61. 8/9 t3415: test fixup with wrapped onelineJohannes Schindelin, Apr 26, 2017
  62. 9/9 rebase -i: rearrange fixup/squash lines using the rebase--helperJohannes Schindelin, Apr 26, 2017
  63. 00/10 The final building block for a faster rebase -iJohannes Schindelin, Apr 28, 2017
  64. 01/10 t3415: verify that an empty instructionFormat is handled as beforeJohannes Schindelin, Apr 28, 2017
  65. 02/10 rebase -i: generate the script via rebase--helperJohannes Schindelin, Apr 28, 2017
  66. 02/10 rebase -i: generate the script via rebase--helperLiam Beguin, May 26, 2017
  67. Johannes SchindelinMay 29, 2017
  68. liam BeguinMay 30, 2017
  69. liam BeguinMay 30, 2017
  70. Junio C HamanoMay 29, 2017
  71. Johannes SchindelinMay 29, 2017
  72. Junio C HamanoMay 30, 2017
  73. Johannes SchindelinMay 30, 2017
  74. revision API design, was Re: [PATCH v4 02/10] rebase -i: generate the script via rebase--helperJohannes Schindelin, May 30, 2017
  75. Junio C HamanoMay 30, 2017
  76. Junio C HamanoJun 1, 2017
  77. 03/10 rebase -i: remove useless indentationJohannes Schindelin, Apr 28, 2017
  78. 03/10 rebase -i: remove useless indentationLiam Beguin, May 26, 2017
  79. Stefan BellerMay 26, 2017
  80. liam BeguinMay 27, 2017
  81. 04/10 rebase -i: do not invent onelines when expanding/collapsing SHA-1sJohannes Schindelin, Apr 28, 2017
  82. 05/10 rebase -i: also expand/collapse the SHA-1s via the rebase--helperJohannes Schindelin, Apr 28, 2017
  83. 05/10 rebase -i: also expand/collapse the SHA-1s via the rebase--helperLiam Beguin, May 26, 2017
  84. Johannes SchindelinMay 29, 2017
  85. 06/10 t3404: relax rebase.missingCommitsCheck testsJohannes Schindelin, Apr 28, 2017
  86. 07/10 rebase -i: check for missing commits in the rebase--helperJohannes Schindelin, Apr 28, 2017
  87. 08/10 rebase -i: skip unnecessary picks using the rebase--helperJohannes Schindelin, Apr 28, 2017
  88. 09/10 t3415: test fixup with wrapped onelineJohannes Schindelin, Apr 28, 2017
  89. 10/10 rebase -i: rearrange fixup/squash lines using the rebase--helperJohannes Schindelin, Apr 28, 2017
  90. 10/10 rebase -i: rearrange fixup/squash lines using the rebase--helperLiam Beguin, May 26, 2017
  91. Johannes SchindelinMay 29, 2017
  92. 00/10 The final building block for a faster rebase -iLiam Beguin, May 26, 2017
  93. René ScharfeMay 27, 2017
  94. Johannes SchindelinMay 29, 2017
  95. Ævar Arnfjörð BjarmasonMay 29, 2017
  96. Johannes SchindelinMay 30, 2017
  97. Ævar Arnfjörð BjarmasonMay 30, 2017
  98. Ævar Arnfjörð BjarmasonMay 31, 2017
  99. Johannes SchindelinMay 29, 2017
  100. Junio C HamanoMay 29, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.