diff --git a/src/base.rs b/src/base.rs index b31d507..549903b 100644 --- a/src/base.rs +++ b/src/base.rs @@ -72,14 +72,20 @@ pub fn commit(message: &str) -> String { let mut commit = format!("tree {}\n", write_tree(".".to_owned())); if let Ok(head) = data::get_ref("HEAD".to_owned()) { - commit += format!("parent {}\n", head).as_str(); + commit += format!("parent {}\n", head.value).as_str(); } commit += "\n"; commit += format!("{}\n", message).as_str(); let oid = data::hash_object(&commit.into_bytes(), "commit".to_owned()); - data::update_ref("HEAD".to_owned(), oid.clone()); + data::update_ref( + "HEAD".to_owned(), + data::RefValue { + value: oid.clone(), + symbolic: false, + }, + ); return oid; } @@ -132,11 +138,23 @@ pub fn iter_commits_and_parents(mut oids: VecDeque) -> Vec { pub fn checkout(oid: String) { let commit = get_commit(oid.clone()); read_tree(commit.tree); - data::update_ref("HEAD".to_owned(), oid); + data::update_ref( + "HEAD".to_owned(), + data::RefValue { + value: oid, + symbolic: false, + }, + ); } pub fn create_tag(name: String, oid: String) { - data::update_ref(format!("refs/tags/{}", name), oid); + data::update_ref( + format!("refs/tags/{}", name), + data::RefValue { + value: oid, + symbolic: false, + }, + ); } pub fn get_oid(mut name: String) -> String { @@ -153,7 +171,7 @@ pub fn get_oid(mut name: String) -> String { for reference in refs_to_try.into_iter() { match data::get_ref(reference.clone()) { - Ok(oid) => return oid, + Ok(oid) => return oid.value, _ => continue, } } @@ -173,7 +191,13 @@ pub fn get_oid(mut name: String) -> String { } pub fn create_branch(name: String, oid: String) { - data::update_ref(format!("refs/heads/{}", name), oid); + data::update_ref( + format!("refs/heads/{}", name), + data::RefValue { + value: oid, + symbolic: false, + }, + ); } fn is_ignored(path: &String) -> bool { diff --git a/src/data.rs b/src/data.rs index 85f8141..8fba900 100644 --- a/src/data.rs +++ b/src/data.rs @@ -6,6 +6,11 @@ use walkdir::WalkDir; static RGIT_DIR: &'static str = ".rgit"; +pub struct RefValue { + pub value: String, + pub symbolic: bool, +} + pub fn init() -> std::io::Result<()> { fs::create_dir(RGIT_DIR)?; fs::create_dir(format!("{}/{}", RGIT_DIR, "objects"))?; @@ -44,17 +49,18 @@ pub fn get_object(hash: String, expected: String) -> String { return data; } -pub fn update_ref(reference: String, oid: String) { +pub fn update_ref(reference: String, value: RefValue) { + assert!(!value.symbolic); let path = format!("{}/{}", RGIT_DIR, reference); let mut parents = Path::new(&path).ancestors(); parents.next(); let parent = parents.next().unwrap().to_str().unwrap(); fs::create_dir_all(parent).expect("Cannot create required dirs"); - fs::write(path, oid).expect("Failed to updated HEAD"); + fs::write(path, value.value).expect("Failed to updated HEAD"); } -pub fn get_ref(reference: String) -> Result> { +pub fn get_ref(reference: String) -> Result> { let ref_path = format!("{}/{}", RGIT_DIR, reference); let value = fs::read_to_string(ref_path)?; @@ -62,11 +68,15 @@ pub fn get_ref(reference: String) -> Result = value.splitn(2, ":").collect(); return get_ref(new_ref[1].to_owned()); } - return Ok(value); + + return Ok(RefValue { + value, + symbolic: false, + }); } -pub fn iter_refs() -> Vec<(String, String)> { - let mut refs: Vec<(String, String)> = vec![]; +pub fn iter_refs() -> Vec<(String, RefValue)> { + let mut refs: Vec<(String, RefValue)> = vec![]; refs.push(("HEAD".to_owned(), get_ref("HEAD".to_owned()).unwrap())); for entry in WalkDir::new(format!("{}/refs/", RGIT_DIR)) { diff --git a/src/main.rs b/src/main.rs index a79a30e..69ee2d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -166,8 +166,8 @@ fn k() { let mut oids = VecDeque::new(); for refinfo in data::iter_refs() { dot.push_str(&format!("\"{}\" [shape=note]\n", refinfo.0)); - dot.push_str(&format!("\"{}\" -> \"{}\"", refinfo.0, refinfo.1)); - oids.push_back(refinfo.1); + dot.push_str(&format!("\"{}\" -> \"{}\"", refinfo.0, refinfo.1.value)); + oids.push_back(refinfo.1.value); } for oid in base::iter_commits_and_parents(oids) {