Skip to content

Commit f3a67e8

Browse files
author
Stephan Dilly
committed
dont show weird 'no text file' when diffing binary
cleanup
1 parent 0598528 commit f3a67e8

File tree

2 files changed

+64
-42
lines changed

2 files changed

+64
-42
lines changed

asyncgit/src/sync/diff.rs

Lines changed: 61 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
use super::utils;
44
use crate::hash;
55
use git2::{
6-
Delta, Diff, DiffDelta, DiffFormat, DiffHunk, DiffOptions, Patch,
7-
Repository,
6+
Delta, Diff, DiffDelta, DiffFormat, DiffHunk, DiffOptions, Error,
7+
Patch, Repository,
88
};
99
use scopetime::scope_time;
1010
use std::{fs, path::Path};
1111

1212
/// type of diff of a single line
13-
#[derive(Copy, Clone, PartialEq, Hash)]
13+
#[derive(Copy, Clone, PartialEq, Hash, Debug)]
1414
pub enum DiffLineType {
1515
/// just surrounding line, no change
1616
None,
@@ -29,7 +29,7 @@ impl Default for DiffLineType {
2929
}
3030

3131
///
32-
#[derive(Default, Clone, Hash)]
32+
#[derive(Default, Clone, Hash, Debug)]
3333
pub struct DiffLine {
3434
///
3535
pub content: String,
@@ -57,7 +57,7 @@ impl From<DiffHunk<'_>> for HunkHeader {
5757
}
5858

5959
/// single diff hunk
60-
#[derive(Default, Clone, Hash)]
60+
#[derive(Default, Clone, Hash, Debug)]
6161
pub struct Hunk {
6262
/// hash of the hunk header
6363
pub header_hash: u64,
@@ -66,7 +66,7 @@ pub struct Hunk {
6666
}
6767

6868
/// collection of hunks, sum of all diff lines
69-
#[derive(Default, Clone, Hash)]
69+
#[derive(Default, Clone, Hash, Debug)]
7070
pub struct FileDiff {
7171
/// list of hunks
7272
pub hunks: Vec<Hunk>,
@@ -79,7 +79,7 @@ pub(crate) fn get_diff_raw<'a>(
7979
p: &str,
8080
stage: bool,
8181
reverse: bool,
82-
) -> (Diff<'a>, DiffOptions) {
82+
) -> Result<Diff<'a>, Error> {
8383
let mut opt = DiffOptions::new();
8484
opt.pathspec(p);
8585
opt.reverse(reverse);
@@ -88,39 +88,38 @@ pub(crate) fn get_diff_raw<'a>(
8888
// diff against head
8989
if let Ok(ref_head) = repo.head() {
9090
let parent =
91-
repo.find_commit(ref_head.target().unwrap()).unwrap();
92-
let tree = parent.tree().unwrap();
91+
repo.find_commit(ref_head.target().unwrap())?;
92+
let tree = parent.tree()?;
9393
repo.diff_tree_to_index(
9494
Some(&tree),
95-
Some(&repo.index().unwrap()),
95+
Some(&repo.index()?),
9696
Some(&mut opt),
97-
)
98-
.unwrap()
97+
)?
9998
} else {
10099
repo.diff_tree_to_index(
101100
None,
102-
Some(&repo.index().unwrap()),
101+
Some(&repo.index()?),
103102
Some(&mut opt),
104-
)
105-
.unwrap()
103+
)?
106104
}
107105
} else {
108106
opt.include_untracked(true);
109107
opt.recurse_untracked_dirs(true);
110-
repo.diff_index_to_workdir(None, Some(&mut opt)).unwrap()
108+
repo.diff_index_to_workdir(None, Some(&mut opt))?
111109
};
112110

113-
(diff, opt)
111+
Ok(diff)
114112
}
115113

114+
//TODO: return Option
116115
///
117116
pub fn get_diff(repo_path: &str, p: String, stage: bool) -> FileDiff {
118117
scope_time!("get_diff");
119118

120119
let repo = utils::repo(repo_path);
121120
let repo_path = repo.path().parent().unwrap();
122121

123-
let (diff, mut opt) = get_diff_raw(&repo, &p, stage, false);
122+
let diff = get_diff_raw(&repo, &p, stage, false).unwrap();
124123

125124
let mut res: FileDiff = FileDiff::default();
126125
let mut current_lines = Vec::new();
@@ -172,26 +171,29 @@ pub fn get_diff(repo_path: &str, p: String, stage: bool) -> FileDiff {
172171
let newfile_path =
173172
repo_path.join(delta.new_file().path().unwrap());
174173

175-
let newfile_content = new_file_content(&newfile_path)
176-
.unwrap_or_else(|| String::from("file not found"));
177-
178-
let mut patch = Patch::from_buffers(
179-
&[],
180-
None,
181-
newfile_content.as_bytes(),
182-
Some(&newfile_path),
183-
Some(&mut opt),
184-
)
185-
.unwrap();
186-
187-
patch
188-
.print(&mut |_delta, hunk:Option<DiffHunk>, line: git2::DiffLine| {
189-
put(hunk,line);
190-
true
191-
})
174+
if let Some(newfile_content) =
175+
new_file_content(&newfile_path)
176+
{
177+
let mut patch = Patch::from_buffers(
178+
&[],
179+
None,
180+
newfile_content.as_bytes(),
181+
Some(&newfile_path),
182+
None,
183+
)
192184
.unwrap();
193185

194-
true
186+
patch
187+
.print(&mut |_delta, hunk:Option<DiffHunk>, line: git2::DiffLine| {
188+
put(hunk,line);
189+
true
190+
})
191+
.unwrap();
192+
193+
true
194+
} else {
195+
false
196+
}
195197
} else {
196198
false
197199
}
@@ -226,8 +228,6 @@ fn new_file_content(path: &Path) -> Option<String> {
226228
} else if meta.file_type().is_file() {
227229
if let Ok(content) = fs::read_to_string(path) {
228230
return Some(content);
229-
} else {
230-
return Some(String::from("no text file"));
231231
}
232232
}
233233
}
@@ -245,7 +245,7 @@ mod tests {
245245
};
246246
use std::{
247247
fs::{self, File},
248-
io::Write,
248+
io::{Error, Write},
249249
path::Path,
250250
};
251251

@@ -391,4 +391,26 @@ mod tests {
391391

392392
assert_eq!(diff.hunks[0].lines[1].content, "test");
393393
}
394+
395+
#[test]
396+
fn test_diff_new_binary_file_using_invalid_utf8(
397+
) -> Result<(), Error> {
398+
let file_path = Path::new("bar");
399+
let (_td, repo) = repo_init_empty();
400+
let root = repo.path().parent().unwrap();
401+
let repo_path = root.as_os_str().to_str().unwrap();
402+
403+
File::create(&root.join(file_path))?
404+
.write_all(b"\xc3\x28")?;
405+
406+
let diff = get_diff(
407+
repo_path,
408+
String::from(file_path.to_str().unwrap()),
409+
false,
410+
);
411+
412+
assert_eq!(diff.hunks.len(), 0);
413+
414+
Ok(())
415+
}
394416
}

asyncgit/src/sync/hunks.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub fn stage_hunk(
1717

1818
let repo = repo(repo_path);
1919

20-
let (diff, _) = get_diff_raw(&repo, &file_path, false, false);
20+
let diff = get_diff_raw(&repo, &file_path, false, false).unwrap();
2121

2222
let mut opt = ApplyOptions::new();
2323
opt.hunk_callback(|hunk| {
@@ -65,7 +65,7 @@ pub fn unstage_hunk(
6565

6666
let repo = repo(repo_path);
6767

68-
let (diff, _) = get_diff_raw(&repo, &file_path, true, false);
68+
let diff = get_diff_raw(&repo, &file_path, true, false).unwrap();
6969
let diff_count_positive = diff.deltas().len();
7070

7171
let hunk_index = find_hunk_index(&diff, hunk_hash);
@@ -75,7 +75,7 @@ pub fn unstage_hunk(
7575
return false;
7676
}
7777

78-
let (diff, _) = get_diff_raw(&repo, &file_path, true, true);
78+
let diff = get_diff_raw(&repo, &file_path, true, true).unwrap();
7979

8080
assert_eq!(diff.deltas().len(), diff_count_positive);
8181

0 commit comments

Comments
 (0)