Skip to content

Commit 79b35fc

Browse files
committed
Allow parsing rename-only diffs (similarity score 100%)
1 parent 05882be commit 79b35fc

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

src/parser.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,9 @@ fn patch(input: Input<'_>) -> IResult<Input<'_>, Patch> {
9999
if let Ok(patch) = binary_files_differ(input) {
100100
return Ok(patch);
101101
}
102+
if let Ok(patch) = file_rename_only(input) {
103+
return Ok(patch);
104+
}
102105
let (input, files) = headers(input)?;
103106
let (input, hunks) = chunks(input)?;
104107
let (input, no_newline_indicator) = no_newline_indicator(input)?;
@@ -151,6 +154,36 @@ fn binary_files_differ(input: Input<'_>) -> IResult<Input<'_>, Patch> {
151154
))
152155
}
153156

157+
/// Parse patches with "similarity index 100%", i.e., patches where a file is renamed without any
158+
/// other change in its diff.
159+
///
160+
/// The `parse` function should handle rename diffs with similary index less than 100%, at least as per the test
161+
/// `parses_file_renames_with_some_diff`.
162+
fn file_rename_only(input: Input<'_>) -> IResult<Input<'_>, Patch> {
163+
let (rest, _parsed) = take_until("\nsimilarity index 100%\n")(input)?;
164+
let (rest, _parsed) = tag("\nsimilarity index 100%\n")(rest)?;
165+
166+
let (rest, old_name) = delimited(tag("rename from "), take_until("\n"), line_ending)(rest)?;
167+
168+
let (rest, new_name) = delimited(tag("rename to "), take_until("\n"), line_ending)(rest)?;
169+
170+
Ok((
171+
rest,
172+
Patch {
173+
old: File {
174+
path: Cow::Borrowed(&old_name),
175+
meta: None,
176+
},
177+
new: File {
178+
path: Cow::Borrowed(&new_name),
179+
meta: None,
180+
},
181+
hunks: Vec::new(),
182+
end_newline: false,
183+
},
184+
))
185+
}
186+
154187
// Header lines
155188
fn headers(input: Input<'_>) -> IResult<Input<'_>, (File, File)> {
156189
// Ignore any preamble lines in produced diffs

tests/parse_patch.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,20 @@ index d923f10..b47f160 100644
399399
.iter()
400400
.any(|line| matches!(line, Line::Add("use new_crate;"))));
401401
}
402+
403+
#[test]
404+
fn parses_file_rename_with_100_pct_similarity() {
405+
let sample = "\
406+
diff --git a/original-path.rs b/new-path.rs
407+
similarity index 100%
408+
rename from original-path.rs
409+
rename to new-path.rs
410+
";
411+
412+
let patches = Patch::from_multiple(sample).unwrap();
413+
414+
assert_eq!(patches.len(), 1);
415+
assert_eq!(patches[0].old.path, "original-path.rs");
416+
assert_eq!(patches[0].new.path, "new-path.rs");
417+
assert!(patches[0].hunks.is_empty());
418+
}

0 commit comments

Comments
 (0)