jj gets stuck at the last step of `jj git import`
Description
After deleting a remote and a bunch of tags, jj hangs at the final step of the jj git import command, making no apparent progress.
Steps to Reproduce the Problem
jj git remote delete foogit tag --delete ..... # a lot of tagsjj status --debug
Expected Behavior
jj reports that several thousand commits were abandoned, then prints the status and exits
Actual Behavior
jj reports that several thousand commits were abandoned, then hangs indefinitely
Specifications
- Platform: linux mint
- Version: jj 0.21.0
this effectively prevents any use of jj, and since --debug isn't printing anything, so for now I'm backing up the .jj directory and recreating it with jj git init --colocate. and if needed / if there's a solution, I can restore the old backup and try out suggestions.
While some of the quadratic behavior should be fixed by 8e500c0182c8, etc. (included in 0.21.0), it's still expensive to rebase thousands of descendants of the abandoned commits (which are likely to result in conflict trees.) Perhaps, we can insert some stats and/or progress message there.
https://github.com/martinvonz/jj/issues/4152 might also help make rebasing faster, but I'm not sure.
would there be any descendants? the commits-to-be-abandoned are already unreachable, which I thought meant their only descendants would also be unreachable and therefore part of the same set to be abandoned
would there be any descendants?
If you have refs on all head commits (as in Git), no there wouldn't. Suppose jj git remote delete foo removed remote refs, there may be tons on descendant commits of deleted tags which were previously pointed to by remote refs.
You can inspect the old state by jj --at-op <old-op> log -r 'deleted_tags:: & (branches()|untracked_remote_branches())..' if you have a backup of .jj repo. (the actual query might be a bit different.)
there may be tons on descendant commits of deleted tags
Maybe I'm misunderstanding reachability, but wouldn't those commits fall into one of the following categories? either:
- they are reachable, therefore their ancestors are reachable, so they aren't abandoned, so no rebase is needed
- they are unreachable, therefore they will be automatically deleted along with their ancestors, so no rebase is needed
Since jj doesn't require Git tags/branches to preserve commits, jj internally has a list of visible heads.
At 1.
jj git remote delete foo
remote refs are deleted internally by jj. visible heads are unchanged.
At 2.
git tag --delete ..... # a lot of tags
tags are deleted externally by git.
At 3.
jj status --debug
here jj notices tags are deleted externally/remotely, so jj tries to replicate the changes made by git. This is done by abandoning commits that were previously reachable by git tags/branches but become unreachable. Descendants of deleted tags weren't reachable by git, so they are preserved.
The last step can be turned off by git.abandon-unreachable-commits = false.
https://martinvonz.github.io/jj/latest/config/#abandon-commits-that-became-unreachable-in-git