From 7871cb7c47a61270fb0c7ae894aef51d75c0efcf Mon Sep 17 00:00:00 2001 From: HouXiaoxuan Date: Wed, 20 Dec 2023 02:07:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0head=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/head.rs | 127 ++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 108 insertions(+), 19 deletions(-) diff --git a/src/head.rs b/src/head.rs index 705fea0..90c4398 100644 --- a/src/head.rs +++ b/src/head.rs @@ -5,7 +5,7 @@ pub enum Head { Branch(String), } -pub fn current_head() -> Head { +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文件损坏"); @@ -16,8 +16,8 @@ pub fn current_head() -> Head { Head::Detached(head_content) } } - -pub fn update_branch(branch_name: &String, commit_hash: &String) { +fn update_branch_head(branch_name: &String, commit_hash: &String) { + // 更新分支head let mut branch = util::get_storage_path().unwrap(); branch.push("refs"); branch.push("heads"); @@ -25,7 +25,7 @@ pub fn update_branch(branch_name: &String, commit_hash: &String) { std::fs::write(branch, commit_hash).expect("无法写入branch"); } -pub fn get_branch_head(branch_name: &String) -> std::option::Option { +fn get_branch_head(branch_name: &String) -> std::option::Option { // 返回当前分支的commit hash let mut branch = util::get_storage_path().unwrap(); branch.push("refs"); @@ -39,22 +39,69 @@ pub fn get_branch_head(branch_name: &String) -> std::option::Option { } } +/**返回当前head指向的commit hash,如果是分支,则返回分支的commit hash*/ +pub fn current_head_commit() -> String { + let head = current_head(); + match head { + Head::Branch(branch_name) => { + let commit_hash = get_branch_head(&branch_name).unwrap(); + commit_hash + } + Head::Detached(commit_hash) => commit_hash, + } +} + +/** 将当前的head指向commit_hash,根据当前的head类型,更新不同的文件 */ +pub fn update_head_commit(commit_hash: &String) { + let head = current_head(); + match head { + Head::Branch(branch_name) => { + update_branch_head(&branch_name, commit_hash); + } + Head::Detached(_) => { + let mut head = util::get_storage_path().unwrap(); + head.push("HEAD"); + std::fs::write(head, commit_hash).expect("无法写入HEAD"); + } + } +} + +/** 列出本地的branch */ +pub fn list_local_branches() -> Vec { + let mut branches = Vec::new(); + let mut branch_dir = util::get_storage_path().unwrap(); + branch_dir.push("refs"); + branch_dir.push("heads"); + if branch_dir.exists() { + let entries = std::fs::read_dir(branch_dir).expect("无法读取branch"); + for entry in entries { + let entry = entry.unwrap(); + let branch_name = entry.file_name().into_string().unwrap(); + branches.push(branch_name); + } + } + branches +} + +/** 切换head到branch */ +pub fn change_head_to_branch(branch_name: &String) { + let mut head = util::get_storage_path().unwrap(); + head.push("HEAD"); + let branch_head = get_branch_head(branch_name).unwrap(); + std::fs::write(head, format!("ref: refs/heads/{}", branch_name)).expect("无法写入HEAD"); + update_head_commit(&branch_head); +} + +/** 切换head到非branchcommit */ +pub fn change_head_to_commit(commit_hash: &String) { + let mut head = util::get_storage_path().unwrap(); + head.push("HEAD"); + std::fs::write(head, commit_hash).expect("无法写入HEAD"); +} + #[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, - }, - "当前不在分支上" - ); - } + use crate::{head::update_branch_head, utils::util}; #[test] fn test_edit_branch() { @@ -64,9 +111,51 @@ mod test { assert!(branch_head.is_none()); let commit_hash = "1234567890".to_string(); - super::update_branch(&branch_name, &commit_hash); + super::update_branch_head(&branch_name, &commit_hash); let branch_head = super::get_branch_head(&branch_name); assert!(branch_head.is_some()); assert!(branch_head.unwrap() == commit_hash); } + + #[test] + fn test_list_local_branches() { + util::setup_test_with_mit(); + let branch_one = "test_branch".to_string() + &rand::random::().to_string(); + let branch_two = "test_branch".to_string() + &rand::random::().to_string(); + update_branch_head(&branch_one, &"1234567890".to_string()); + update_branch_head(&branch_two, &"1234567890".to_string()); + + let branches = super::list_local_branches(); + assert!(branches.contains(&branch_one)); + assert!(branches.contains(&branch_two)); + } + + #[test] + fn test_change_head_to_branch() { + util::setup_test_with_mit(); + let branch_name = "test_branch".to_string() + &rand::random::().to_string(); + update_branch_head(&branch_name, &"1234567890".to_string()); + super::change_head_to_branch(&branch_name); + assert!( + match super::current_head() { + super::Head::Branch(head_commit) => head_commit == branch_name, + _ => false, + }, + "当前不在分支上" + ); + } + + #[test] + fn test_change_head_to_commit() { + util::setup_test_with_mit(); + let commit_hash = "1234567890".to_string(); + super::change_head_to_commit(&commit_hash); + assert!( + match super::current_head() { + super::Head::Detached(head_commit) => head_commit == commit_hash, + _ => false, + }, + "当前不在分支上" + ); + } }