mirror of
https://github.com/MrBeanCpp/MIT.git
synced 2026-07-05 02:36:04 +08:00
修改Blob逻辑,主要变更为 Blob 与 objects文件解构。store作为与objects文件交互的唯一依赖。具体为:
1. Blob使用Content新建而不是path 2. workdir的读写能力由util::read|write workfile提供 3. 判断文件是否更改不直接计算hash,经由新建一个不保存的Blob进行。现在Hash算法只由Store决定。
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use sha1::{Digest, Sha1};
|
||||
|
||||
use crate::models::Hash;
|
||||
|
||||
use super::util;
|
||||
@@ -13,6 +15,13 @@ pub struct Store {
|
||||
* 每一个object文件名与内容的hash值相同
|
||||
*/
|
||||
impl Store {
|
||||
fn calc_hash(data: &String) -> String {
|
||||
let mut hasher = Sha1::new();
|
||||
hasher.update(data);
|
||||
let hash = hasher.finalize();
|
||||
hex::encode(hash)
|
||||
}
|
||||
|
||||
pub fn new() -> Store {
|
||||
util::check_repo_exist();
|
||||
let store_path = util::get_storage_path().unwrap();
|
||||
@@ -29,16 +38,6 @@ impl Store {
|
||||
}
|
||||
}
|
||||
|
||||
/// 将hash对应的文件内容(主要是blob)还原到file
|
||||
pub fn restore_to_file(&self, hash: &Hash, file: &PathBuf) {
|
||||
let content = self.load(hash);
|
||||
// 保证文件层次存在
|
||||
let mut parent = file.clone();
|
||||
parent.pop();
|
||||
std::fs::create_dir_all(parent).unwrap();
|
||||
std::fs::write(file, content).unwrap();
|
||||
}
|
||||
|
||||
/** 根据前缀搜索,有歧义时返回 None */
|
||||
pub fn search(&self, hash: &String) -> Option<Hash> {
|
||||
if hash.is_empty() {
|
||||
@@ -65,10 +64,9 @@ impl Store {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn save(&self, content: &String) -> String {
|
||||
pub fn save(&self, content: &String) -> Hash {
|
||||
/* 保存文件内容 */
|
||||
let hash = util::calc_hash(content);
|
||||
let hash = Self::calc_hash(content);
|
||||
let mut path = self.store_path.clone();
|
||||
path.push("objects");
|
||||
path.push(&hash);
|
||||
@@ -82,6 +80,13 @@ impl Store {
|
||||
Err(_) => panic!("储存库疑似损坏,无法写入文件"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn dry_save(&self, content: &String) -> Hash {
|
||||
/* 不实际保存文件,返回Hash */
|
||||
let hash = Self::calc_hash(content);
|
||||
// TODO more such as check
|
||||
hash
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use sha1::{Digest, Sha1};
|
||||
|
||||
use std::{
|
||||
collections::HashSet,
|
||||
fs, io,
|
||||
@@ -10,18 +10,6 @@ use crate::models::{commit::Commit, object::Hash, tree::Tree};
|
||||
pub const ROOT_DIR: &str = ".mit";
|
||||
|
||||
/* tools for mit */
|
||||
pub fn calc_hash(data: &String) -> String {
|
||||
let mut hasher = Sha1::new();
|
||||
hasher.update(data);
|
||||
let hash = hasher.finalize();
|
||||
hex::encode(hash)
|
||||
}
|
||||
|
||||
/// 计算文件的hash
|
||||
pub fn calc_file_hash(path: &Path) -> String {
|
||||
let data = fs::read_to_string(path).expect(&format!("无法读取文件:{}", path.display()));
|
||||
calc_hash(&data)
|
||||
}
|
||||
|
||||
pub fn storage_exist() -> bool {
|
||||
/*检查是否存在储存库 */
|
||||
@@ -427,11 +415,25 @@ pub fn is_typeof_commit(hash: Hash) -> bool {
|
||||
check_object_type(hash) == ObjectType::Commit
|
||||
}
|
||||
|
||||
|
||||
/// 将内容对应的文件内容(主要是blob)还原到file
|
||||
pub fn write_workfile(content: String, file: &PathBuf) {
|
||||
let mut parent = file.clone();
|
||||
parent.pop();
|
||||
std::fs::create_dir_all(parent).unwrap();
|
||||
std::fs::write(file, content).unwrap();
|
||||
}
|
||||
|
||||
/// 从工作区读取文件内容
|
||||
pub fn read_workfile(file: &Path) -> String {
|
||||
std::fs::read_to_string(file).unwrap()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
models::{blob::Blob, index::Index},
|
||||
utils::{test_util, util::*},
|
||||
utils::{test_util, util::{*, self}},
|
||||
};
|
||||
|
||||
#[test]
|
||||
@@ -536,7 +538,8 @@ mod tests {
|
||||
test_util::setup_test_with_clean_mit();
|
||||
assert_eq!(check_object_type("123".into()), ObjectType::Invalid);
|
||||
test_util::ensure_test_file(Path::new("test.txt"), Some("test"));
|
||||
let hash = Blob::new(get_working_dir().unwrap().join("test.txt").as_path()).get_hash();
|
||||
let content = util::read_workfile(get_working_dir().unwrap().join("test.txt").as_path());
|
||||
let hash = Blob::new(content).get_hash();
|
||||
assert_eq!(check_object_type(hash), ObjectType::Blob);
|
||||
let mut commit = Commit::new(&Index::get_instance(), vec![], "test".to_string());
|
||||
assert_eq!(check_object_type(commit.get_tree_hash()), ObjectType::Tree);
|
||||
|
||||
Reference in New Issue
Block a user