mirror of
https://github.com/MrBeanCpp/MIT.git
synced 2026-04-23 18:31:16 +08:00
fix: 用status重构add,正确处理文件夹中被删除的文件
This commit is contained in:
@@ -1,87 +1,69 @@
|
|||||||
use std::{
|
use std::path::{Path, PathBuf};
|
||||||
env,
|
|
||||||
path::{Path, PathBuf},
|
|
||||||
};
|
|
||||||
|
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
|
|
||||||
use crate::{
|
use crate::commands::status;
|
||||||
models::{
|
use crate::models::{
|
||||||
blob::Blob,
|
blob::Blob,
|
||||||
index::{FileMetaData, Index},
|
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::utils::util;
|
||||||
|
|
||||||
pub fn add(files: Vec<String>, all: bool, mut update: bool) {
|
/// add是对index的操作,不会对工作区产生影响
|
||||||
check_repo_exist();
|
pub fn add(raw_paths: Vec<String>, all: bool, mut update: bool) {
|
||||||
let mut index = Index::new();
|
util::check_repo_exist();
|
||||||
let mut dot = files.contains(&".".to_string());
|
|
||||||
|
|
||||||
let mut files: Vec<PathBuf> = files.into_iter().map(PathBuf::from).collect();
|
let mut paths: Vec<PathBuf> = raw_paths.into_iter().map(PathBuf::from).collect();
|
||||||
|
if all || update {
|
||||||
if dot || all || update {
|
println!("{}", "--all || --update 对工作区所有文件进行操作".bright_green());
|
||||||
//TODO files中可能包含文件夹,需要统计文件夹中被删除的文件
|
paths.push(util::get_working_dir().unwrap());
|
||||||
if all {
|
}
|
||||||
// all 优先级最高
|
if all {
|
||||||
dot = false;
|
update = false; // all 优先级最高
|
||||||
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)); //包含已删除的文件
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//待暂存的更改: 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 {
|
for file in &files {
|
||||||
add_a_file(file, &mut index);
|
add_a_file(file, &mut index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_a_file(file: &Path, index: &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;
|
return;
|
||||||
}
|
}
|
||||||
if is_inside_repo(file) {
|
if util::is_inside_repo(file) {
|
||||||
//文件在.mit内
|
//文件在.mit内
|
||||||
println!("fatal: '{}' is inside '{}' repo", file.display(), ROOT_DIR);
|
println!("fatal: '{}' is inside '{}' repo", file.display(), util::ROOT_DIR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let relative_path = to_workdir_relative_path(file);
|
let rel_path = util::to_cur_relative_path(file);
|
||||||
if !file.exists() {
|
if !file.exists() {
|
||||||
//文件被删除
|
//文件被删除
|
||||||
index.remove(file);
|
index.remove(file);
|
||||||
println!("removed: {}", relative_path.display());
|
println!("removed: {}", rel_path.display());
|
||||||
} else {
|
} else {
|
||||||
//文件存在
|
//文件存在
|
||||||
if !index.contains(file) {
|
if !index.contains(file) {
|
||||||
//文件未被跟踪
|
//文件未被跟踪
|
||||||
let blob = Blob::new(file);
|
let blob = Blob::new(file);
|
||||||
index.add(file.to_path_buf(), FileMetaData::new(&blob, file));
|
index.add(file.to_path_buf(), FileMetaData::new(&blob, file));
|
||||||
println!("add(stage): {}", relative_path.display());
|
println!("add(stage): {}", rel_path.display());
|
||||||
} else {
|
} else {
|
||||||
//文件已被跟踪,可能被修改
|
//文件已被跟踪,可能被修改
|
||||||
if index.is_modified(file) {
|
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()) {
|
if !index.verify_hash(file, &blob.get_hash()) {
|
||||||
//比较hash 确认内容更改
|
//比较hash 确认内容更改
|
||||||
index.update(file.to_path_buf(), FileMetaData::new(&blob, file));
|
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},
|
utils::{util, util::check_repo_exist},
|
||||||
};
|
};
|
||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use std::env;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
/** 获取需要commit的更改(staged)
|
/** 获取需要commit的更改(staged)
|
||||||
@@ -139,7 +138,6 @@ pub fn changes_to_be_staged() -> Changes {
|
|||||||
*/
|
*/
|
||||||
pub fn status() {
|
pub fn status() {
|
||||||
check_repo_exist();
|
check_repo_exist();
|
||||||
//TODO: 输出文件与当前所在目录有关 输出时过滤
|
|
||||||
match head::current_head() {
|
match head::current_head() {
|
||||||
Head::Detached(commit) => {
|
Head::Detached(commit) => {
|
||||||
println!("HEAD detached at {}", commit[0..7].to_string());
|
println!("HEAD detached at {}", commit[0..7].to_string());
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ impl Store {
|
|||||||
let mut path = self.store_path.clone();
|
let mut path = self.store_path.clone();
|
||||||
path.push("objects");
|
path.push("objects");
|
||||||
path.push(&hash);
|
path.push(&hash);
|
||||||
println!("Saved to: [{}]", path.display());
|
// println!("Saved to: [{}]", path.display());
|
||||||
match std::fs::write(path, content) {
|
match std::fs::write(path, content) {
|
||||||
Ok(_) => hash,
|
Ok(_) => hash,
|
||||||
Err(_) => panic!("储存库疑似损坏,无法写入文件"),
|
Err(_) => panic!("储存库疑似损坏,无法写入文件"),
|
||||||
|
|||||||
Reference in New Issue
Block a user