git: Add diff view for stash entries (#38280)
Continues the work from #35927 to add a git diff view for stash entries. [Screencast From 2025-09-17 19-46-01.webm](https://github.com/user-attachments/assets/ded33782-adef-4696-8e34-3665911c09c7) Stash entries are [represented as commits](https://git-scm.com/docs/git-stash#_discussion) except they have up to 3 parents: ``` .----W (this is the stash entry) / /| -----H----I | \| U ``` Where `H` is the `HEAD` commit, `I` is a commit that records the state of the index, and `U` is another commit that records untracked files (when using `git stash -u`). Given this, I modified the existing commit view struct to allow loading stash and commits entries with git sha identifier so that we can get a similar git diff view for both of them. The stash diff is generated by comparing the stash commit with its parent (`<commit>^` or `H` in the diagram) which generates the same diff as doing `git stash show -p <stash entry>`. This *can* be counter-intuitive since a user may expect the comparison to be made between the stash commit and the current commit (`HEAD`), but given that the default behavior in git cli is to compare with the stash parent, I went for that approach. Hoping to get some feedback from a Zed team member to see if they agree with this approach. Release Notes: - Add git diff view for stash entries - Add toolbar on git diff view for stash entries - Prompt before executing a destructive stash action on diff view - Fix commit view for merge commits (see #38289)
This commit is contained in:
@@ -693,10 +693,11 @@ impl GitRepository for RealGitRepository {
|
||||
.args([
|
||||
"--no-optional-locks",
|
||||
"show",
|
||||
"--format=%P",
|
||||
"--format=",
|
||||
"-z",
|
||||
"--no-renames",
|
||||
"--name-status",
|
||||
"--first-parent",
|
||||
])
|
||||
.arg(&commit)
|
||||
.stdin(Stdio::null())
|
||||
@@ -707,9 +708,8 @@ impl GitRepository for RealGitRepository {
|
||||
.context("starting git show process")?;
|
||||
|
||||
let show_stdout = String::from_utf8_lossy(&show_output.stdout);
|
||||
let mut lines = show_stdout.split('\n');
|
||||
let parent_sha = lines.next().unwrap().trim().trim_end_matches('\0');
|
||||
let changes = parse_git_diff_name_status(lines.next().unwrap_or(""));
|
||||
let changes = parse_git_diff_name_status(&show_stdout);
|
||||
let parent_sha = format!("{}^", commit);
|
||||
|
||||
let mut cat_file_process = util::command::new_smol_command(&git_binary_path)
|
||||
.current_dir(&working_directory)
|
||||
|
||||
Reference in New Issue
Block a user