Hi Peff, On Wed, 13 Mar 2019, Jeff King wrote: > > 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@xxxxxxxxxxx> $1 +0000" \ > > + "committer A U Thor <author@xxxxxxxxxxx> $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. > > + 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. > 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