mirror of
https://github.com/MrBeanCpp/MIT.git
synced 2026-02-03 18:33:46 +08:00
fix: 用status重构add,正确处理文件夹中被删除的文件
This commit is contained in:
@@ -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<String>, 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<String>, all: bool, mut update: bool) {
|
||||
util::check_repo_exist();
|
||||
|
||||
let mut files: Vec<PathBuf> = 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<PathBuf> = 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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!("储存库疑似损坏,无法写入文件"),
|
||||
|
||||
Reference in New Issue
Block a user