fix blob creation and get changes
This commit is contained in:
parent
ce047eba12
commit
91a29480df
@ -1,4 +1,7 @@
|
|||||||
use std::io;
|
use std::io::{self, Read};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
use std::fs::OpenOptions;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@ -9,15 +12,17 @@ use crate::store::head;
|
|||||||
use crate::store::object::{update_dates, add_node, create_obj, rm_node};
|
use crate::store::object::{update_dates, add_node, create_obj, rm_node};
|
||||||
|
|
||||||
pub struct Blob {
|
pub struct Blob {
|
||||||
path: PathBuf,
|
r_path: PathBuf,
|
||||||
|
a_path: PathBuf,
|
||||||
hash: String,
|
hash: String,
|
||||||
obj_p: PathBuf,
|
obj_p: PathBuf,
|
||||||
|
data: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Blob {
|
impl Blob {
|
||||||
pub fn new(path: PathBuf) -> Blob {
|
pub fn new(r_path: PathBuf) -> Blob {
|
||||||
let mut hasher = Sha1::new();
|
let mut hasher = Sha1::new();
|
||||||
hasher.input_str(path.to_str().unwrap());
|
hasher.input_str(r_path.to_str().unwrap());
|
||||||
let hash = hasher.result_str();
|
let hash = hasher.result_str();
|
||||||
|
|
||||||
let (dir, res) = hash.split_at(2);
|
let (dir, res) = hash.split_at(2);
|
||||||
@ -26,15 +31,20 @@ impl Blob {
|
|||||||
obj_p.push(dir);
|
obj_p.push(dir);
|
||||||
obj_p.push(res);
|
obj_p.push(res);
|
||||||
|
|
||||||
|
let root = path::repo_root();
|
||||||
|
let a_path = root.join(r_path.clone());
|
||||||
|
|
||||||
Blob {
|
Blob {
|
||||||
path,
|
r_path,
|
||||||
|
a_path,
|
||||||
hash,
|
hash,
|
||||||
obj_p,
|
obj_p,
|
||||||
|
data: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_line_filename(&mut self) -> (String, String) {
|
fn get_line_filename(&mut self) -> (String, String) {
|
||||||
let file_name = self.path.file_name().unwrap().to_str().unwrap().to_owned();
|
let file_name = self.r_path.file_name().unwrap().to_str().unwrap().to_owned();
|
||||||
let mut line = String::from("blob");
|
let mut line = String::from("blob");
|
||||||
line.push_str(" ");
|
line.push_str(" ");
|
||||||
line.push_str(&self.hash);
|
line.push_str(&self.hash);
|
||||||
@ -44,7 +54,7 @@ impl Blob {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_file_hash(&self) -> String {
|
fn get_file_hash(&self) -> String {
|
||||||
let bytes = std::fs::read(self.path.clone()).unwrap();
|
let bytes = std::fs::read(self.a_path.clone()).unwrap();
|
||||||
let hash = md5::compute(&bytes);
|
let hash = md5::compute(&bytes);
|
||||||
format!("{:x}", hash)
|
format!("{:x}", hash)
|
||||||
}
|
}
|
||||||
@ -53,14 +63,14 @@ impl Blob {
|
|||||||
let (line, file_name) = self.get_line_filename();
|
let (line, file_name) = self.get_line_filename();
|
||||||
|
|
||||||
// add blob reference to parent
|
// add blob reference to parent
|
||||||
if self.path.iter().count() == 1 {
|
if self.r_path.iter().count() == 1 {
|
||||||
head::add_line(line)?;
|
head::add_line(line)?;
|
||||||
} else {
|
} else {
|
||||||
add_node(self.path.parent().unwrap(), &line)?;
|
add_node(self.r_path.parent().unwrap(), &line)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create blob object
|
// create blob object
|
||||||
let metadata = fs::metadata(self.path.clone())?;
|
let metadata = fs::metadata(self.a_path.clone())?;
|
||||||
|
|
||||||
let mut content = file_name.clone();
|
let mut content = file_name.clone();
|
||||||
content.push_str(" ");
|
content.push_str(" ");
|
||||||
@ -68,6 +78,7 @@ impl Blob {
|
|||||||
content.push_str(" ");
|
content.push_str(" ");
|
||||||
content.push_str(&metadata.len().to_string());
|
content.push_str(&metadata.len().to_string());
|
||||||
content.push_str(" ");
|
content.push_str(" ");
|
||||||
|
|
||||||
let secs = metadata
|
let secs = metadata
|
||||||
.modified()
|
.modified()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -77,11 +88,22 @@ impl Blob {
|
|||||||
content.push_str(&secs.to_string());
|
content.push_str(&secs.to_string());
|
||||||
content.push_str(" ");
|
content.push_str(" ");
|
||||||
content.push_str(&self.get_file_hash());
|
content.push_str(&self.get_file_hash());
|
||||||
create_obj(self.hash.clone(), &content)?;
|
content.push_str(" ");
|
||||||
|
|
||||||
|
// create ref of object
|
||||||
|
let binding = self.obj_p.clone();
|
||||||
|
let child = binding.file_name();
|
||||||
|
self.obj_p.pop();
|
||||||
|
self.obj_p.push(child.unwrap().to_str().unwrap());
|
||||||
|
let mut file = OpenOptions::new()
|
||||||
|
.create_new(true)
|
||||||
|
.write(true)
|
||||||
|
.open(self.obj_p.clone())?;
|
||||||
|
writeln!(file, "{}", &content)?;
|
||||||
|
|
||||||
// update date for all parent
|
// update date for all parent
|
||||||
if up_parent {
|
if up_parent {
|
||||||
update_dates(self.path.clone(), ts_remote)?;
|
update_dates(self.r_path.clone(), ts_remote)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -90,10 +112,10 @@ impl Blob {
|
|||||||
let (line, _) = self.get_line_filename();
|
let (line, _) = self.get_line_filename();
|
||||||
|
|
||||||
// remove blob reference to parent
|
// remove blob reference to parent
|
||||||
if self.path.iter().count() == 1 {
|
if self.r_path.iter().count() == 1 {
|
||||||
head::rm_line(&line)?;
|
head::rm_line(&line)?;
|
||||||
} else {
|
} else {
|
||||||
rm_node(self.path.parent().unwrap(), &line)?;
|
rm_node(self.r_path.parent().unwrap(), &line)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove blob object
|
// remove blob object
|
||||||
@ -101,4 +123,57 @@ impl Blob {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_data(&mut self) {
|
||||||
|
if self.data.len() == 0 {
|
||||||
|
if let Ok(mut file) = File::open(self.obj_p.clone()) {
|
||||||
|
let mut buffer = String::new();
|
||||||
|
let _ = file.read_to_string(&mut buffer);
|
||||||
|
let data = buffer.rsplit(' ').collect::<Vec<_>>();
|
||||||
|
for e in data {
|
||||||
|
self.data.push(String::from(e));
|
||||||
|
}
|
||||||
|
self.data.reverse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_same_size(&mut self) -> bool {
|
||||||
|
let metadata = match fs::metadata(self.a_path.clone()) {
|
||||||
|
Ok(m) => m,
|
||||||
|
Err(_) => return true,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.read_data();
|
||||||
|
if self.data.len() < 3 { return true; }
|
||||||
|
metadata.len().to_string() == self.data[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_newer(&mut self) -> bool {
|
||||||
|
let metadata = match fs::metadata(self.a_path.clone()) {
|
||||||
|
Ok(m) => m,
|
||||||
|
Err(_) => return true,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.read_data();
|
||||||
|
let secs = metadata
|
||||||
|
.modified()
|
||||||
|
.unwrap()
|
||||||
|
.duration_since(SystemTime::UNIX_EPOCH)
|
||||||
|
.unwrap()
|
||||||
|
.as_secs();
|
||||||
|
if self.data.len() < 4 { return true; }
|
||||||
|
secs > self.data[3].parse::<u64>().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_same_hash(&mut self) -> bool {
|
||||||
|
self.read_data();
|
||||||
|
if self.data.len() < 5 { return false; }
|
||||||
|
self.data[4] == self.get_file_hash()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn has_change(&mut self) -> bool {
|
||||||
|
!self.has_same_size() || (self.is_newer() && !self.has_same_hash())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user