diff --git a/radicle-surf/src/diff.rs b/radicle-surf/src/diff.rs index 03710b6..9ebcd3c 100644 --- a/radicle-surf/src/diff.rs +++ b/radicle-surf/src/diff.rs @@ -148,12 +148,21 @@ impl Diff { self.files.push(diff); } - pub fn insert_copied(&mut self, old_path: PathBuf, new_path: PathBuf) { + pub fn insert_copied( + &mut self, + old_path: PathBuf, + new_path: PathBuf, + old: DiffFile, + new: DiffFile, + content: DiffContent, + ) { self.update_stats(&DiffContent::Empty); let diff = FileDiff::Copied(Copied { old_path, new_path, - diff: DiffContent::Empty, + old, + new, + diff: content, }); self.files.push(diff); } @@ -213,6 +222,7 @@ impl Serialize for Moved { let mut state = serializer.serialize_struct("Moved", 2)?; state.serialize_field("oldPath", &self.old_path)?; state.serialize_field("newPath", &self.new_path)?; + state.serialize_field("current", &self.new)?; state.end() } else { let mut state = serializer.serialize_struct("Moved", 5)?; @@ -234,6 +244,8 @@ pub struct Copied { pub old_path: PathBuf, /// The new path to this file, relative to the repository root. pub new_path: PathBuf, + pub old: DiffFile, + pub new: DiffFile, pub diff: DiffContent, } diff --git a/radicle-surf/src/diff/git.rs b/radicle-surf/src/diff/git.rs index 7e9e3ae..0ff0a9c 100644 --- a/radicle-surf/src/diff/git.rs +++ b/radicle-surf/src/diff/git.rs @@ -236,7 +236,7 @@ impl<'a> TryFrom> for Diff { Delta::Deleted => deleted(&mut diff, &git_diff, idx, &delta)?, Delta::Modified => modified(&mut diff, &git_diff, idx, &delta)?, Delta::Renamed => renamed(&mut diff, &git_diff, idx, &delta)?, - Delta::Copied => copied(&mut diff, &delta)?, + Delta::Copied => copied(&mut diff, &git_diff, idx, &delta)?, status => { return Err(error::Diff::DeltaUnhandled(status)); }, @@ -353,16 +353,32 @@ fn renamed( Ok(()) } -fn copied(diff: &mut Diff, delta: &git2::DiffDelta<'_>) -> Result<(), error::Diff> { - let old = delta +fn copied( + diff: &mut Diff, + git_diff: &git2::Diff<'_>, + idx: usize, + delta: &git2::DiffDelta<'_>, +) -> Result<(), error::Diff> { + let old_path = delta .old_file() .path() - .ok_or(error::Diff::PathUnavailable)?; - let new = delta + .ok_or(error::Diff::PathUnavailable)? + .to_path_buf(); + let new_path = delta .new_file() .path() - .ok_or(error::Diff::PathUnavailable)?; + .ok_or(error::Diff::PathUnavailable)? + .to_path_buf(); + let patch = git2::Patch::from_diff(git_diff, idx)?; + let old = DiffFile::try_from(delta.old_file())?; + let new = DiffFile::try_from(delta.new_file())?; - diff.insert_copied(old.to_path_buf(), new.to_path_buf()); + if let Some(patch) = patch { + diff.insert_copied(old_path, new_path, old, new, DiffContent::try_from(patch)?); + } else if delta.new_file().is_binary() { + diff.insert_copied(old_path, new_path, old, new, DiffContent::Binary); + } else { + diff.insert_copied(old_path, new_path, old, new, DiffContent::Empty); + } Ok(()) } diff --git a/radicle-surf/t/src/diff.rs b/radicle-surf/t/src/diff.rs index 8e81a5d..09165f5 100644 --- a/radicle-surf/t/src/diff.rs +++ b/radicle-surf/t/src/diff.rs @@ -299,14 +299,28 @@ fn test_diff_serde() -> Result<(), Error> { }, }], "moved": [{ + "current": { + "mode": "blob", + "oid": "1570277532948712fea9029d100a4208f9e34241", + }, "oldPath": "text/emoji.txt", "newPath": "emoji.txt", }], "copied": [{ "diff": { - "type": "empty", + "eof": "noneMissing", + "hunks": [], + "type": "plain", + }, + "new": { + "mode": "blob", + "oid": "5e07534cd74a6a9b2ccd2729b181c4ef26173a5e", }, "newPath": "file_operations/copied.md", + "old": { + "mode": "blob", + "oid": "5e07534cd74a6a9b2ccd2729b181c4ef26173a5e", + }, "oldPath": "README.md", }], "modified": [{