diff --git a/src/commands/add.rs b/src/commands/add.rs index a7c3991..e788ade 100644 --- a/src/commands/add.rs +++ b/src/commands/add.rs @@ -1,87 +1,69 @@ -use std::{ - env, - path::{Path, PathBuf}, -}; +use std::path::{Path, PathBuf}; use colored::Colorize; -use crate::{ - models::{ - blob::Blob, - index::{FileMetaData, Index}, - }, - utils::util::{ - check_repo_exist, get_working_dir, is_inside_repo, is_inside_workdir, list_files, to_workdir_relative_path, - ROOT_DIR, - }, +use crate::commands::status; +use crate::models::{ + blob::Blob, + index::{FileMetaData, Index}, }; +use crate::utils::util; -pub fn add(files: Vec, all: bool, mut update: bool) { - check_repo_exist(); - let mut index = Index::new(); - let mut dot = files.contains(&".".to_string()); +/// add是对index的操作,不会对工作区产生影响 +pub fn add(raw_paths: Vec, all: bool, mut update: bool) { + util::check_repo_exist(); - let mut files: Vec = files.into_iter().map(PathBuf::from).collect(); - - if dot || all || update { - //TODO files中可能包含文件夹,需要统计文件夹中被删除的文件 - if all { - // all 优先级最高 - dot = false; - update = false; - } else if update { - // update 优先级次之 - dot = false; - } - - let dir = if all || update { - println!("{}", "--all || --update 运行于工作区目录".bright_green()); - get_working_dir().unwrap() - } else if dot { - println!("{}", "'.'代表了当前目录".bright_green()); - env::current_dir().unwrap() - } else { - panic!(); - }; - - println!("Working on [{}]\n", dir.to_str().unwrap().bright_blue()); - files = list_files(&dir).unwrap(); - if update { - files.retain(|file| index.contains(file)); - } - - files.extend(index.get_deleted_files(&dir)); //包含已删除的文件 + let mut paths: Vec = raw_paths.into_iter().map(PathBuf::from).collect(); + if all || update { + println!("{}", "--all || --update 对工作区所有文件进行操作".bright_green()); + paths.push(util::get_working_dir().unwrap()); + } + if all { + update = false; // all 优先级最高 } + //待暂存的更改: index vs worktree + let changes = status::changes_to_be_staged().filter_relative(&paths); //对paths过滤 + let mut files = changes.modified; + //统合所有更改到files再一起处理,其实也可以直接根据changes的分类进行处理 主要是为了错误处理 而且思想上更?简单? + files.extend(changes.deleted); + if !update { + files.extend(changes.new); + } else { + println!("{}", "--update 只对已跟踪文件进行操作 不包含new".bright_green()); + } + + let mut index = Index::new(); for file in &files { add_a_file(file, &mut index); } } fn add_a_file(file: &Path, index: &mut Index) { - if !is_inside_workdir(file) && file.exists() { + let workdir = util::get_working_dir().unwrap(); + if !util::is_sub_path(file, &workdir) { //文件不在工作区内 - println!("fatal: '{}' is outside repository at '{}'", file.display(), get_working_dir().unwrap().display()); + println!("fatal: '{}' is outside workdir at '{}'", file.display(), workdir.display()); return; } - if is_inside_repo(file) { + if util::is_inside_repo(file) { //文件在.mit内 - println!("fatal: '{}' is inside '{}' repo", file.display(), ROOT_DIR); + println!("fatal: '{}' is inside '{}' repo", file.display(), util::ROOT_DIR); return; } - let relative_path = to_workdir_relative_path(file); + let rel_path = util::to_cur_relative_path(file); if !file.exists() { //文件被删除 index.remove(file); - println!("removed: {}", relative_path.display()); + println!("removed: {}", rel_path.display()); } else { //文件存在 if !index.contains(file) { //文件未被跟踪 let blob = Blob::new(file); index.add(file.to_path_buf(), FileMetaData::new(&blob, file)); - println!("add(stage): {}", relative_path.display()); + println!("add(stage): {}", rel_path.display()); } else { //文件已被跟踪,可能被修改 if index.is_modified(file) { @@ -90,7 +72,7 @@ fn add_a_file(file: &Path, index: &mut Index) { if !index.verify_hash(file, &blob.get_hash()) { //比较hash 确认内容更改 index.update(file.to_path_buf(), FileMetaData::new(&blob, file)); - println!("add(modified): {}", relative_path.display()); + println!("add(modified): {}", rel_path.display()); } } } diff --git a/src/commands/status.rs b/src/commands/status.rs index 88f901e..9be5dc3 100644 --- a/src/commands/status.rs +++ b/src/commands/status.rs @@ -5,7 +5,6 @@ use crate::{ utils::{util, util::check_repo_exist}, }; use colored::Colorize; -use std::env; use std::path::PathBuf; /** 获取需要commit的更改(staged) @@ -139,7 +138,6 @@ pub fn changes_to_be_staged() -> Changes { */ pub fn status() { check_repo_exist(); - //TODO: 输出文件与当前所在目录有关 输出时过滤 match head::current_head() { Head::Detached(commit) => { println!("HEAD detached at {}", commit[0..7].to_string()); diff --git a/src/store.rs b/src/store.rs index c0b0a0e..5f8ee31 100644 --- a/src/store.rs +++ b/src/store.rs @@ -75,7 +75,7 @@ impl Store { let mut path = self.store_path.clone(); path.push("objects"); path.push(&hash); - println!("Saved to: [{}]", path.display()); + // println!("Saved to: [{}]", path.display()); match std::fs::write(path, content) { Ok(_) => hash, Err(_) => panic!("储存库疑似损坏,无法写入文件"),