From e621d0dd05b2afa60385b583ddb5d5f149170dbd Mon Sep 17 00:00:00 2001 From: alkinun Date: Fri, 8 May 2026 23:06:36 +0300 Subject: [PATCH] git_ui: Escape markdown in discard confirmation dialog (#56197) ## Summary Filenames containing markdown syntax (e.g. `__somefile__`, `*somefile*`) were being rendered as formatted text in the git discard confirmation dialog. Follow-up to #55697 for the git discard confirmation path mentioned in #53060. ## Changes Wrapped the git discard confirmation filename with `MarkdownInlineCode` in `git_panel.rs`, so special markdown characters like `_`, `*`, and `[` render literally. ## Testing Added `test_discard_prompt_escapes_markdown_in_file_name` in `git_panel.rs` to verify filenames with markdown special characters render literally in the discard confirmation dialog. Run: ```bash cargo test -p git_ui test_discard_prompt_escapes_markdown_in_file_name ``` Release Notes: - Fixed file names containing markdown special characters (e.g. `__somefile__`) being rendered as formatted text in the git discard confirmation dialog. --- crates/git_ui/src/git_panel.rs | 78 +++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 5 deletions(-) diff --git a/crates/git_ui/src/git_panel.rs b/crates/git_ui/src/git_panel.rs index 7b8898b9ab8dc81aebd677ccfe8587d1f142f1e9..382bf7d7eed30357894bfd565082b7c01a4d0242 100644 --- a/crates/git_ui/src/git_panel.rs +++ b/crates/git_ui/src/git_panel.rs @@ -76,7 +76,7 @@ use ui::{ prelude::*, }; use util::paths::PathStyle; -use util::{ResultExt, TryFutureExt, maybe, rel_path::RelPath}; +use util::{ResultExt, TryFutureExt, markdown::MarkdownInlineCode, maybe, rel_path::RelPath}; use workspace::SERIALIZATION_THROTTLE_TIME; use workspace::{ Workspace, @@ -1421,10 +1421,12 @@ impl GitPanel { PromptLevel::Warning, &format!( "Are you sure you want to discard changes to {}?", - entry - .repo_path - .file_name() - .unwrap_or(entry.repo_path.display(path_style).as_ref()), + MarkdownInlineCode( + entry + .repo_path + .file_name() + .unwrap_or(entry.repo_path.display(path_style).as_ref()) + ), ), None, &["Discard Changes", "Cancel"], @@ -7097,6 +7099,72 @@ mod tests { ); } + #[gpui::test] + async fn test_discard_prompt_escapes_markdown_in_file_name(cx: &mut TestAppContext) { + init_test(cx); + let fs = FakeFs::new(cx.background_executor.clone()); + fs.insert_tree( + "/root", + json!({ + "project": { + ".git": {}, + "__somefile__": "modified\n", + }, + }), + ) + .await; + + fs.set_status_for_repo( + Path::new(path!("/root/project/.git")), + &[("__somefile__", StatusCode::Modified.worktree())], + ); + + let project = Project::test(fs.clone(), [Path::new(path!("/root/project"))], cx).await; + let window_handle = + cx.add_window(|window, cx| MultiWorkspace::test_new(project.clone(), window, cx)); + let workspace = window_handle + .read_with(cx, |mw, _| mw.workspace().clone()) + .unwrap(); + let cx = &mut VisualTestContext::from_window(window_handle.into(), cx); + + cx.read(|cx| { + project + .read(cx) + .worktrees(cx) + .next() + .unwrap() + .read(cx) + .as_local() + .unwrap() + .scan_complete() + }) + .await; + + cx.executor().run_until_parked(); + + let panel = workspace.update_in(cx, GitPanel::new); + + let handle = cx.update_window_entity(&panel, |panel, _, _| { + std::mem::replace(&mut panel.update_visible_entries_task, Task::ready(())) + }); + cx.executor().advance_clock(2 * UPDATE_DEBOUNCE); + handle.await; + + panel.update_in(cx, |panel, window, cx| { + panel.selected_entry = Some(1); + panel.revert_selected(&git::RestoreFile::default(), window, cx); + }); + + let (message, _detail) = cx + .pending_prompt() + .expect("discard should show a confirmation prompt"); + + assert_eq!( + message, + "Are you sure you want to discard changes to `__somefile__`?" + ); + } + #[gpui::test] async fn test_bulk_staging(cx: &mut TestAppContext) { use GitListEntry::*;