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()));
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<String>) -> Vec<String> {
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 {

View File

@ -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<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 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();
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)) {

View File

@ -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) {