diff --git a/Cargo.toml b/Cargo.toml index abd5a3a..5a9f4d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,4 +12,5 @@ clap = { version = "4.4.11", features = ["derive"] } chrono = "0.4.31" serde = { version = "1.0.193", features = ["derive"] } serde_json = "1.0.108" -colored = "2.1.0" \ No newline at end of file +colored = "2.1.0" +rand = "0.8.5" diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 78fdf68..7219386 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -1,2 +1,3 @@ pub mod init; -pub mod add; \ No newline at end of file +pub mod add; +pub mod commit; \ No newline at end of file diff --git a/src/head.rs b/src/head.rs new file mode 100644 index 0000000..705fea0 --- /dev/null +++ b/src/head.rs @@ -0,0 +1,72 @@ +use crate::utils::util; + +pub enum Head { + Detached(String), + Branch(String), +} + +pub fn current_head() -> Head { + let mut head = util::get_storage_path().unwrap(); + head.push("HEAD"); + let head_content = std::fs::read_to_string(head).expect("HEAD文件损坏"); + if head_content.starts_with("ref: refs/heads/") { + let branch_name = head_content.trim_start_matches("ref: refs/heads/"); + Head::Branch(branch_name.to_string()) + } else { + Head::Detached(head_content) + } +} + +pub fn update_branch(branch_name: &String, commit_hash: &String) { + let mut branch = util::get_storage_path().unwrap(); + branch.push("refs"); + branch.push("heads"); + branch.push(branch_name); + std::fs::write(branch, commit_hash).expect("无法写入branch"); +} + +pub fn get_branch_head(branch_name: &String) -> std::option::Option { + // 返回当前分支的commit hash + let mut branch = util::get_storage_path().unwrap(); + branch.push("refs"); + branch.push("heads"); + branch.push(branch_name); + if branch.exists() { + let commit_hash = std::fs::read_to_string(branch).expect("无法读取branch"); + Some(commit_hash) + } else { + None + } +} + +#[cfg(test)] +mod test { + use crate::utils::util; + + #[test] + fn test_current_head() { + util::setup_test_with_mit(); + let head = super::current_head(); + assert!( + match head { + super::Head::Branch(_) => true, + _ => false, + }, + "当前不在分支上" + ); + } + + #[test] + fn test_edit_branch() { + util::setup_test_with_mit(); + let branch_name = "test_branch".to_string() + &rand::random::().to_string(); + let branch_head = super::get_branch_head(&branch_name); + assert!(branch_head.is_none()); + + let commit_hash = "1234567890".to_string(); + super::update_branch(&branch_name, &commit_hash); + let branch_head = super::get_branch_head(&branch_name); + assert!(branch_head.is_some()); + assert!(branch_head.unwrap() == commit_hash); + } +} diff --git a/src/lib.rs b/src/lib.rs index f246b1b..5f577c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,4 +2,5 @@ pub mod models; pub mod utils; pub mod commands; -mod store; \ No newline at end of file +mod store; +mod head; \ No newline at end of file diff --git a/src/utils/util.rs b/src/utils/util.rs index 6be7ea0..d744e08 100644 --- a/src/utils/util.rs +++ b/src/utils/util.rs @@ -5,7 +5,7 @@ use std::{fs, io}; pub const ROOT_DIR: &str = ".mit"; pub const TEST_DIR: &str = "mit_test_storage"; // 执行测试的储存库 -pub fn setup_test_dir() { +fn setup_test_dir() { let path = std::env::var("CARGO_MANIFEST_DIR").unwrap(); let mut path = PathBuf::from(path); path.push(TEST_DIR);