···6677let colored_string = Jj_tui.AnsiReverse.colored_string
8899-(**lists the files in a specific revision*)
1010-let list_files ?(rev = "@") () =
1111- jj_no_log ~snapshot:false ~color:false [ "diff"; "-r"; rev; "--summary" ]
99+let parse_changed_files output =
1010+ output
1211 |> String.split_on_char '\n'
1312 |> List.filter_map (fun x ->
1413 if x |> String.trim <> "" then Base.String.lsplit2 ~on:' ' x else None)
1414+;;
1515+1616+let is_missing_revision_error error =
1717+ Base.String.is_substring error ~substring:"doesn't exist"
1818+ || Base.String.is_substring error ~substring:"Revision `"
1919+;;
2020+2121+(** History-rewriting jj commands like squash can delete the revision currently held
2222+ in UI state. When that happens, the graph will soon refresh to a valid node, but
2323+ the file pane may still try to diff the stale revision in the meantime. Reset the
2424+ transient selection state so follow-up refreshes target a revision that still exists. *)
2525+let recover_missing_revision rev =
2626+ let hovered_matches = String.equal (Vars.get_hovered_rev ()) rev in
2727+ let selected_contains = Vars.get_selected_revs () |> List.exists (String.equal rev) in
2828+ if hovered_matches then Vars.ui_state.hovered_revision $= Unique "@";
2929+ if hovered_matches || selected_contains
3030+ then (
3131+ Vars.ui_state.selected_revisions $= [];
3232+ Vars.reset_selection ())
3333+;;
3434+3535+(**lists the files in a specific revision*)
3636+let list_files ?(rev = "@") () =
3737+ let diff_summary rev =
3838+ jj_no_log_errorable ~snapshot:false ~color:false [ "diff"; "-r"; rev; "--summary" ]
3939+ in
4040+ match diff_summary rev with
4141+ | Ok (output, _) ->
4242+ output |> parse_changed_files
4343+ | Error (`BadExit (_, error)) when is_missing_revision_error error ->
4444+ (* This is the crash path hit after squash: the selected revision disappeared
4545+ between UI updates. Recover locally instead of raising through startup/render
4646+ fibers, then repopulate the file list from the working copy. *)
4747+ [%log
4848+ warn "Revision '%s' disappeared while updating file list; falling back to @" rev];
4949+ recover_missing_revision rev;
5050+ (match diff_summary "@" with
5151+ | Ok (output, _) ->
5252+ output |> parse_changed_files
5353+ | Error (`BadExit (_, error)) ->
5454+ [%log warn "Failed to refresh fallback file list for @: %s" error];
5555+ []
5656+ | Error (`Exception error) ->
5757+ [%log warn "Failed to refresh fallback file list for @: %s" error];
5858+ [])
5959+ | Error (`BadExit (_, error)) ->
6060+ [%log warn "Failed to update file list for revision '%s': %s" rev error];
6161+ []
6262+ | Error (`Exception error) ->
6363+ [%log warn "Failed to update file list for revision '%s': %s" rev error];
6464+ []
1565;;
16661767let check_startup () =