diff --git a/src/commands/status.rs b/src/commands/status.rs index e36b89b..8aa91be 100644 --- a/src/commands/status.rs +++ b/src/commands/status.rs @@ -1,6 +1,10 @@ use std::path::PathBuf; -use crate::{head, models::index, utils::util}; +use crate::{ + head, + models::{blob, index}, + utils::util, +}; /** 获取需要commit的更改 */ pub struct Changes { @@ -37,25 +41,90 @@ pub fn changes_to_be_committed() -> Changes { let commit = crate::models::commit::Commit::load(&head_hash); let tree = commit.get_tree(); - let mut tree_files = tree.get_recursive_blobs(); - let mut index_files: Vec = index + let tree_files = tree.get_recursive_blobs(); + let index_files: Vec = index .get_tracked_files() .iter() .map(|f| util::to_root_relative_path(f)) .collect(); for tree_item in tree_files.iter() { - if index_files.contains(&tree_item.0) { - // 比较文件内容 - // XXX @mrbeanc 我看到Blob的new被改成调用save了。这里的实现希望比较Blob内容,不然就得读取文件内容。 - } else { + 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)); + } else { + let index_blob = blob::Blob::new( + util::get_working_dir() + .unwrap() + .join(index_file.unwrap()) + .as_path(), + ); + // XXX @mrbeanc 我看到Blob的new被改成调用save了。这里的实现希望比较Blob内容,不然就得读取文件内容。 + if index_blob.get_hash() != tree_item.1.get_hash() { + change.modified.push(__file_string(&tree_item.0)); + } + } + } + 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 } pub fn status() { unimplemented!() } + +#[cfg(test)] +mod tests { + use super::*; + use crate::{commands::commit, utils::util}; + use std::{fs, path::Path}; + + #[test] + fn test_changes_to_be_committed() { + util::setup_test_with_clean_mit(); + let test_file = "a.txt"; + util::ensure_test_file(Path::new(test_file), None); + + commit::commit("test commit".to_string(), true); + let mut index = index::Index::new(); + index.add( + PathBuf::from(test_file), + index::FileMetaData::new(&blob::Blob::new(Path::new(test_file)), Path::new(test_file)), + ); + index.save(); + let change = changes_to_be_committed(); + assert_eq!(change.new.len(), 1); + assert_eq!(change.modified.len(), 0); + assert_eq!(change.deleted.len(), 0); + + commit::commit("test commit".to_string(), true); + util::ensure_test_file(Path::new(test_file), Some("new content")); + index.add( + PathBuf::from(test_file), + index::FileMetaData::new(&blob::Blob::new(Path::new(test_file)), Path::new(test_file)), + ); + index.save(); + let change = changes_to_be_committed(); + assert_eq!(change.new.len(), 0); + assert_eq!(change.modified.len(), 1); + assert_eq!(change.deleted.len(), 0); + + commit::commit("test commit".to_string(), true); + index.remove( + util::get_working_dir() + .unwrap() + .join(Path::new(test_file)) + .as_path(), + ); + index.save(); + let change = changes_to_be_committed(); + assert_eq!(change.new.len(), 0); + assert_eq!(change.modified.len(), 0); + assert_eq!(change.deleted.len(), 1); + } +}