martinvonz/jj

`jj close` (and some others) sometimes crashes on first attempt with Git backend

martinvonz opened this issue · 3 comments

jj prune, like most commands, first commit the working copy. When using the Git backend, that produces a Git commit with some hash. The next step for jj prune is to prune the commit. That's done by creating a successor commit with a is_pruned flag set. The problem is that both the predecessors field and the is_pruned field are stored outside of the Git commit and the timestamps are typically the same as well (it happens in much less than a second), so the resulting Git commit remains the same. The Git backend then fails the write (it doesn't allow two Git commits with different non-Git metadata).

I've known about this bug for a long time, but I figured it can be useful to track it. I'm working on removing support for evolution. The bug should be resolved by that work.

With the recent work on #32, the specific case of jj prune (now called jj abandon) shouldn't crash anymore. That was the most common way to run into the bug. However, jj close still suffers from the same problem: jj describe -m test; echo a >> a; jj close will almost always crash. At least it's pretty harmless and you can simply run jj close again after waiting a second.

I'm not sure what the best fix for this is. One option is to catch the error and have some commands wait a bit and then retry so the user doesn't have to do it, but that's pretty ugly. A better solution is probably to give each commit created from jj its own native commit ID that's unrelated to the git commit ID. Then those commits would have the extra metadata and it would be fine for two of them to point to the same git commit. Then we'd need to display both commit IDs in e.g. log output, although the native commit ID would only be needed for the few cases where multiple native commits pointed to the same git commit.

In #635, we saw that e.g. jj duplicate; jj describe -m 'new description'-r @- is another easy way to trigger this bug.