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 { 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()));
let head = data::get_ref("HEAD".to_owned()); let head = data::get_ref("HEAD".to_owned(), true);
if head.value != "" { if head.value != "" {
commit += format!("parent {}\n", head.value).as_str(); commit += format!("parent {}\n", head.value).as_str();
} }
@ -86,6 +86,7 @@ pub fn commit(message: &str) -> String {
value: oid.clone(), value: oid.clone(),
symbolic: false, symbolic: false,
}, },
true,
); );
return oid; return oid;
} }
@ -145,6 +146,7 @@ pub fn checkout(oid: String) {
value: oid, value: oid,
symbolic: false, symbolic: false,
}, },
true,
); );
} }
@ -155,6 +157,7 @@ pub fn create_tag(name: String, oid: String) {
value: oid, value: oid,
symbolic: false, symbolic: false,
}, },
true,
); );
} }
@ -171,7 +174,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() {
let found = data::get_ref(reference.clone()); let found = data::get_ref(reference.clone(), false);
if found.value != "" { if found.value != "" {
return found.value; return found.value;
} else { } else {
@ -200,6 +203,7 @@ pub fn create_branch(name: String, oid: String) {
value: oid, value: oid,
symbolic: false, symbolic: false,
}, },
true,
); );
} }

View File

@ -49,9 +49,9 @@ pub fn get_object(hash: String, expected: String) -> String {
return data; 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); assert!(!value.symbolic);
reference = get_ref_internal(reference).0; reference = get_ref_internal(reference, deref).0;
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();
@ -61,13 +61,13 @@ pub fn update_ref(mut reference: String, value: RefValue) {
fs::write(path, value.value).expect("Failed to updated HEAD"); fs::write(path, value.value).expect("Failed to updated HEAD");
} }
pub fn get_ref(reference: String) -> RefValue { pub fn get_ref(reference: String, deref: bool) -> RefValue {
return get_ref_internal(reference).1; 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![]; 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)) { for entry in WalkDir::new(format!("{}/refs/", RGIT_DIR)) {
let item = entry.unwrap(); 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(); let relative_path = item.path().strip_prefix(RGIT_DIR).unwrap();
refs.push(( refs.push((
relative_path.to_str().unwrap().to_owned(), 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; 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 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(); 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 ( return (reference, RefValue { value, symbolic });
reference,
RefValue {
value,
symbolic: false,
},
);
} }

View File

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