jj icon indicating copy to clipboard operation
jj copied to clipboard

jj gets stuck at the last step of `jj git import`

Open Zoybean opened this issue 1 year ago • 6 comments

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

  1. jj git remote delete foo
  2. git tag --delete ..... # a lot of tags
  3. jj 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

Zoybean avatar Sep 17 '24 15:09 Zoybean

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.

Zoybean avatar Sep 17 '24 15:09 Zoybean

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.

yuja avatar Sep 18 '24 00:09 yuja

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

Zoybean avatar Sep 18 '24 00:09 Zoybean

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.)

yuja avatar Sep 18 '24 01:09 yuja

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

Zoybean avatar Sep 18 '24 07:09 Zoybean

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

yuja avatar Sep 18 '24 07:09 yuja