aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTeddy Wing2020-07-28 02:06:39 +0200
committerTeddy Wing2020-07-28 19:47:13 +0200
commit11118c94cc8fa315cbad1e39f3f285eb7ccbcca8 (patch)
tree2fbd459446106448d95d29753468d319a0ad67c3 /src
parent1283d0511bac89957163097d1a68bb9753208f09 (diff)
downloadgit-suggestion-11118c94cc8fa315cbad1e39f3f285eb7ccbcca8.tar.bz2
Suggestion.apply(): Error when patch doesn't apply
Don't apply the patch when it doesn't apply, instead fail with an error. Previously, the `apply()` method would apply the patch to the lines from `Suggestion`, even if the file was different from what the suggestion expected. So, you could end up with the `Suggestion` lines being overwritten with the suggestion text, even when they didn't match the original side of the suggestion. Fix this by getting the diff text from `diff_with_repo()` and applying it using `git-apply`. This gives us a suitable error when the patch doesn't apply to the file, leaving the file alone.
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs25
1 files changed, 8 insertions, 17 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 7612857..31df669 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -6,8 +6,6 @@ mod url;
pub use crate::url::SuggestionUrl;
-use std::fs;
-use std::fs::{File, OpenOptions};
use std::io::{BufRead, BufReader, BufWriter, Write};
use std::path::Path;
@@ -17,7 +15,6 @@ use regex::Regex;
use serde::Deserialize;
use serde_json::Value;
use thiserror::Error;
-use tempfile::NamedTempFile;
#[derive(Debug, Error)]
@@ -177,23 +174,17 @@ impl Suggestion {
pub fn apply(&self) -> Result<(), Error> {
let repo = Repository::open(".").unwrap();
- let repo_root = repo.workdir().unwrap();
- // let original = File::open(repo_root.join(&self.path)).unwrap();
- // let metadata = original.metadata().unwrap();
- // let created_at = metadata.created().unwrap();
+ let diff_text = self.diff_with_repo(&repo);
+ let diff = git2::Diff::from_buffer(diff_text.as_bytes()).unwrap();
- let new = NamedTempFile::new().unwrap();
-
- fs::copy(repo_root.join(&self.path), new.path()).unwrap();
-
- let mut original = OpenOptions::new()
- .write(true)
- .truncate(true)
- .open(repo_root.join(&self.path)).unwrap();
+ repo.apply(
+ &diff,
+ git2::ApplyLocation::WorkDir,
+ None,
+ ).unwrap();
- let new_buffer = BufReader::new(new);
- self.apply_to(new_buffer, &mut original)
+ Ok(())
}
fn apply_to<R: BufRead, W: Write>(