From c0cb618f4f01328657b47f37f8db6ded16a80806 Mon Sep 17 00:00:00 2001 From: HouXiaoxuan Date: Thu, 21 Dec 2023 19:04:47 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/commands/status.rs | 55 ++++++++++++++++++------------------------ src/head.rs | 14 ++++++++--- src/models/tree.rs | 31 +++++++++++------------- 3 files changed, 47 insertions(+), 53 deletions(-) diff --git a/src/commands/status.rs b/src/commands/status.rs index 5aab088..de556f2 100644 --- a/src/commands/status.rs +++ b/src/commands/status.rs @@ -1,65 +1,55 @@ use std::path::PathBuf; +use crate::utils::util::to_workdir_absolute_path; use crate::{ head, - models::{blob, index, commit}, + models::{blob, commit, index}, utils::util, }; -use crate::utils::util::to_workdir_absolute_path; /** 获取需要commit的更改(staged) */ #[derive(Debug, Default)] pub struct Changes { - pub new: Vec, //todo PathBuf? - pub modified: Vec, - pub deleted: Vec, -} - -fn __file_string(path: &PathBuf) -> String { - util::to_root_relative_path(path) //todo: to_string_lossy() - .as_os_str() - .to_str() - .unwrap() - .to_string() + pub new: Vec, //todo PathBuf? + pub modified: Vec, + pub deleted: Vec, } pub fn changes_to_be_committed() -> Changes { let mut change = Changes::default(); let index = index::Index::new(); let head_hash = head::current_head_commit(); - let tracked_files = index.get_tracked_files(); - if head_hash == "" { // 初始提交 - change.new = tracked_files - .iter() - .map(__file_string) - .collect(); + let tracked_files = index + .get_tracked_files() + .iter() + .map(|f| util::to_root_relative_path(f)) + .collect::>(); + if head_hash == "" { + // 初始提交 + change.new = tracked_files; return change; } let commit = commit::Commit::load(&head_hash); let tree = commit.get_tree(); let tree_files = tree.get_recursive_blobs(); //相对路径 - let index_files: Vec = tracked_files - .iter() - .map(|f| util::to_root_relative_path(f)) - .collect(); + let index_files: Vec = tracked_files; - for tree_item in tree_files.iter() { - let index_file = index_files.iter().find(|&f| *f == tree_item.0); + for (tree_file, blob_hash) in tree_files.iter() { + let index_file = index_files.iter().find(|&f| f == tree_file); if let Some(index_file) = index_file { let index_path = to_workdir_absolute_path(index_file); - if !index.verify_hash(&index_path, &tree_item.1.get_hash()) { - change.modified.push(__file_string(&tree_item.0)); + if !index.verify_hash(&index_path, blob_hash) { + change.modified.push(tree_file.clone()); } } else { - change.deleted.push(__file_string(&tree_item.0)); //todo: abs_path? + change.deleted.push(tree_file.clone()); //todo: abs_path? } - } for index_file in index_files.iter() { let tree_item = tree_files.iter().find(|f| f.0 == *index_file); if tree_item.is_none() { - change.new.push(__file_string(&index_file)); + change.new.push(index_file.clone()); } } change @@ -81,7 +71,7 @@ pub fn status() { mod tests { use super::*; use crate::{commands::commit, utils::util}; - use std::{path::Path}; + use std::path::Path; #[test] fn test_changes_to_be_committed() { @@ -91,7 +81,8 @@ mod tests { commit::commit("test commit".to_string(), true); let mut index = index::Index::new(); - index.add( //todo 可以直接调用add函数 + index.add( + //todo 可以直接调用add函数 PathBuf::from(test_file), index::FileMetaData::new(&blob::Blob::new(Path::new(test_file)), Path::new(test_file)), ); diff --git a/src/head.rs b/src/head.rs index e602fe5..7d9ca38 100644 --- a/src/head.rs +++ b/src/head.rs @@ -1,14 +1,17 @@ -use crate::utils::util; +use crate::{models::object::Hash, utils::util}; pub enum Head { Detached(String), - Branch(String), //todo Hash + Branch(Hash), // TODO Hash } pub fn current_head() -> Head { let mut head = util::get_storage_path().unwrap(); head.push("HEAD"); - let head_content = std::fs::read_to_string(head).expect("HEAD文件损坏").trim_end().to_string(); //去除末尾\n + let head_content = std::fs::read_to_string(head) + .expect("HEAD文件损坏") + .trim_end() + .to_string(); //去除末尾\n if head_content.starts_with("ref: refs/heads/") { let branch_name = head_content.trim_start_matches("ref: refs/heads/"); Head::Branch(branch_name.to_string()) @@ -22,7 +25,10 @@ fn update_branch_head(branch_name: &String, commit_hash: &String) { branch.push("refs"); branch.push("heads"); branch.push(branch_name); - std::fs::write(&branch, commit_hash).expect(&format!("无法写入branch in {:?} with {}", branch, commit_hash)); + std::fs::write(&branch, commit_hash).expect(&format!( + "无法写入branch in {:?} with {}", + branch, commit_hash + )); } fn get_branch_head(branch_name: &String) -> String { diff --git a/src/models/tree.rs b/src/models/tree.rs index a1df197..1671c68 100644 --- a/src/models/tree.rs +++ b/src/models/tree.rs @@ -1,7 +1,4 @@ -use std::{ - collections::HashMap, - path::{PathBuf}, -}; +use std::{collections::HashMap, path::PathBuf}; use serde::{Deserialize, Serialize}; @@ -139,28 +136,30 @@ impl Tree { } ///注:相对路径 - pub fn get_recursive_blobs(&self) -> Vec<(PathBuf, super::blob::Blob)> { - let mut blobs = Vec::new(); + pub fn get_recursive_blobs(&self) -> Vec<(PathBuf, Hash)> { + let mut blob_hashs = Vec::new(); for entry in self.entries.iter() { if entry.filemode.0 == "blob" { - let blob = super::blob::Blob::load(&entry.object_hash); //todo: hash only - blobs.push((PathBuf::from(entry.name.clone()), blob)); + blob_hashs.push((PathBuf::from(entry.name.clone()), entry.object_hash.clone())); } else { let sub_tree = Tree::load(&entry.object_hash); let sub_blobs = sub_tree.get_recursive_blobs(); - blobs.append( + blob_hashs.append( sub_blobs .iter() - .map(|(path, blob)| { - (PathBuf::from(entry.name.clone()).join(path), blob.clone()) + .map(|(path, blob_hash)| { + ( + PathBuf::from(entry.name.clone()).join(path), + blob_hash.clone(), + ) }) - .collect::>() + .collect::>() .as_mut(), ); } } - blobs + blob_hashs } } @@ -263,9 +262,7 @@ mod test { let loaded_tree = super::Tree::load(&tree_hash); let blobs = loaded_tree.get_recursive_blobs(); assert!(blobs.len() == test_files.len()); - assert!(blobs[0].0.to_str().unwrap() == test_files[0]); - assert!(blobs[1].0.to_str().unwrap() == test_files[1]); - assert!(blobs[0].1.get_hash() == test_blobs[0].get_hash()); - assert!(blobs[1].1.get_hash() == test_blobs[1].get_hash()); + assert!(blobs.contains(&(PathBuf::from(test_files[0]), test_blobs[0].get_hash()))); + assert!(blobs.contains(&(PathBuf::from(test_files[1]), test_blobs[1].get_hash()))); } }