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

Re: [PATCH 09/22] sequencer: completely revamp the "todo" script parsing

From
Jakub Narębski <jnareb@gmail.com>
Date
Sep 1, 2016, 22:05 UTC
Message-ID
<d8112b27-8de3-0860-e902-fb271b80a0e7@gmail.com>
In-Reply-To
<alpine.DEB.2.20.1609010836010.129229@virtualbox>
Hello Johannes,
W dniu 01.09.2016 o 09:49, Johannes Schindelin pisze:
> On Wed, 31 Aug 2016, Jakub Narębski wrote: 
>> W dniu 29.08.2016 o 10:05, Johannes Schindelin pisze:
[...]
Show 14 quoted lines
>> Hmmm... commit_list is, as defined in commit.h, a linked list.
> 
> That is the most prominent reason why the rest is not a mindless
> conversion from commit_list to todo_list.
> 
> And we need todo_list as an array, because we need to be able to peek, or
> even move, backwards from the current command.
> 
>> Here todo_list uses growable array implementation of list.  Which
>> is I guess better on current CPU architecture, with slow memory,
>> limited-size caches, and adjacency prefetching.
> 
> That is not the reason that an array is used here. The array allows us
> much more flexibility.

It would be nice if this reasoning (behind the change from linked list to growable array) was mentioned in appropriate commit message, and perhaps also in the cover letter for the series. It is IMVHO quite important information (that you thought obvious).

> 
> One of the major performance improvements will come at the very end, for
> example: the reordering of the fixup!/squash! lines. And that would be a
> *major* pain to do if the todo_list were still a linked list.

Actually deletion from and insertion into single linked list are not that hard, and O(1) after finding place, O(N) with finding included. Moving elements in array is O(N),... and arguably a bit simpler - but at high level, with appropriate primitives, they are about the same.

Yes, array is easier for permutation and reordering.
Show 15 quoted lines
>>> +struct todo_item *append_todo(struct todo_list *todo_list)
>>
>> Errr... I don't quite understand the name of this function.
>> What are you appending here to the todo_list?
> 
> A new item.
> 
>> Compare string_list_append() and string_list_append_nodup(),
>> where the second parameter is item to append.
> 
> Yes, that is correct. In the case of a todo_item, things are a lot more
> complicated, though. Some of the values have to be determined tediously
> (such as the offset and length of the oneline after the "pick <oid>"
> command). I just put those values directly into the newly allocated item,
> is all.

I would expect sth_append command to take a list (or other collection), an element, and return [modified] collection with the new element added. Such API would require temporary variable in caller and memcopy in the sth_append() function.

This is not it. It creates a new element, expanding a list (a collection), and then expose this element. Which spares us memcopy... on non-critical path.

I don't know how to name operation "grow list and return new element".
But "append" it is not.
 
Show 12 quoted lines
>>> +	ALLOC_GROW(todo_list->items, todo_list->nr + 1, todo_list->alloc);
>>> +	return todo_list->items + todo_list->nr++;
>>>  }
>>>  
>>> -static struct commit *parse_insn_line(char *bol, char *eol, struct replay_opts *opts)
>>> +static int parse_insn_line(struct todo_item *item, const char *bol, char *eol)
>>
>> Why the change of return type?  
> 
> Because it makes no sense to return a commit here because not all commands
> are about commits (think rebase -i's `exec`). It makes tons of sense to
> return an error condition, though.
All right.

I have not checked / not remember what caller of parse_insn_line() used it's return value for. I guess that we save it into todo_item, moving that operation from caller to callee.

Show 15 quoted lines
>> Why now struct todo_item is first when struct replay_opts was last?
> 
> Those play very, very different roles.
> 
> The opts parameter used to provide parse_insn_line() with enough
> information to complain loudly when the overall command was not identical
> to the parsed command.
> 
> The item parameter is a receptacle for the parsed data. It will contain
> the pointer to the commit that was previously returned, if any. But it
> will also contain much more information, such as the command, the oneline,
> the offset in the buffer, etc etc
> 
> So "opts" was an "in" parameter while "item" is an "out" one. Apples and
> oranges.

All right. Good explanation. And the one that is too low-level detail to put in the commit message, I think.

Show 7 quoted lines
>>> -	end_of_object_name = bol + strcspn(bol, " \t\n");
>>> +	end_of_object_name = (char *) bol + strcspn(bol, " \t\n");
>>
>> Why is this cast needed?
> 
> Because bol is a "const char *" and we need to put "NUL" temporarily to
> *end_of_object_name:
Would compiler complain without this const'ness-stripping cast?
Show 12 quoted lines
> 
>>>  	saved = *end_of_object_name;
>>>  	*end_of_object_name = '\0';
>>>  	status = get_sha1(bol, commit_sha1);
>>>  	*end_of_object_name = saved;
> 
> Technically, this would have made a fine excuse to teach get_sha1() a mode
> where it expects a length parameter instead of relying on a NUL-terminated
> string.
> 
> Practically, such fine excuses cost me months in this rebase--helper
> project already, and I need to protect my time better.
Put it in TODO list (and perhaps add a TODO comment) ;-).

BTW. open-source produces better software, and development bandwidth is good, but the latency :-((((

Show 18 quoted lines
> 
>>> -	/*
>>> -	 * Verify that the action matches up with the one in
>>> -	 * opts; we don't support arbitrary instructions
>>> -	 */
>>> -	if (action != opts->action) {
>>> -		if (action == REPLAY_REVERT)
>>> -		      error((opts->action == REPLAY_REVERT)
>>> -			    ? _("Cannot revert during another revert.")
>>
>> Errr... could the above ever happen?  Namely
>>
>>   action != opts->action && action == REPLAY_REVERT && opts->action == REPLAY_REVERT
>>
>> Surely not.
> 
> Your reply pointed to the very circumstance when this may happen: `git
> cherry-pick --continue` after an interrupted `git revert`.

I was talking about "Cannot revert during another revert." and "Cannot cherry-pick during another cherry-pick." errors, which can never happen because of the outermost if.

   x == A && y == A && x != Y
can never happen, because equality is transitive^*
   x == A && y == A  =>  x == y
*) except NaN (NaN != NaN), but we don't deal with floating point here.

From those error messages it looks like they were originally intended to prevent from starting another revert or cherry-pick if sequencer based operation is already in progress (to not stomp on the latter internal state). But for that it would need to examine the opts->subcommand if it is REPLAY_NONE (or equivalent), check that sequencer file already exists, and read it to fond which operation is in progress.

This is about checking that command in todo-list agrees with the git command used (we probably checked that it is --continue, or maybe --skip). But the error message does not spell that; it is misleading.

[Nb. git-blame shows Vasco Almeida as author of those lines]
> 
> But then, I remove that code here, so I should not try to defend it.
> 

But that was / is another reason for removing code: it is slightly wrong.

Show 17 quoted lines
>>> -			    : _("Cannot revert during a cherry-pick."));
>>> -		else
>>> -		      error((opts->action == REPLAY_REVERT)
>>> -			    ? _("Cannot cherry-pick during a revert.")
>>> -			    : _("Cannot cherry-pick during another cherry-pick."));
>>> -		return NULL;
>>> -	}
>>
>> Anyway, while it is / would be a good idea to prevent starting any
>> sequencer-based command (cherry-pick, revert, soon rebase -i) when
>> other command is in progress (cherry-pick, revert, soon rebase -i).
>> That is, if cherry-pick / revert waits for user action, you cannot
>> run another cherry-pick or revert.
>>
>> Which I guess the above code was not about...
> 
> It was about that, though.
No it was not, see the reasoning above.
Show 6 quoted lines
> 
> It went about it in a pretty round-about way: opts->action comes from the
> name of the command ("was I called as `git revert` or `git cherry-pick`?")
> and action comes from the todo script, which was assumed to be written by
> a previous run of the sequencer, using the then-current value of
> opts->action.

It did different check, that we continue with the same command as we began with.

Show 11 quoted lines
> 
> So it wrote that command into *every single line* of the todo script, *for
> the sole purpose* of verifying that it was the same action when running
> via --continue.
> 
> As I said earlier, I would not complain at all if an interrupted `git
> revert` could be continued via `git cherry-pick --continue`.
> 
> If that is not desirable, I can reintroduce that overzealous check, but
> that will have to wait until after v2.10.0. And it would require an
> argument that convinces me.

One argument is that you can add options to --continue, and among options for cherry-pick, revert and rebase -i, there are options that apply only to some of them. So we need at least decide what to do if we started rebase, and try to continue with cherry-pick: do we accept rebase-only options? What we do with cherry-pick-only options, that rebase does not understand?

It is easier to just check that revert is continued with revert (by checking command in todo file), cherry-pick with cherry-pick (same), rebase -i with rebase (by checking another file), and am with am.

Show 16 quoted lines
> 
>>> +		item = append_todo(todo_list);
>>
>> A better name, in my personal option, would be
>>
>>   +		item = todo_list_next(todo_list);
>>
>> Or todo_next(todo_list).
> 
> That sounds more like a function that performs the next command in the
> todo_list.
> 
> While I agree that naming is hard, I still think that `append_todo()` with
> the todo_list as single parameter and returning a todo_item is pretty much
> self-explanatory: it appends a new item to the todo_list and returns a
> pointer to it.

It creates new item in the todo_list at the end, or it grows todo_list, but the function does not append anything...

[...]
Show 9 quoted lines
>>> -	if (strbuf_read(&buf, fd, 0) < 0) {
>>> +	if (strbuf_read(&todo_list->buf, fd, 0) < 0) {
>>>  		close(fd);
>>> -		strbuf_release(&buf);
>>
>> A question: when is todo_list->buf released?
> 
> Why, I am glad you asked! It is released in todo_list_release(), called at
> the end e.g. of sequencer_continue().
All right.  I could have guessed that.
Show 29 quoted lines
>>> -static int walk_revs_populate_todo(struct commit_list **todo_list,
>>> +static int walk_revs_populate_todo(struct todo_list *todo_list,
>>>  				struct replay_opts *opts)
>>>  {
>>> +	enum todo_command command = opts->action == REPLAY_PICK ?
>>> +		TODO_PICK : TODO_REVERT;
>>>  	struct commit *commit;
>>> -	struct commit_list **next;
>>>  
>>>  	if (prepare_revs(opts))
>>>  		return -1;
>>>  
>>> -	next = todo_list;
>>> -	while ((commit = get_revision(opts->revs)))
>>> -		next = commit_list_append(commit, next);
>>> +	while ((commit = get_revision(opts->revs))) {
>>> +		struct todo_item *item = append_todo(todo_list);
>>> +		const char *commit_buffer = get_commit_buffer(commit, NULL);
>>
>> I see that you are creating todo file contents while walking revision list,
>> something that was left for later in current / previous implementation
>> of the sequencer...
> 
> Not really. This function was always about generating a todo_list. It just
> did not format it yet.
> 
> With the change of keeping the original formatting of the todo script
> instead of re-formatting it in save_todo(), this function now has to
> format the todo_list itself.

So the commit parsing was moved from save_todo(), which contrary to the name also re-generated todo list, to walk_revs_populate_todo(). I guess it is the same callchain.

Additional question, answer to which should address Junio's complaint about early/eager commit parsing (if I understand it correctly): do information from parsing commit is needed for creating a new commit, i.e. doing a pick or revert? If not, then perhaps parsing only those commits that are left, at the time of saving todo file (with probably less commit that what we have started with), would be better?

[...]
Show 21 quoted lines
>>> -static int save_todo(struct commit_list *todo_list, struct replay_opts *opts)
>>> +static int save_todo(struct todo_list *todo_list, struct replay_opts *opts)
>>>  {
>>>  	static struct lock_file todo_lock;
>>> -	struct strbuf buf = STRBUF_INIT;
>>> -	int fd;
>>> +	const char *todo_path = get_todo_path(opts);
>>> +	int next = todo_list->current, offset, fd;
>>
>> The "next = todo_list->current" looks a bit strange.
> 
> Depending whether we need rebase -i processing or revert/cherry-pick's
> slightly different one, the "current" position points to the next one
> already...
> 
>> Also, we do not change todo_list->current, we use it in one place, so it
>> can be used directly without help of temporary / helper variable.  But
>> that is just my personal opinion.
> 
> No, it has nothing to do with opinion. It prepares the code to keep it
> readable even when REPLAY_INTERACTIVE_REBASE is introduced.
Ah, all right.
[...]
Show 6 quoted lines
>> and this should be done in one of earlier patches, isn't it?
> 
> No. I deliberately skipped save_todo() from "future-proofing" as I planned
> to rewrite it anyway. There is no point in future-proofing something you
> are going to toss in a minute.
> 

All right. Though I wonder if it should not be mentioned in the commit message of said previous patch (though I have missed that not all sites were "future-proofed" in review; I'm sorry).

Show 32 quoted lines
>>> -	if (commit_lock_file(&todo_lock) < 0) {
>>> -		strbuf_release(&buf);
>>> -		return error(_("Error wrapping up %s."), git_path_todo_file());
>>> -	}
>>> -	strbuf_release(&buf);
>>> +	if (commit_lock_file(&todo_lock) < 0)
>>> +		return error(_("Error wrapping up %s."), todo_path);
>>
>> Note: this is unrelated change, but we usually put paths in quotes, like this
>>
>>   +		return error(_("Error wrapping up '%s'."), todo_path);
>>
>> (in this and earlier error message), so that paths containing spaces show
>> correctly and readably to the user.  Though this possibly is not a problem
>> for this path.
> 
> Right.
> 
>> Also, how user is to understand "wrapping up"?
> 
> The same as before: the removed lines already had the error message,
> missing the quotes, too.
> 
> Don't get me wrong: I am a big fan of consistency, and I wish that Git's
> source code had more of it. So I would love to see a patch series that
> makes all error messages consistently reporting paths enclosed in single
> quotes.
> 
> I am also a big fan of the separation of concerns, though. And this patch
> series' concern is consistency *with the existing code*.
> 
> So I won't change the error message that I inherited at this point.
All right, I can understand that.  But I think it won't cost
much to do _while at it_ adding of quotes around pathnames in
error messages, where you notice this problem.
 
Show 13 quoted lines
>>>  static int single_pick(struct commit *cmit, struct replay_opts *opts)
>>>  {
>>>  	setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
>>> -	return do_pick_commit(cmit, opts);
>>> +	return do_pick_commit(opts->action == REPLAY_PICK ?
>>> +		TODO_PICK : TODO_REVERT, cmit, opts);
>>
>> The ternary conditional operator here translates one enum to other enum,
>> isn't it?
> 
> Well, almost. Please note that the enum will receive a new value in the
> sequencer-i patch series. And there is no equivalent todo_command for
> REPLAY_INTERACTIVE_REBASE.

All right. And casting one enum to other, relying on the same order, is tricky to the extreme and brittle.

> 
> Thanks for the review!
You are welcome.
Best,
-- 
Jakub Narębski
Previous: Johannes SchindelinNext: Johannes Schindelin
Message 50 of 352 in “Prepare the sequencer for the upcoming rebase -i patches”
  1. 00/22 Prepare the sequencer for the upcoming rebase -i patchesJohannes Schindelin, Aug 29, 2016
  2. 02/22 sequencer: use memoized sequencer directory pathJohannes Schindelin, Aug 29, 2016
  3. Jakub NarębskiAug 29, 2016
  4. Johannes SchindelinAug 29, 2016
  5. 01/22 sequencer: use static initializers for replay_optsJohannes Schindelin, Aug 29, 2016
  6. Dennis KaarsemakerAug 29, 2016
  7. Johannes SchindelinAug 29, 2016
  8. Jakub NarębskiAug 29, 2016
  9. Johannes SchindelinAug 29, 2016
  10. 03/22 sequencer: avoid unnecessary indirectionJohannes Schindelin, Aug 29, 2016
  11. Jakub NarębskiAug 29, 2016
  12. Johannes SchindelinAug 29, 2016
  13. 04/22 sequencer: future-proof remove_sequencer_state()Johannes Schindelin, Aug 29, 2016
  14. Dennis KaarsemakerAug 29, 2016
  15. Johannes SchindelinAug 29, 2016
  16. Johannes SchindelinAug 29, 2016
  17. 05/22 sequencer: allow the sequencer to take custody of malloc()ed dataJohannes Schindelin, Aug 29, 2016
  18. Jakub NarębskiAug 29, 2016
  19. Johannes SixtAug 30, 2016
  20. Johannes SchindelinAug 30, 2016
  21. Johannes SchindelinAug 30, 2016
  22. Jakub NarębskiAug 30, 2016
  23. Junio C HamanoAug 30, 2016
  24. Johannes SchindelinAug 31, 2016
  25. 06/22 sequencer: release memory that was allocated when reading optionsJohannes Schindelin, Aug 29, 2016
  26. Jakub NarębskiAug 30, 2016
  27. Johannes SchindelinAug 30, 2016
  28. Johannes SixtAug 30, 2016
  29. Junio C HamanoAug 30, 2016
  30. Jakub NarębskiAug 30, 2016
  31. Junio C HamanoAug 30, 2016
  32. Johannes SchindelinAug 31, 2016
  33. 07/22 sequencer: future-proof read_populate_todo()Johannes Schindelin, Aug 29, 2016
  34. Jakub NarębskiAug 30, 2016
  35. Johannes SchindelinAug 30, 2016
  36. 08/22 sequencer: remove overzealous assumptionJohannes Schindelin, Aug 29, 2016
  37. Jakub NarębskiAug 31, 2016
  38. Johannes SchindelinAug 31, 2016
  39. Jakub NarębskiAug 31, 2016
  40. Johannes SchindelinSep 1, 2016
  41. Jakub NarębskiSep 1, 2016
  42. Junio C HamanoAug 31, 2016
  43. Johannes SchindelinSep 1, 2016
  44. 09/22 sequencer: completely revamp the "todo" script parsingJohannes Schindelin, Aug 29, 2016
  45. Jakub NarębskiAug 31, 2016
  46. Stefan BellerAug 31, 2016
  47. Johannes SchindelinSep 1, 2016
  48. Junio C HamanoSep 1, 2016
  49. Johannes SchindelinSep 1, 2016
  50. Jakub NarębskiSep 1, 2016
  51. Johannes SchindelinSep 9, 2016
  52. 10/22 sequencer: avoid completely different messages for different actionsJohannes Schindelin, Aug 29, 2016
  53. Jakub NarębskiAug 31, 2016
  54. Johannes SchindelinSep 1, 2016
  55. Jakub NarębskiSep 1, 2016
  56. Johannes SchindelinSep 9, 2016
  57. 13/22 sequencer: remember the onelines when parsing the todo fileJohannes Schindelin, Aug 29, 2016
  58. Jakub NarębskiAug 31, 2016
  59. Junio C HamanoAug 31, 2016
  60. Jakub NarębskiAug 31, 2016
  61. Junio C HamanoAug 31, 2016
  62. Johannes SchindelinSep 1, 2016
  63. Johannes SchindelinSep 1, 2016
  64. Jakub NarębskiSep 1, 2016
  65. Johannes SchindelinSep 1, 2016
  66. Junio C HamanoSep 1, 2016
  67. Johannes SchindelinSep 9, 2016
  68. Jakub NarębskiSep 9, 2016
  69. Git garden shears, was Re: [PATCH 13/22] sequencer: remember the onelines when parsing the todo fileJohannes Schindelin, Sep 11, 2016
  70. Jakub NarębskiSep 21, 2016
  71. Johannes SchindelinSep 25, 2016
  72. Jakub NarębskiSep 1, 2016
  73. Junio C HamanoSep 1, 2016
  74. Johannes SchindelinSep 9, 2016
  75. Johannes SchindelinSep 1, 2016
  76. 14/22 sequencer: prepare for rebase -i's commit functionalityJohannes Schindelin, Aug 29, 2016
  77. Junio C HamanoAug 29, 2016
  78. Johannes SchindelinAug 30, 2016
  79. Junio C HamanoAug 30, 2016
  80. Johannes SchindelinAug 30, 2016
  81. Junio C HamanoAug 30, 2016
  82. Johannes SchindelinAug 31, 2016
  83. 16/22 sequencer: prepare for rebase -i's GPG settingsJohannes Schindelin, Aug 29, 2016
  84. Jakub NarębskiAug 31, 2016
  85. Junio C HamanoAug 31, 2016
  86. Jakub NarębskiAug 31, 2016
  87. Junio C HamanoAug 31, 2016
  88. Johannes SchindelinSep 1, 2016
  89. Johannes SchindelinSep 1, 2016
  90. Johannes SchindelinSep 1, 2016
  91. Jakub NarębskiSep 1, 2016
  92. 15/22 sequencer: introduce a helper to read files written by scriptsJohannes Schindelin, Aug 29, 2016
  93. Dennis KaarsemakerAug 29, 2016
  94. Johannes SchindelinAug 29, 2016
  95. 17/22 sequencer: allow editing the commit message on a case-by-case basisJohannes Schindelin, Aug 29, 2016
  96. Jakub NarębskiAug 31, 2016
  97. Johannes SchindelinSep 1, 2016
  98. 18/22 sequencer: support amending commitsJohannes Schindelin, Aug 29, 2016
  99. Jakub NarębskiAug 31, 2016
  100. Johannes SchindelinSep 1, 2016
  101. 19/22 sequencer: support cleaning up commit messagesJohannes Schindelin, Aug 29, 2016
  102. Jakub NarębskiSep 1, 2016
  103. Johannes SchindelinSep 1, 2016
  104. Jakub NarębskiSep 1, 2016
  105. 20/22 sequencer: remember do_recursive_merge()'s return valueJohannes Schindelin, Aug 29, 2016
  106. Dennis KaarsemakerAug 29, 2016
  107. Johannes SchindelinAug 29, 2016
  108. Jakub NarębskiAug 29, 2016
  109. Junio C HamanoAug 29, 2016
  110. 12/22 sequencer: refactor the code to obtain a short commit nameJohannes Schindelin, Aug 29, 2016
  111. Dennis KaarsemakerAug 29, 2016
  112. Johannes SchindelinAug 29, 2016
  113. 22/22 sequencer: refactor write_message()Johannes Schindelin, Aug 29, 2016
  114. Jakub NarębskiSep 1, 2016
  115. Johannes SchindelinSep 1, 2016
  116. Jakub NarębskiSep 1, 2016
  117. Johannes SchindelinSep 9, 2016
  118. Jakub NarębskiSep 9, 2016
  119. Johannes SchindelinSep 11, 2016
  120. 21/22 sequencer: left-trim the lines read from the scriptJohannes Schindelin, Aug 29, 2016
  121. Jakub NarębskiSep 1, 2016
  122. Johannes SchindelinSep 1, 2016
  123. Junio C HamanoSep 1, 2016
  124. Johannes SchindelinSep 9, 2016
  125. Jakub NarębskiSep 1, 2016
  126. Johannes SchindelinSep 9, 2016
  127. 11/22 sequencer: get rid of the subcommand fieldJohannes Schindelin, Aug 29, 2016
  128. Jakub NarębskiAug 31, 2016
  129. Johannes SchindelinSep 1, 2016
  130. Dennis KaarsemakerAug 29, 2016
  131. Johannes SchindelinAug 29, 2016
  132. Jakub NarębskiSep 2, 2016
  133. Johannes SchindelinSep 2, 2016
  134. 00/25 Prepare the sequencer for the upcoming rebase -i patchesJohannes Schindelin, Sep 11, 2016
  135. 01/25 sequencer: use static initializers for replay_optsJohannes Schindelin, Sep 11, 2016
  136. Junio C HamanoSep 12, 2016
  137. 02/25 sequencer: use memoized sequencer directory pathJohannes Schindelin, Sep 11, 2016
  138. Junio C HamanoSep 12, 2016
  139. 03/25 sequencer: avoid unnecessary indirectionJohannes Schindelin, Sep 11, 2016
  140. Junio C HamanoSep 12, 2016
  141. 05/25 sequencer: allow the sequencer to take custody of malloc()ed dataJohannes Schindelin, Sep 11, 2016
  142. Junio C HamanoSep 12, 2016
  143. Johannes SchindelinOct 5, 2016
  144. Junio C HamanoOct 6, 2016
  145. Jakub NarębskiOct 6, 2016
  146. Junio C HamanoOct 6, 2016
  147. Johannes SchindelinOct 8, 2016
  148. 04/25 sequencer: future-proof remove_sequencer_state()Johannes Schindelin, Sep 11, 2016
  149. Junio C HamanoSep 12, 2016
  150. Johannes SchindelinOct 5, 2016
  151. Junio C HamanoOct 5, 2016
  152. 06/25 sequencer: release memory that was allocated when reading optionsJohannes Schindelin, Sep 11, 2016
  153. 07/25 sequencer: future-proof read_populate_todo()Johannes Schindelin, Sep 11, 2016
  154. 08/25 sequencer: completely revamp the "todo" script parsingJohannes Schindelin, Sep 11, 2016
  155. 09/25 sequencer: avoid completely different messages for different actionsJohannes Schindelin, Sep 11, 2016
  156. 10/25 sequencer: get rid of the subcommand fieldJohannes Schindelin, Sep 11, 2016
  157. Junio C HamanoSep 15, 2016
  158. 11/25 sequencer: refactor the code to obtain a short commit nameJohannes Schindelin, Sep 11, 2016
  159. 12/25 sequencer: remember the onelines when parsing the todo fileJohannes Schindelin, Sep 11, 2016
  160. 13/25 sequencer: prepare for rebase -i's commit functionalityJohannes Schindelin, Sep 11, 2016
  161. 14/25 sequencer: introduce a helper to read files written by scriptsJohannes Schindelin, Sep 11, 2016
  162. 15/25 sequencer: prepare for rebase -i's GPG settingsJohannes Schindelin, Sep 11, 2016
  163. 16/25 sequencer: allow editing the commit message on a case-by-case basisJohannes Schindelin, Sep 11, 2016
  164. 17/25 sequencer: support amending commitsJohannes Schindelin, Sep 11, 2016
  165. Junio C HamanoSep 12, 2016
  166. Johannes SchindelinOct 5, 2016
  167. 18/25 sequencer: support cleaning up commit messagesJohannes Schindelin, Sep 11, 2016
  168. Junio C HamanoSep 12, 2016
  169. 19/25 sequencer: remember do_recursive_merge()'s return valueJohannes Schindelin, Sep 11, 2016
  170. Junio C HamanoSep 12, 2016
  171. Johannes SchindelinOct 5, 2016
  172. Junio C HamanoOct 5, 2016
  173. 20/25 sequencer: left-trim lines read from the scriptJohannes Schindelin, Sep 11, 2016
  174. Junio C HamanoSep 11, 2016
  175. Johannes SchindelinSep 12, 2016
  176. Junio C HamanoSep 12, 2016
  177. Johannes SchindelinOct 6, 2016
  178. Johannes SixtOct 6, 2016
  179. Junio C HamanoOct 6, 2016
  180. Johannes SchindelinOct 9, 2016
  181. Johannes SixtOct 9, 2016
  182. 21/25 sequencer: refactor write_message()Johannes Schindelin, Sep 11, 2016
  183. Junio C HamanoSep 11, 2016
  184. Johannes SixtSep 12, 2016
  185. Junio C HamanoSep 15, 2016
  186. Johannes SchindelinOct 5, 2016
  187. 22/25 sequencer: remove overzealous assumption in rebase -i modeJohannes Schindelin, Sep 11, 2016
  188. Junio C HamanoSep 11, 2016
  189. 23/25 sequencer: mark action_name() for translationJohannes Schindelin, Sep 11, 2016
  190. 24/25 sequencer: quote filenames in error messagesJohannes Schindelin, Sep 11, 2016
  191. Junio C HamanoSep 11, 2016
  192. Johannes SchindelinOct 6, 2016
  193. 25/25 sequencer: remove bogus hint for translatorsJohannes Schindelin, Sep 11, 2016
  194. Junio C HamanoSep 11, 2016
  195. Johannes SchindelinOct 6, 2016
  196. 00/25 Prepare the sequencer for the upcoming rebase -i patchesJohannes Schindelin, Oct 10, 2016
  197. 01/25 sequencer: use static initializers for replay_optsJohannes Schindelin, Oct 10, 2016
  198. Junio C HamanoOct 10, 2016
  199. 02/25 sequencer: use memoized sequencer directory pathJohannes Schindelin, Oct 10, 2016
  200. 04/25 sequencer: future-proof remove_sequencer_state()Johannes Schindelin, Oct 10, 2016
  201. 03/25 sequencer: avoid unnecessary indirectionJohannes Schindelin, Oct 10, 2016
  202. Junio C HamanoOct 10, 2016
  203. 05/25 sequencer: eventually release memory allocated for the option valuesJohannes Schindelin, Oct 10, 2016
  204. Junio C HamanoOct 10, 2016
  205. Johannes SchindelinOct 11, 2016
  206. Junio C HamanoOct 11, 2016
  207. Johannes SchindelinOct 12, 2016
  208. Re* [PATCH v3 05/25] sequencer: eventually release memory allocated for the option valuesJunio C Hamano, Oct 12, 2016
  209. Johannes SchindelinOct 13, 2016
  210. 07/25 sequencer: completely revamp the "todo" script parsingJohannes Schindelin, Oct 10, 2016
  211. Junio C HamanoOct 10, 2016
  212. Johannes SchindelinOct 11, 2016
  213. Johannes SchindelinOct 11, 2016
  214. Johannes SchindelinOct 11, 2016
  215. Junio C HamanoOct 11, 2016
  216. Junio C HamanoOct 11, 2016
  217. Torsten BögershausenOct 15, 2016
  218. Jeff KingOct 15, 2016
  219. Torsten BögershausenOct 15, 2016
  220. Jeff KingOct 15, 2016
  221. Johannes SchindelinOct 16, 2016
  222. Jeff KingOct 16, 2016
  223. Johannes SchindelinOct 17, 2016
  224. Jeff KingOct 17, 2016
  225. 06/25 sequencer: future-proof read_populate_todo()Johannes Schindelin, Oct 10, 2016
  226. 08/25 sequencer: strip CR from the todo scriptJohannes Schindelin, Oct 10, 2016
  227. Junio C HamanoOct 11, 2016
  228. Johannes SchindelinOct 12, 2016
  229. 11/25 sequencer: refactor the code to obtain a short commit nameJohannes Schindelin, Oct 10, 2016
  230. 09/25 sequencer: avoid completely different messages for different actionsJohannes Schindelin, Oct 10, 2016
  231. 12/25 sequencer: remember the onelines when parsing the todo fileJohannes Schindelin, Oct 10, 2016
  232. Junio C HamanoOct 11, 2016
  233. Johannes SchindelinOct 12, 2016
  234. Junio C HamanoOct 12, 2016
  235. Johannes SchindelinOct 13, 2016
  236. 14/25 sequencer: introduce a helper to read files written by scriptsJohannes Schindelin, Oct 10, 2016
  237. Junio C HamanoOct 17, 2016
  238. Johannes SchindelinOct 18, 2016
  239. Junio C HamanoOct 18, 2016
  240. Johannes SchindelinOct 20, 2016
  241. 13/25 sequencer: prepare for rebase -i's commit functionalityJohannes Schindelin, Oct 10, 2016
  242. Junio C HamanoOct 11, 2016
  243. Johannes SchindelinOct 12, 2016
  244. Junio C HamanoOct 12, 2016
  245. Johannes SchindelinOct 13, 2016
  246. Junio C HamanoOct 14, 2016
  247. 15/25 sequencer: allow editing the commit message on a case-by-case basisJohannes Schindelin, Oct 10, 2016
  248. Junio C HamanoOct 17, 2016
  249. 10/25 sequencer: get rid of the subcommand fieldJohannes Schindelin, Oct 10, 2016
  250. 17/25 sequencer: support cleaning up commit messagesJohannes Schindelin, Oct 10, 2016
  251. 18/25 sequencer: do not try to commit when there were merge conflictsJohannes Schindelin, Oct 10, 2016
  252. 16/25 sequencer: support amending commitsJohannes Schindelin, Oct 10, 2016
  253. Junio C HamanoOct 17, 2016
  254. Johannes SchindelinOct 18, 2016
  255. Junio C HamanoOct 18, 2016
  256. 19/25 sequencer: left-trim lines read from the scriptJohannes Schindelin, Oct 10, 2016
  257. 20/25 sequencer: refactor write_message()Johannes Schindelin, Oct 10, 2016
  258. 23/25 sequencer: quote filenames in error messagesJohannes Schindelin, Oct 10, 2016
  259. 24/25 sequencer: start error messages consistently with lower caseJohannes Schindelin, Oct 10, 2016
  260. 25/25 sequencer: mark all error messages for translationJohannes Schindelin, Oct 10, 2016
  261. Johannes SixtOct 12, 2016
  262. Junio C HamanoOct 12, 2016
  263. Johannes SchindelinOct 13, 2016
  264. Johannes SixtOct 13, 2016
  265. 22/25 sequencer: mark action_name() for translationJohannes Schindelin, Oct 10, 2016
  266. 21/25 sequencer: remove overzealous assumption in rebase -i modeJohannes Schindelin, Oct 10, 2016
  267. 00/25 Prepare the sequencer for the upcoming rebase -i patchesJohannes Schindelin, Oct 14, 2016
  268. 18/25 sequencer: do not try to commit when there were merge conflictsJohannes Schindelin, Oct 14, 2016
  269. Junio C HamanoOct 20, 2016
  270. Johannes SchindelinOct 21, 2016
  271. 17/25 sequencer: support cleaning up commit messagesJohannes Schindelin, Oct 14, 2016
  272. Junio C HamanoOct 20, 2016
  273. 16/25 sequencer: support amending commitsJohannes Schindelin, Oct 14, 2016
  274. 19/25 sequencer: left-trim lines read from the scriptJohannes Schindelin, Oct 14, 2016
  275. 14/25 sequencer: introduce a helper to read files written by scriptsJohannes Schindelin, Oct 14, 2016
  276. 12/25 sequencer: remember the onelines when parsing the todo fileJohannes Schindelin, Oct 14, 2016
  277. 15/25 sequencer: allow editing the commit message on a case-by-case basisJohannes Schindelin, Oct 14, 2016
  278. 11/25 sequencer: get rid of the subcommand fieldJohannes Schindelin, Oct 14, 2016
  279. 13/25 sequencer: prepare for rebase -i's commit functionalityJohannes Schindelin, Oct 14, 2016
  280. 20/25 sequencer: refactor write_message()Johannes Schindelin, Oct 14, 2016
  281. Junio C HamanoOct 20, 2016
  282. Junio C HamanoOct 20, 2016
  283. Johannes SchindelinOct 21, 2016
  284. Junio C HamanoOct 21, 2016
  285. Johannes SchindelinOct 23, 2016
  286. 24/25 sequencer: start error messages consistently with lower caseJohannes Schindelin, Oct 14, 2016
  287. 22/25 sequencer: mark action_name() for translationJohannes Schindelin, Oct 14, 2016
  288. 25/25 sequencer: mark all error messages for translationJohannes Schindelin, Oct 14, 2016
  289. 23/25 sequencer: quote filenames in error messagesJohannes Schindelin, Oct 14, 2016
  290. Junio C HamanoOct 20, 2016
  291. Junio C HamanoOct 20, 2016
  292. 21/25 sequencer: remove overzealous assumption in rebase -i modeJohannes Schindelin, Oct 14, 2016
  293. 08/25 sequencer: completely revamp the "todo" script parsingJohannes Schindelin, Oct 14, 2016
  294. Junio C HamanoOct 17, 2016
  295. Johannes SchindelinOct 18, 2016
  296. 09/25 sequencer: strip CR from the todo scriptJohannes Schindelin, Oct 14, 2016
  297. 03/25 sequencer: avoid unnecessary indirectionJohannes Schindelin, Oct 14, 2016
  298. 05/25 sequencer: eventually release memory allocated for the option valuesJohannes Schindelin, Oct 14, 2016
  299. Junio C HamanoOct 17, 2016
  300. Johannes SchindelinOct 18, 2016
  301. Junio C HamanoOct 19, 2016
  302. Johannes SchindelinOct 20, 2016
  303. 04/25 sequencer: future-proof remove_sequencer_state()Johannes Schindelin, Oct 14, 2016
  304. 07/25 sequencer: refactor the code to obtain a short commit nameJohannes Schindelin, Oct 14, 2016
  305. 02/25 sequencer: use memoized sequencer directory pathJohannes Schindelin, Oct 14, 2016
  306. 10/25 sequencer: avoid completely different messages for different actionsJohannes Schindelin, Oct 14, 2016
  307. 06/25 sequencer: future-proof read_populate_todo()Johannes Schindelin, Oct 14, 2016
  308. 01/25 sequencer: use static initializers for replay_optsJohannes Schindelin, Oct 14, 2016
  309. Junio C HamanoOct 17, 2016
  310. 00/27 Prepare the sequencer for the upcoming rebase -i patchesJohannes Schindelin, Oct 21, 2016
  311. 02/27 sequencer: use memoized sequencer directory pathJohannes Schindelin, Oct 21, 2016
  312. 01/27 sequencer: use static initializers for replay_optsJohannes Schindelin, Oct 21, 2016
  313. 04/27 sequencer: future-proof remove_sequencer_state()Johannes Schindelin, Oct 21, 2016
  314. 03/27 sequencer: avoid unnecessary indirectionJohannes Schindelin, Oct 21, 2016
  315. 05/27 sequencer: plug memory leaks for the option valuesJohannes Schindelin, Oct 21, 2016
  316. 06/27 sequencer: future-proof read_populate_todo()Johannes Schindelin, Oct 21, 2016
  317. 08/27 sequencer: completely revamp the "todo" script parsingJohannes Schindelin, Oct 21, 2016
  318. Lars SchneiderNov 6, 2016
  319. 09/27 sequencer: strip CR from the todo scriptJohannes Schindelin, Oct 21, 2016
  320. 07/27 sequencer: refactor the code to obtain a short commit nameJohannes Schindelin, Oct 21, 2016
  321. 11/27 sequencer: get rid of the subcommand fieldJohannes Schindelin, Oct 21, 2016
  322. 12/27 sequencer: remember the onelines when parsing the todo fileJohannes Schindelin, Oct 21, 2016
  323. 13/27 sequencer: prepare for rebase -i's commit functionalityJohannes Schindelin, Oct 21, 2016
  324. 10/27 sequencer: avoid completely different messages for different actionsJohannes Schindelin, Oct 21, 2016
  325. 15/27 sequencer: allow editing the commit message on a case-by-case basisJohannes Schindelin, Oct 21, 2016
  326. 14/27 sequencer: introduce a helper to read files written by scriptsJohannes Schindelin, Oct 21, 2016
  327. 16/27 sequencer: support amending commitsJohannes Schindelin, Oct 21, 2016
  328. 17/27 sequencer: support cleaning up commit messagesJohannes Schindelin, Oct 21, 2016
  329. 18/27 sequencer: left-trim lines read from the scriptJohannes Schindelin, Oct 21, 2016
  330. 21/27 sequencer: refactor write_message() to take a pointer/lengthJohannes Schindelin, Oct 21, 2016
  331. 19/27 sequencer: stop releasing the strbuf in write_message()Johannes Schindelin, Oct 21, 2016
  332. Junio C HamanoOct 21, 2016
  333. 23/27 sequencer: remove overzealous assumption in rebase -i modeJohannes Schindelin, Oct 21, 2016
  334. 25/27 sequencer: quote filenames in error messagesJohannes Schindelin, Oct 21, 2016
  335. 22/27 sequencer: teach write_message() to append an optional LFJohannes Schindelin, Oct 21, 2016
  336. Junio C HamanoOct 21, 2016
  337. Johannes SchindelinOct 23, 2016
  338. 26/27 sequencer: start error messages consistently with lower caseJohannes Schindelin, Oct 21, 2016
  339. 20/27 sequencer: roll back lock file if write_message() failedJohannes Schindelin, Oct 21, 2016
  340. 24/27 sequencer: mark action_name() for translationJohannes Schindelin, Oct 21, 2016
  341. 27/27 sequencer: mark all error messages for translationJohannes Schindelin, Oct 21, 2016
  342. Junio C HamanoOct 21, 2016
  343. Johannes SchindelinOct 23, 2016
  344. Junio C HamanoOct 24, 2016
  345. Junio C HamanoOct 22, 2016
  346. Johannes SchindelinOct 23, 2016
  347. Johannes SchindelinOct 23, 2016
  348. Max HornOct 24, 2016
  349. Johannes SchindelinOct 24, 2016
  350. Junio C HamanoOct 24, 2016
  351. Stefan BellerOct 24, 2016
  352. Junio C HamanoOct 24, 2016

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.