step thirty two: create RefValue container

This commit is contained in:
Gonçalo Valério 2020-11-07 23:25:00 +00:00
parent da2967c736
commit 38dfc9147d
3 changed files with 48 additions and 14 deletions

View File

@ -72,14 +72,20 @@ pub fn commit(message: &str) -> String {
let mut commit = format!("tree {}\n", write_tree(".".to_owned())); let mut commit = format!("tree {}\n", write_tree(".".to_owned()));
if let Ok(head) = data::get_ref("HEAD".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 += "\n";
commit += format!("{}\n", message).as_str(); commit += format!("{}\n", message).as_str();
let oid = data::hash_object(&commit.into_bytes(), "commit".to_owned()); 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; return oid;
} }
@ -132,11 +138,23 @@ pub fn iter_commits_and_parents(mut oids: VecDeque<String>) -> Vec<String> {
pub fn checkout(oid: String) { pub fn checkout(oid: String) {
let commit = get_commit(oid.clone()); let commit = get_commit(oid.clone());
read_tree(commit.tree); 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) { 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 { 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() { for reference in refs_to_try.into_iter() {
match data::get_ref(reference.clone()) { match data::get_ref(reference.clone()) {
Ok(oid) => return oid, Ok(oid) => return oid.value,
_ => continue, _ => continue,
} }
} }
@ -173,7 +191,13 @@ pub fn get_oid(mut name: String) -> String {
} }
pub fn create_branch(name: String, oid: 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 { fn is_ignored(path: &String) -> bool {

View File

@ -6,6 +6,11 @@ use walkdir::WalkDir;
static RGIT_DIR: &'static str = ".rgit"; static RGIT_DIR: &'static str = ".rgit";
pub struct RefValue {
pub value: String,
pub symbolic: bool,
}
pub fn init() -> std::io::Result<()> { pub fn init() -> std::io::Result<()> {
fs::create_dir(RGIT_DIR)?; fs::create_dir(RGIT_DIR)?;
fs::create_dir(format!("{}/{}", RGIT_DIR, "objects"))?; fs::create_dir(format!("{}/{}", RGIT_DIR, "objects"))?;
@ -44,17 +49,18 @@ pub fn get_object(hash: String, expected: String) -> String {
return data; 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 path = format!("{}/{}", RGIT_DIR, reference);
let mut parents = Path::new(&path).ancestors(); let mut parents = Path::new(&path).ancestors();
parents.next(); parents.next();
let parent = parents.next().unwrap().to_str().unwrap(); let parent = parents.next().unwrap().to_str().unwrap();
fs::create_dir_all(parent).expect("Cannot create required dirs"); 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<String, Box<dyn std::error::Error + 'static>> { pub fn get_ref(reference: String) -> Result<RefValue, Box<dyn std::error::Error + 'static>> {
let ref_path = format!("{}/{}", RGIT_DIR, reference); let ref_path = format!("{}/{}", RGIT_DIR, reference);
let value = fs::read_to_string(ref_path)?; let value = fs::read_to_string(ref_path)?;
@ -62,11 +68,15 @@ pub fn get_ref(reference: String) -> Result<String, Box<dyn std::error::Error +
let new_ref: Vec<&str> = value.splitn(2, ":").collect(); let new_ref: Vec<&str> = value.splitn(2, ":").collect();
return get_ref(new_ref[1].to_owned()); return get_ref(new_ref[1].to_owned());
} }
return Ok(value);
return Ok(RefValue {
value,
symbolic: false,
});
} }
pub fn iter_refs() -> Vec<(String, String)> { pub fn iter_refs() -> Vec<(String, RefValue)> {
let mut refs: Vec<(String, String)> = vec![]; let mut refs: Vec<(String, RefValue)> = vec![];
refs.push(("HEAD".to_owned(), get_ref("HEAD".to_owned()).unwrap())); refs.push(("HEAD".to_owned(), get_ref("HEAD".to_owned()).unwrap()));
for entry in WalkDir::new(format!("{}/refs/", RGIT_DIR)) { for entry in WalkDir::new(format!("{}/refs/", RGIT_DIR)) {

View File

@ -166,8 +166,8 @@ fn k() {
let mut oids = VecDeque::new(); let mut oids = VecDeque::new();
for refinfo in data::iter_refs() { for refinfo in data::iter_refs() {
dot.push_str(&format!("\"{}\" [shape=note]\n", refinfo.0)); dot.push_str(&format!("\"{}\" [shape=note]\n", refinfo.0));
dot.push_str(&format!("\"{}\" -> \"{}\"", refinfo.0, refinfo.1)); dot.push_str(&format!("\"{}\" -> \"{}\"", refinfo.0, refinfo.1.value));
oids.push_back(refinfo.1); oids.push_back(refinfo.1.value);
} }
for oid in base::iter_commits_and_parents(oids) { for oid in base::iter_commits_and_parents(oids) {