Skip to content

Commit 51c5109

Browse files
committed
fix: assure differences are handled exhaustively. (#26)
Previously it was possible to have multiple diffs in one crate distributed over multiple commits to rightfully show up as multiple hunks of modified and added lines only register the modified lines, not the new ones (or the deleted ones for that matter). This would cause updates or removals to be missed. Now hunks of changes are exhaused properly, fixing this issue.
1 parent 69c8f43 commit 51c5109

File tree

2 files changed

+54
-49
lines changed

2 files changed

+54
-49
lines changed

src/index/diff/delegate.rs

Lines changed: 51 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -75,62 +75,68 @@ impl Delegate {
7575
.iter()
7676
.map(|&line| input.interner[line].as_bstr())
7777
.peekable();
78-
match (lines_before.peek().is_some(), lines_after.peek().is_some()) {
79-
(true, false) => {
80-
for removed in lines_before {
81-
match version_from_json_line(removed, location) {
82-
Ok(version) => {
83-
self.delete_version_ids.insert(version.id());
84-
}
85-
Err(e) => {
86-
err = Some(e);
87-
break;
88-
}
89-
}
90-
}
91-
}
92-
(false, true) => {
93-
for inserted in lines_after {
94-
match version_from_json_line(inserted, location) {
95-
Ok(version) => {
96-
self.changes.push(if version.yanked {
97-
Change::Yanked(version)
98-
} else {
99-
Change::Added(version)
100-
});
101-
}
102-
Err(e) => {
103-
err = Some(e);
104-
break;
78+
loop {
79+
match (lines_before.peek().is_some(), lines_after.peek().is_some())
80+
{
81+
(true, false) => {
82+
for removed in lines_before {
83+
match version_from_json_line(removed, location) {
84+
Ok(version) => {
85+
self.delete_version_ids.insert(version.id());
86+
}
87+
Err(e) => {
88+
err = Some(e);
89+
break;
90+
}
10591
}
10692
}
93+
break;
10794
}
108-
}
109-
(true, true) => {
110-
for (removed, inserted) in lines_before.zip(lines_after) {
111-
match version_from_json_line(inserted, location).and_then(
112-
|inserted| {
113-
version_from_json_line(removed, location)
114-
.map(|removed| (removed, inserted))
115-
},
116-
) {
117-
Ok((removed, inserted)) => {
118-
if removed.yanked != inserted.yanked {
119-
self.changes.push(if inserted.yanked {
120-
Change::Yanked(inserted)
95+
(false, true) => {
96+
for inserted in lines_after {
97+
match version_from_json_line(inserted, location) {
98+
Ok(version) => {
99+
self.changes.push(if version.yanked {
100+
Change::Yanked(version)
121101
} else {
122-
Change::Added(inserted)
102+
Change::Added(version)
123103
});
124104
}
105+
Err(e) => {
106+
err = Some(e);
107+
break;
108+
}
125109
}
126-
Err(e) => {
127-
err = Some(e);
128-
break;
110+
}
111+
break;
112+
}
113+
(true, true) => {
114+
for (removed, inserted) in
115+
lines_before.by_ref().zip(lines_after.by_ref())
116+
{
117+
match version_from_json_line(inserted, location)
118+
.and_then(|inserted| {
119+
version_from_json_line(removed, location)
120+
.map(|removed| (removed, inserted))
121+
}) {
122+
Ok((removed, inserted)) => {
123+
if removed.yanked != inserted.yanked {
124+
self.changes.push(if inserted.yanked {
125+
Change::Yanked(inserted)
126+
} else {
127+
Change::Added(inserted)
128+
});
129+
}
130+
}
131+
Err(e) => {
132+
err = Some(e);
133+
break;
134+
}
129135
}
130136
}
131137
}
138+
(false, false) => break,
132139
}
133-
(false, false) => {}
134140
}
135141
},
136142
);

tests/index/changes_between_commits.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ fn directory_deletions_are_not_picked_up() -> crate::Result {
1111
}
1212

1313
#[test]
14-
#[ignore]
1514
fn updates_before_yanks_are_picked_up() -> crate::Result {
1615
let index = index_ro()?;
1716
let repo = index.repository();
@@ -21,9 +20,9 @@ fn updates_before_yanks_are_picked_up() -> crate::Result {
2120
)?;
2221

2322
assert_eq!(changes.len(), 3, "1 update and 2 yanks");
24-
assert_eq!(changes[0].added().expect("first updated").version, "0.3.11");
25-
assert_eq!(changes[1].yanked().expect("second yanked").version, "0.3.4");
26-
assert_eq!(changes[2].yanked().expect("third yanked").version, "0.3.5");
23+
assert_eq!(changes[0].yanked().expect("second yanked").version, "0.3.4");
24+
assert_eq!(changes[1].yanked().expect("third yanked").version, "0.3.5");
25+
assert_eq!(changes[2].added().expect("first updated").version, "0.3.11");
2726
Ok(())
2827
}
2928

0 commit comments

Comments
 (0)