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

Re: [PATCH 1/4] rebase -i: demonstrate obscure loose object cache bug

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Mar 13, 2019, 22:40 UTC
Message-ID
<nycvar.QRO.7.76.6.1903132327500.41@tvgsbejvaqbjf.bet>
In-Reply-To
<20190313165320.GA717@sigill.intra.peff.net>
Hi Peff,
On Wed, 13 Mar 2019, Jeff King wrote:
Show 19 quoted lines
> 
> By the way, while reading the test more carefully, I did notice two
> funny things:
> 
> > +test_expect_failure SHA1 'loose object cache vs re-reading todo list' '
> > +	GIT_REBASE_TODO=.git/rebase-merge/git-rebase-todo &&
> > +	export GIT_REBASE_TODO &&
> > +	write_script append-todo.sh <<-\EOS &&
> > +	# For values 5 and 6, this yields SHA-1s with the same first two digits
> > +	echo "pick $(git rev-parse --short \
> > +		$(printf "%s\\n" \
> > +			"tree $EMPTY_TREE" \
> > +			"author A U Thor <author@example.org> $1 +0000" \
> > +			"committer A U Thor <author@example.org> $1 +0000" \
> > +			"" \
> > +			"$1" |
> > +		  git hash-object -t commit -w --stdin))" >>$GIT_REBASE_TODO
> 
> Here we redirect the output into $GIT_REBASE_TODO, not stdout.
Indeed, because we want to append a `pick` command to the todo list.
Show 5 quoted lines
> > +	shift
> > +	test -z "$*" ||
> > +	echo "exec $0 $*" >>$GIT_REBASE_TODO
> 
> And here we do the same thing. That second redirection is unnecessary.

It is actually not unnecessary, but to the contrary quite necessary to achieve the intended effect: with this command, we append an `exec` line to the todo list that is guaranteed to be executed after the `pick` command that we added earlier.

Show 8 quoted lines
> I also find it interesting that it iterates over its arguments by
> recursive processes. Wouldn't:
> 
>   for i in "$@"; do
> 	echo "pick ..." >>$GIT_REBASE_TODO
>   done
> 
> be a bit more efficient (as well as more obvious?).

It would be more efficient, but it would also fail to test for the regression.

Remember: it is absolutely crucial for the regression test that the parent
process' loose object cache already has been initialized *before* the new
commit is created and then picked. Otherwise the cache would contain that
commit object already. The whole point of the regression test is that the
cache does *not* contain that object.

The only way we can guarantee that order in this test is if the first commit is created and picked *before* we `exec` to create the second commit and then append the `pick` line for that one.

Now, I could have tried to play some fake editor games because it is not strictly necessary to create the first commit via an `exec` line. Instead, I could have generated it before the rebase, and then initialized the todo list with the `pick` of the first commit and then an `exec` of the script that creates the second commit and then appends a `pick` line for that.

But the reality is that this would have resulted in more code! And not even easier-to-read code at that! (I know, because one of my unsent iterations did exactly that.)

So instead, I opted for using the `-x` option to modify the initial todo list to begin with (it consists of a single `noop`, obviously). This will add that `exec` line that calls the script that creates the first commit and appends the `pick` line.

It *also* adds an `exec` line to guarantee that the second commit is created, and a `pick` line for it is appended to the todo list, *after* the sequencer initalized the loose object cache by virtue of picking the first commit.

So yes, it is crucial that the `append-todo.sh` script is `exec`ed *twice*. Otherwise the first `pick` would initialize the loose object cache *after* the second commit was created, which Just Works, even without this here patch series.

Ciao, Dscho

Previous: Jeff KingNext: Jeff King
Message 6 of 32 in “get_oid: cope with a possibly stale loose object cache”
  1. 0/4 get_oid: cope with a possibly stale loose object cacheJohannes Schindelin via GitGitGadget, Mar 13, 2019
  2. 1/4 rebase -i: demonstrate obscure loose object cache bugJohannes Schindelin via GitGitGadget, Mar 13, 2019
  3. Ævar Arnfjörð BjarmasonMar 13, 2019
  4. Jeff KingMar 13, 2019
  5. Jeff KingMar 13, 2019
  6. Johannes SchindelinMar 13, 2019
  7. Jeff KingMar 14, 2019
  8. Johannes SchindelinMar 13, 2019
  9. Jeff KingMar 14, 2019
  10. Johannes SixtMar 14, 2019
  11. Johannes SchindelinMar 14, 2019
  12. Junio C HamanoMar 14, 2019
  13. Johannes SchindelinMar 14, 2019
  14. 2/4 sequencer: improve error message when an OID could not be parsedJohannes Schindelin via GitGitGadget, Mar 13, 2019
  15. Junio C HamanoMar 14, 2019
  16. 4/4 get_oid(): when an object was not found, try harderJohannes Schindelin via GitGitGadget, Mar 13, 2019
  17. Junio C HamanoMar 14, 2019
  18. Jeff KingMar 14, 2019
  19. Jeff KingMar 14, 2019
  20. Junio C HamanoMar 14, 2019
  21. Jeff KingMar 14, 2019
  22. Junio C HamanoMar 14, 2019
  23. Johannes SchindelinMar 14, 2019
  24. Jeff KingMar 14, 2019
  25. Johannes SchindelinMar 14, 2019
  26. 3/4 sequencer: move stale comment into correct locationJohannes Schindelin via GitGitGadget, Mar 13, 2019
  27. Jeff KingMar 13, 2019
  28. 0/4 get_short_oid: cope with a possibly stale loose object cacheJohannes Schindelin via GitGitGadget, Mar 14, 2019
  29. 1/4 rebase -i: demonstrate obscure loose object cache bugJohannes Schindelin via GitGitGadget, Mar 14, 2019
  30. 2/4 sequencer: improve error message when an OID could not be parsedJohannes Schindelin via GitGitGadget, Mar 14, 2019
  31. 3/4 sequencer: move stale comment into correct locationJohannes Schindelin via GitGitGadget, Mar 14, 2019
  32. 4/4 get_oid(): when an object was not found, try harderJohannes Schindelin via GitGitGadget, Mar 14, 2019

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.