diff --git a/src/commands/add.rs b/src/commands/add.rs index fc032c1..8b31e12 100644 --- a/src/commands/add.rs +++ b/src/commands/add.rs @@ -5,7 +5,10 @@ use colored::Colorize; use crate::models::blob::Blob; use crate::models::index::{FileMetaData, Index}; -use crate::utils::util::{check_repo_exist, get_relative_path, get_working_dir, list_files}; +use crate::utils::util::{ + check_repo_exist, get_working_dir, is_inside_repo, is_inside_workdir, list_files, to_workdir_relative_path, + ROOT_DIR, +}; // TODO: fatal: ../moj/app.py: '../moj/app.py' is outside repository at 'Git-Rust' pub fn add(files: Vec, all: bool, mut update: bool) { @@ -50,8 +53,18 @@ pub fn add(files: Vec, all: bool, mut update: bool) { } fn add_a_file(file: &Path, index: &mut Index) { - let relative_path = get_relative_path(file, &get_working_dir().unwrap()); + if !is_inside_workdir(file) { + //文件不在工作区内 + println!("fatal: '{}' is outside repository at '{}'", file.display(), get_working_dir().unwrap().display()); + return; + } + if is_inside_repo(file) { + //文件在.mit内 + println!("fatal: '{}' is inside '{}' repo", file.display(), ROOT_DIR); + return; + } + let relative_path = to_workdir_relative_path(file); if !file.exists() { //文件被删除 index.remove(file); diff --git a/src/utils/util.rs b/src/utils/util.rs index d2b8afa..a7b50d9 100644 --- a/src/utils/util.rs +++ b/src/utils/util.rs @@ -123,6 +123,26 @@ pub fn get_working_dir() -> Option { } } +/// 检查文件是否在dir内(包括子文件夹), 若不存在则false +pub fn is_inside_dir(file: &Path, dir: &Path) -> bool { + if file.exists() { + let file = get_absolute_path(file); + file.starts_with(dir) + } else { + false + } +} + +/// 检查文件是否在工作区内, 若不存在则false +pub fn is_inside_workdir(file: &Path) -> bool { + is_inside_dir(file, &get_working_dir().unwrap()) +} + +/// 检查文件是否在.mit内, 若不存在则false +pub fn is_inside_repo(file: &Path) -> bool { + is_inside_dir(file, &get_storage_path().unwrap()) +} + pub fn format_time(time: &std::time::SystemTime) -> String { let datetime: chrono::DateTime = time.clone().into(); datetime.format("%Y-%m-%d %H:%M:%S.%3f").to_string() @@ -256,10 +276,21 @@ mod tests { } } + #[test] + fn test_is_inside_repo() { + setup_test_with_mit(); + let path = Path::new("../Cargo.toml"); + assert_eq!(is_inside_workdir(path), false); + + let path = Path::new(".mit/HEAD"); + assert_eq!(is_inside_workdir(path), true); + } + #[test] fn test_format_time() { let time = std::time::SystemTime::now(); let formatted_time = format_time(&time); + println!("{:?}", time); println!("{}", formatted_time); }