mirror of
https://github.com/MrBeanCpp/MIT.git
synced 2026-02-07 04:13:50 +08:00
完善add逻辑
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
use std::env;
|
||||
use std::path::{Path, PathBuf};
|
||||
use colored::Colorize;
|
||||
use sha1::Digest;
|
||||
use crate::models::blob::Blob;
|
||||
use crate::models::index::{FileMetaData, Index};
|
||||
use crate::utils::util::{check_repo_exist, get_file_mode, get_relative_path, get_working_dir, list_files};
|
||||
use crate::utils::util::{check_repo_exist, get_relative_path, get_working_dir, list_files};
|
||||
|
||||
pub fn add(files: Vec<String>, all: bool, mut update: bool) {
|
||||
check_repo_exist();
|
||||
@@ -41,23 +42,21 @@ pub fn add(files: Vec<String>, all: bool, mut update: bool) {
|
||||
for file in &files {
|
||||
add_a_file(file, &mut index);
|
||||
}
|
||||
|
||||
index.save();
|
||||
}
|
||||
|
||||
fn add_a_file(file: &Path, index: &mut Index) {
|
||||
println!("add a file: {}", get_relative_path(file, get_working_dir().unwrap()).display());
|
||||
if !file.exists() { //文件被删除
|
||||
index.remove(file);
|
||||
} else if !index.contains(file) { //文件未被跟踪
|
||||
} else {
|
||||
let blob = Blob::new(file);
|
||||
let meta = file.metadata().unwrap();
|
||||
index.add(file.to_path_buf(), FileMetaData{
|
||||
hash: blob.get_hash(),
|
||||
size: meta.len(),
|
||||
created_time: meta.created().unwrap(),
|
||||
modified_time: meta.modified().unwrap(),
|
||||
mode: get_file_mode(file)
|
||||
});
|
||||
} else { //文件已被跟踪,可能被修改
|
||||
|
||||
let file_data = FileMetaData::new(&blob, file);
|
||||
if !index.contains(file) { //文件未被跟踪
|
||||
index.add(file.to_path_buf(), file_data);
|
||||
} else { //文件已被跟踪,可能被修改
|
||||
index.update(file.to_path_buf(), file_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,13 @@ pub struct Blob {
|
||||
}
|
||||
|
||||
impl Blob {
|
||||
/// 从源文件新建blob对象,并直接保存到/objects/中
|
||||
pub fn new(file: &Path) -> Blob {
|
||||
let data = fs::read_to_string(file).unwrap();
|
||||
let hash = calc_hash(&data);
|
||||
Blob { hash, data }
|
||||
let blob = Blob { hash, data };
|
||||
blob.save();
|
||||
blob
|
||||
}
|
||||
|
||||
pub fn load(hash: &String) -> Blob {
|
||||
@@ -32,7 +35,10 @@ impl Blob {
|
||||
|
||||
pub fn save(&self) {
|
||||
let s = Store::new();
|
||||
s.save(&self.data);
|
||||
if !s.contains(&self.hash) {
|
||||
let hash = s.save(&self.data);
|
||||
assert_eq!(hash, self.hash);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_hash(&self) -> String {
|
||||
|
||||
@@ -3,8 +3,9 @@ use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::time::SystemTime;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use crate::models::blob::Blob;
|
||||
use crate::models::object::Hash;
|
||||
use crate::utils::util::get_working_dir;
|
||||
use crate::utils::util::{get_file_mode, get_working_dir};
|
||||
|
||||
// 文件元数据结构
|
||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||
@@ -16,6 +17,19 @@ pub struct FileMetaData {
|
||||
pub mode: String, // 文件模式
|
||||
}
|
||||
|
||||
impl FileMetaData {
|
||||
pub fn new(blob: &Blob, file: &Path) -> FileMetaData {
|
||||
let meta = file.metadata().unwrap();
|
||||
FileMetaData {
|
||||
hash: blob.get_hash(),
|
||||
size: meta.len(),
|
||||
created_time: meta.created().unwrap(),
|
||||
modified_time: meta.modified().unwrap(),
|
||||
mode: get_file_mode(file)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 索引数据结构
|
||||
#[derive(Serialize, Deserialize, Debug, Default)]
|
||||
pub struct Index {
|
||||
@@ -69,12 +83,16 @@ impl Index {
|
||||
files
|
||||
}
|
||||
|
||||
pub fn update(&mut self, path: PathBuf, data: FileMetaData) {
|
||||
self.entries.insert(path, data);
|
||||
}
|
||||
|
||||
fn load(&mut self) {
|
||||
|
||||
}
|
||||
|
||||
/// 二进制序列化
|
||||
fn save(&self) { //要先转化为相对路径
|
||||
pub fn save(&self) { //要先转化为相对路径
|
||||
let ser = serde_json::to_string(&self).unwrap();
|
||||
println!("{}", ser);
|
||||
}
|
||||
@@ -97,8 +115,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_save(){
|
||||
util::setup_test_with_mit();
|
||||
let mut index = Index::new();
|
||||
let metadata = fs::metadata(".gitignore").unwrap();
|
||||
let metadata = fs::metadata("../.gitignore").unwrap();
|
||||
let file_meta_data = FileMetaData {
|
||||
hash: "123".to_string(),
|
||||
size: metadata.len(),
|
||||
|
||||
@@ -24,6 +24,14 @@ impl Store {
|
||||
Err(_) => panic!("储存库疑似损坏,无法读取文件"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn contains(&self, hash: &String) -> bool {
|
||||
let mut path = self.store_path.clone();
|
||||
path.push("objects");
|
||||
path.push(hash);
|
||||
path.exists()
|
||||
}
|
||||
|
||||
pub fn save(&self, content: &String) -> String {
|
||||
/* 保存文件内容 */
|
||||
println!("store_path: {:?}", self.store_path);
|
||||
@@ -41,7 +49,6 @@ impl Store {
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user