step thirty four: dont always dereference refs

This commit is contained in:
Gonçalo Valério 2020-11-08 13:09:17 +00:00
parent 57c1631be2
commit 1d810df2ae
3 changed files with 26 additions and 22 deletions

View File

@ -71,7 +71,7 @@ pub fn read_tree(oid: String) {
pub fn commit(message: &str) -> String {
let mut commit = format!("tree {}\n", write_tree(".".to_owned()));
let head = data::get_ref("HEAD".to_owned());
let head = data::get_ref("HEAD".to_owned(), true);
if head.value != "" {
commit += format!("parent {}\n", head.value).as_str();
}
@ -86,6 +86,7 @@ pub fn commit(message: &str) -> String {
value: oid.clone(),
symbolic: false,
},
true,
);
return oid;
}
@ -145,6 +146,7 @@ pub fn checkout(oid: String) {
value: oid,
symbolic: false,
},
true,
);
}
@ -155,6 +157,7 @@ pub fn create_tag(name: String, oid: String) {
value: oid,
symbolic: false,
},
true,
);
}
@ -171,7 +174,7 @@ pub fn get_oid(mut name: String) -> String {
];
for reference in refs_to_try.into_iter() {
let found = data::get_ref(reference.clone());
let found = data::get_ref(reference.clone(), false);
if found.value != "" {
return found.value;
} else {
@ -200,6 +203,7 @@ pub fn create_branch(name: String, oid: String) {
value: oid,
symbolic: false,
},
true,
);
}

View File

@ -49,9 +49,9 @@ pub fn get_object(hash: String, expected: String) -> String {
return data;
}
pub fn update_ref(mut reference: String, value: RefValue) {
pub fn update_ref(mut reference: String, value: RefValue, deref: bool) {
assert!(!value.symbolic);
reference = get_ref_internal(reference).0;
reference = get_ref_internal(reference, deref).0;
let path = format!("{}/{}", RGIT_DIR, reference);
let mut parents = Path::new(&path).ancestors();
parents.next();
@ -61,13 +61,13 @@ pub fn update_ref(mut reference: String, value: RefValue) {
fs::write(path, value.value).expect("Failed to updated HEAD");
}
pub fn get_ref(reference: String) -> RefValue {
return get_ref_internal(reference).1;
pub fn get_ref(reference: String, deref: bool) -> RefValue {
return get_ref_internal(reference, deref).1;
}
pub fn iter_refs() -> Vec<(String, RefValue)> {
pub fn iter_refs(deref: bool) -> Vec<(String, RefValue)> {
let mut refs: Vec<(String, RefValue)> = vec![];
refs.push(("HEAD".to_owned(), get_ref("HEAD".to_owned())));
refs.push(("HEAD".to_owned(), get_ref("HEAD".to_owned(), deref)));
for entry in WalkDir::new(format!("{}/refs/", RGIT_DIR)) {
let item = entry.unwrap();
@ -77,7 +77,7 @@ pub fn iter_refs() -> Vec<(String, RefValue)> {
let relative_path = item.path().strip_prefix(RGIT_DIR).unwrap();
refs.push((
relative_path.to_str().unwrap().to_owned(),
get_ref(relative_path.to_str().unwrap().to_owned()),
get_ref(relative_path.to_str().unwrap().to_owned(), deref),
));
}
}
@ -85,20 +85,18 @@ pub fn iter_refs() -> Vec<(String, RefValue)> {
return refs;
}
pub fn get_ref_internal(reference: String) -> (String, RefValue) {
pub fn get_ref_internal(reference: String, deref: bool) -> (String, RefValue) {
let ref_path = format!("{}/{}", RGIT_DIR, reference);
let value = fs::read_to_string(ref_path).unwrap_or("".to_owned());
let mut value = fs::read_to_string(ref_path).unwrap_or("".to_owned());
let symbolic = !value.is_empty() && value.starts_with("ref:");
if !value.is_empty() && value.starts_with("ref:") {
if symbolic {
let new_ref: Vec<&str> = value.splitn(2, ":").collect();
return get_ref_internal(new_ref[1].to_owned());
value = new_ref[1].to_owned();
if deref {
return get_ref_internal(value, deref);
}
}
return (
reference,
RefValue {
value,
symbolic: false,
},
);
return (reference, RefValue { value, symbolic });
}

View File

@ -164,10 +164,12 @@ fn tag(matches: ArgMatches) {
fn k() {
let mut dot = "digraph commits {\n".to_owned();
let mut oids = VecDeque::new();
for refinfo in data::iter_refs() {
for refinfo in data::iter_refs(false) {
dot.push_str(&format!("\"{}\" [shape=note]\n", refinfo.0));
dot.push_str(&format!("\"{}\" -> \"{}\"", refinfo.0, refinfo.1.value));
oids.push_back(refinfo.1.value);
if !refinfo.1.symbolic {
oids.push_back(refinfo.1.value);
}
}
for oid in base::iter_commits_and_parents(oids) {