use std::path::{Path, PathBuf};
use colored::Colorize;
use crate::commands::status;
use crate::models::index::FileMetaData;
use crate::models::*;
use crate::utils::util;
/// add是对index的操作,不会对工作区产生影响
/// @see git add .,git add -A,git add -u,git add * 的区别与联系
pub fn add(raw_paths: Vec, all: bool, mut update: bool) {
util::check_repo_exist();
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 index = Index::get_instance();
for file in &files {
add_a_file(file, index);
}
index.save();
}
fn add_a_file(file: &Path, index: &mut Index) {
let workdir = util::get_working_dir().unwrap();
if !util::is_sub_path(file, &workdir) {
//文件不在工作区内
println!("fatal: '{}' is outside workdir at '{}'", file.display(), workdir.display());
return;
}
if util::is_inside_repo(file) {
//文件在.mit内
println!("fatal: '{}' is inside '{}' repo", file.display(), util::ROOT_DIR);
return;
}
let rel_path = util::to_cur_relative_path(file);
if !file.exists() {
//文件被删除
index.remove(file);
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): {}", rel_path.display());
} else {
//文件已被跟踪,可能被修改
if index.is_modified(file) {
//文件被修改,但不一定内容更改
let blob = Blob::new(file); //到这一步才创建blob是为了优化
if !index.verify_hash(file, &blob.get_hash()) {
//比较hash 确认内容更改
index.update(file.to_path_buf(), FileMetaData::new(&blob, file));
println!("add(modified): {}", rel_path.display());
}
}
}
}
}