diff --git a/src/commands/add.rs b/src/commands/add.rs index 256238d..7bae406 100644 --- a/src/commands/add.rs +++ b/src/commands/add.rs @@ -50,13 +50,17 @@ fn add_a_file(file: &Path, index: &mut Index) { println!("add a file: {}", get_relative_path(file, get_working_dir().unwrap()).display()); if !file.exists() { //文件被删除 index.remove(file); - } else { - let blob = Blob::new(file); - let file_data = FileMetaData::new(&blob, file); + } else { //文件存在 if !index.contains(file) { //文件未被跟踪 - index.add(file.to_path_buf(), file_data); + let blob = Blob::new(file); + index.add(file.to_path_buf(), FileMetaData::new(&blob, file)); } else { //文件已被跟踪,可能被修改 - index.update(file.to_path_buf(), file_data); + 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)); + } + } } } } \ No newline at end of file diff --git a/src/models/index.rs b/src/models/index.rs index fcccd61..b30180d 100644 --- a/src/models/index.rs +++ b/src/models/index.rs @@ -59,8 +59,16 @@ impl Index { } // 获取文件元数据 - fn get(&self, path: PathBuf) -> Option<&FileMetaData> { - self.entries.get(&path) + fn get(&self, path: &Path) -> Option<&FileMetaData> { + self.entries.get(path) + } + + pub fn get_hash(&self, file: &Path) -> Option { + Option::from(self.get(file)?.hash.clone()) + } + + pub fn verify_hash(&self, file: &Path, hash: &Hash) -> bool { + &self.get_hash(file).unwrap_or_default() == hash } // 获取所有文件元数据 @@ -83,6 +91,23 @@ impl Index { files } + /// 与暂存区比较,确定文件自上次add以来是否被编辑(内容不一定修改,还需要算hash) + pub fn is_modified(&self, file: &Path) -> bool{ + if let Some(self_data) = self.get(file) { + if let Ok(meta) = file.metadata() { + let same = self_data.created_time == meta.created().unwrap_or(SystemTime::now()) + && self_data.modified_time == meta.modified().unwrap_or(SystemTime::now()) + && self_data.size == meta.len(); + + return !same; + } else { + true + } + } else { + true + } + } + pub fn update(&mut self, path: PathBuf, data: FileMetaData) { self.entries.insert(path, data); }