mirror of
https://github.com/MrBeanCpp/MIT.git
synced 2026-02-11 14:15:58 +08:00
优化changes_to_be_committed()
This commit is contained in:
@@ -2,20 +2,21 @@ use std::path::PathBuf;
|
||||
|
||||
use crate::{
|
||||
head,
|
||||
models::{blob, index},
|
||||
models::{blob, index, commit},
|
||||
utils::util,
|
||||
};
|
||||
use crate::utils::util::to_workdir_absolute_path;
|
||||
|
||||
/** 获取需要commit的更改(staged) */
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Changes {
|
||||
pub new: Vec<String>,
|
||||
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()
|
||||
util::to_root_relative_path(path) //todo: to_string_lossy()
|
||||
.as_os_str()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
@@ -23,51 +24,40 @@ fn __file_string(path: &PathBuf) -> String {
|
||||
}
|
||||
|
||||
pub fn changes_to_be_committed() -> Changes {
|
||||
let mut change = Changes { //todo: Changes::default()
|
||||
new: vec![],
|
||||
modified: vec![],
|
||||
deleted: vec![],
|
||||
};
|
||||
let mut change = Changes::default();
|
||||
let index = index::Index::new();
|
||||
let head_hash = head::current_head_commit();
|
||||
if head_hash == "".to_string() { //todo: head_hash.is_empty() or head_hash == ""
|
||||
// 初始提交
|
||||
change.new = index
|
||||
.get_tracked_files()
|
||||
let tracked_files = index.get_tracked_files();
|
||||
if head_hash == "" { // 初始提交
|
||||
change.new = tracked_files
|
||||
.iter()
|
||||
.map(|f| __file_string(f))
|
||||
.map(__file_string)
|
||||
.collect();
|
||||
return change;
|
||||
}
|
||||
|
||||
let commit = crate::models::commit::Commit::load(&head_hash);
|
||||
let commit = commit::Commit::load(&head_hash);
|
||||
let tree = commit.get_tree();
|
||||
let tree_files = tree.get_recursive_blobs();
|
||||
let index_files: Vec<PathBuf> = index
|
||||
.get_tracked_files()
|
||||
let tree_files = tree.get_recursive_blobs(); //相对路径
|
||||
let index_files: Vec<PathBuf> = tracked_files
|
||||
.iter()
|
||||
.map(|f| util::to_root_relative_path(f))
|
||||
.collect();
|
||||
|
||||
for tree_item in tree_files.iter() {
|
||||
let index_file = index_files.iter().find(|f| **f == tree_item.0);
|
||||
if index_file.is_none() {
|
||||
change.deleted.push(__file_string(&tree_item.0)); //todo: abs_path?
|
||||
} else {
|
||||
let index_blob = blob::Blob::new( //todo: index有函数可以获取blob_hash 不需要new
|
||||
util::get_working_dir() //todo: 优化:提取为变量
|
||||
.unwrap()
|
||||
.join(index_file.unwrap())
|
||||
.as_path(),
|
||||
);
|
||||
// XXX @mrbeanc 我看到Blob的new被改成调用save了。这里的实现希望比较Blob内容,不然就得读取文件内容。
|
||||
if index_blob.get_hash() != tree_item.1.get_hash() {
|
||||
let index_file = index_files.iter().find(|&f| *f == tree_item.0);
|
||||
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));
|
||||
}
|
||||
} else {
|
||||
change.deleted.push(__file_string(&tree_item.0)); //todo: abs_path?
|
||||
}
|
||||
|
||||
}
|
||||
for index_file in index_files.iter() {
|
||||
let tree_item = tree_files.iter().find(|f| f.0 == **index_file);
|
||||
let tree_item = tree_files.iter().find(|f| f.0 == *index_file);
|
||||
if tree_item.is_none() {
|
||||
change.new.push(__file_string(&index_file));
|
||||
}
|
||||
@@ -87,7 +77,7 @@ pub fn status() {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{commands::commit, utils::util};
|
||||
use std::{fs, path::Path};
|
||||
use std::{path::Path};
|
||||
|
||||
#[test]
|
||||
fn test_changes_to_be_committed() {
|
||||
@@ -107,6 +97,8 @@ mod tests {
|
||||
assert_eq!(change.modified.len(), 0);
|
||||
assert_eq!(change.deleted.len(), 0);
|
||||
|
||||
println!("{:?}", change);
|
||||
|
||||
commit::commit("test commit".to_string(), true);
|
||||
util::ensure_test_file(Path::new(test_file), Some("new content"));
|
||||
index.add(
|
||||
@@ -119,6 +111,8 @@ mod tests {
|
||||
assert_eq!(change.modified.len(), 1);
|
||||
assert_eq!(change.deleted.len(), 0);
|
||||
|
||||
println!("{:?}", change);
|
||||
|
||||
commit::commit("test commit".to_string(), true);
|
||||
index.remove(
|
||||
util::get_working_dir()
|
||||
@@ -131,5 +125,7 @@ mod tests {
|
||||
assert_eq!(change.new.len(), 0);
|
||||
assert_eq!(change.modified.len(), 0);
|
||||
assert_eq!(change.deleted.len(), 1);
|
||||
|
||||
println!("{:?}", change);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use crate::utils::util;
|
||||
|
||||
pub enum Head {
|
||||
Detached(String),
|
||||
Branch(String),
|
||||
Branch(String), //todo Hash
|
||||
}
|
||||
|
||||
pub fn current_head() -> Head {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
path::{Component, PathBuf},
|
||||
path::{PathBuf},
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -19,6 +19,7 @@ pub struct TreeEntry {
|
||||
pub name: String, // file name
|
||||
}
|
||||
|
||||
/// 相对路径
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Tree {
|
||||
#[serde(skip)]
|
||||
@@ -137,6 +138,7 @@ impl Tree {
|
||||
files
|
||||
}
|
||||
|
||||
///注:相对路径
|
||||
pub fn get_recursive_blobs(&self) -> Vec<(PathBuf, super::blob::Blob)> {
|
||||
let mut blobs = Vec::new();
|
||||
for entry in self.entries.iter() {
|
||||
@@ -151,7 +153,7 @@ impl Tree {
|
||||
sub_blobs
|
||||
.iter()
|
||||
.map(|(path, blob)| {
|
||||
(PathBuf::from(entry.name.clone()).join(path), blob.clone()) //todo: why join?
|
||||
(PathBuf::from(entry.name.clone()).join(path), blob.clone())
|
||||
})
|
||||
.collect::<Vec<(PathBuf, super::blob::Blob)>>()
|
||||
.as_mut(),
|
||||
|
||||
@@ -169,8 +169,13 @@ pub fn to_root_relative_path(path: &Path) -> PathBuf { //todo: rename
|
||||
get_relative_path(path, &get_working_dir().unwrap())
|
||||
}
|
||||
|
||||
/// 获取相较于工作区(Working Dir)的绝对路径
|
||||
pub fn to_workdir_absolute_path(path: &Path) -> PathBuf {
|
||||
get_working_dir().unwrap().join(path)
|
||||
if path.is_relative() {
|
||||
get_working_dir().unwrap().join(path)
|
||||
} else {
|
||||
path.to_path_buf()
|
||||
}
|
||||
}
|
||||
|
||||
fn is_executable(path: &str) -> bool {
|
||||
|
||||
Reference in New Issue
Block a user