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

Re: [PATCH v3 6/9] rebase -i: check for missing commits in the rebase--helper

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Apr 28, 2017, 15:10 UTC
Message-ID
<alpine.DEB.2.20.1704281659010.3480@virtualbox>
In-Reply-To
<xmqqh91ao1of.fsf@gitster.mtv.corp.google.com>
Hi Junio,
On Wed, 26 Apr 2017, Junio C Hamano wrote:
Show 13 quoted lines
> Johannes Schindelin <johannes.schindelin@gmx.de> writes:
> 
> > -check_todo_list
> > +git rebase--helper --check-todo-list || {
> > +	ret=$?
> > +	checkout_onto
> > +	exit $ret
> > +}
> 
> I find this a better division of labor between "check_todo_list" and
> its caller.  Compared to the original that did the "recover and exit
> with failure" inside the helper, this is much easier to see what is
> going on.

Yes. My first attempt did not even checkout <onto>, and it was surprisingly difficult to pin that one down. I would never have expected check_todo_list to have that side effect.

Show 37 quoted lines
> > +/*
> > + * Check if the user dropped some commits by mistake
> > + * Behaviour determined by rebase.missingCommitsCheck.
> > + * Check if there is an unrecognized command or a
> > + * bad SHA-1 in a command.
> > + */
> > +int check_todo_list(void)
> > +{
> > +	enum check_level check_level = get_missing_commit_check_level();
> > +	struct strbuf todo_file = STRBUF_INIT;
> > +	struct todo_list todo_list = TODO_LIST_INIT;
> > +	struct commit_list *missing = NULL;
> > +	int raise_error = 0, res = 0, fd, i;
> > +
> > +	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);
> > +		goto leave_check;
> > +	}
> > +	if (strbuf_read(&todo_list.buf, fd, 0) < 0) {
> > +		close(fd);
> > +		res = error(_("could not read '%s'."), todo_file.buf);
> > +		goto leave_check;
> > +	}
> > +	close(fd);
> > +	raise_error = res =
> > +		parse_insn_buffer(todo_list.buf.buf, &todo_list);
> > +
> > +	if (check_level == CHECK_IGNORE)
> > +		goto leave_check;
> 
> OK, so even it is set to ignore, unreadable todo list will be shown
> with a loud error message that tells the user to use --edit-todo.
> 
> What should happen when it is not set to ignore and we found the
> todo list unacceptable, I wonder?

Whoops. In case of a parse error, it does not make sense to check, does it. Fixed.

Show 10 quoted lines
> > +	/* Get the SHA-1 of the commits */
> > +	for (i = 0; i < todo_list.nr; i++) {
> > +		struct commit *commit = todo_list.items[i].commit;
> > +		if (commit)
> > +			commit->util = todo_list.items + i;
> > +	}
> 
> It does not look like this loop is "Get(ting) the SHA-1 of the commits"
> to me, though.  It is setting up ->util to be usable as a back-pointer
> into the list.

Right, and that is not even necessary. It is even incorrect, as we release the todo_list and read git-rebase-todo.backup into the same data structure, possibly reallocating the array, therefore the pointers may become stale. So I went with your suggestion further down to use (void *)1 instead.

Also, the comment is actively wrong, I agree. I changed it to
	/* Mark the commits in git-rebase-todo as seen */
> > +	todo_list_release(&todo_list);
> 
> But then the todo-list is released?  The util field we have set, if
> any, in the previous loop are now dangling, no?
Right.
Show 17 quoted lines
> > +	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);
> > +		goto leave_check;
> > +	}
> > +	if (strbuf_read(&todo_list.buf, fd, 0) < 0) {
> > +		close(fd);
> > +		res = error(_("could not read '%s'."), todo_file.buf);
> > +		goto leave_check;
> > +	}
> > +	close(fd);
> > +	strbuf_release(&todo_file);
> > +	res = !!parse_insn_buffer(todo_list.buf.buf, &todo_list);
> 
> Then we read from .backup; failure to do so does not result in the
> "you need to --edit-todo" warning.
Correct. At this point, we could even add
	if (res)
		die("BUG: cannot read '%s'", todo_file.buf);

(moving the strbuf_release(&todo_file) below, of course), as the .backup file is not intended to be edited by the user, i.e. it is the original todo which should *never* be unparseable.

Show 26 quoted lines
> > +	/* Find commits that are missing after editing */
> > +	for (i = 0; i < todo_list.nr; i++) {
> > +		struct commit *commit = todo_list.items[i].commit;
> > +		if (commit && !commit->util) {
> > +			commit_list_insert(commit, &missing);
> > +			commit->util = todo_list.items + i;
> > +		}
> > +	}
> 
> And we check the commits mentioned in the backup; any commit whose
> util is not marked in the previous loop is noticed and thrown into
> the missing list.
> 
> The loop we later have does "while (missing)" and does not look at
> commit->util for commits that are *not* missing, i.e. the ones that
> are marked in the previous loop, so it does not matter that their
> util field have dangling pointers.  In that sense, it may not be
> buggy, but it is misleading.  The only thing these two loops care
> about is that the commits found in the earlier loop get their util
> field set to non-NULL, so instead of using "todo_list.items+i",
> perhaps doing this
> 
> 	if (commit)
> 		commit->util = (void *)1; /* mark as seen */
> 
> in the earlier loop instead would be much less confusing.

... and doing the same in this loop. I agree, that's exactly what I changed it to.

Show 20 quoted lines
> > +	/* Warn about missing commits */
> > +	if (!missing)
> > +		goto leave_check;
> 
> If there is no missing one, we may still return error about
> unacceptable backup file.  But if we read backup fine and didn't
> find anything missing, we'll return silently and with success.  OK.
> 
> > +	if (check_level == CHECK_ERROR)
> > +		raise_error = res = 1;
> 
> Otherwise, we found missing ones and we want to report here.
> 
> The reason why I started reading this function aloud was because I
> found two variables (raise_error and res) somewhat confusing.  I
> think what the code does makes sense, but I still find the way how
> the code expresses the logic with these two variables confusing.
> Perhaps somebody else can hopefully offer possible improvements, as
> I do not offhand think of a way better than what is currently in
> this patch myself.

I renamed the `raise_error` variable to `advise_to_edit_todo`. The `res` does not need renaming, methinks, as it is used everywhere else in that file to indicate the return value.

Ciao, Dscho

Previous: Junio C HamanoNext: Johannes Schindelin
Message 59 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.