类型修改

This commit is contained in:
HouXiaoxuan
2023-12-21 19:04:47 +08:00
parent 72b6f65c83
commit c0cb618f4f
3 changed files with 47 additions and 53 deletions

View File

@@ -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<String>, //todo PathBuf?
pub modified: Vec<String>,
pub deleted: Vec<String>,
}
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<PathBuf>, //todo PathBuf?
pub modified: Vec<PathBuf>,
pub deleted: Vec<PathBuf>,
}
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::<Vec<PathBuf>>();
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<PathBuf> = tracked_files
.iter()
.map(|f| util::to_root_relative_path(f))
.collect();
let index_files: Vec<PathBuf> = 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)),
);

View File

@@ -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 {

View File

@@ -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::<Vec<(PathBuf, super::blob::Blob)>>()
.collect::<Vec<(PathBuf, Hash)>>()
.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())));
}
}