step twelve: extract tree from object
This commit is contained in:
parent
c93915acf7
commit
3436deb267
|
@ -1,2 +1,3 @@
|
||||||
/target
|
/target
|
||||||
|
/test
|
||||||
.rgit
|
.rgit
|
||||||
|
|
49
src/base.rs
49
src/base.rs
|
@ -1,4 +1,7 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::io;
|
||||||
|
use std::path::Path;
|
||||||
#[path = "data.rs"]
|
#[path = "data.rs"]
|
||||||
mod data;
|
mod data;
|
||||||
|
|
||||||
|
@ -45,6 +48,19 @@ pub fn write_tree(directory: String) -> String {
|
||||||
return data::hash_object(&tree.into_bytes(), "tree".to_owned());
|
return data::hash_object(&tree.into_bytes(), "tree".to_owned());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_tree(oid: String) {
|
||||||
|
for (path, object_id) in get_tree(oid, "./".to_owned()).iter() {
|
||||||
|
let mut dirs = Path::new(path).ancestors();
|
||||||
|
dirs.next();
|
||||||
|
|
||||||
|
let dir = dirs.next().unwrap().to_str().unwrap();
|
||||||
|
|
||||||
|
fs::create_dir_all(dir).expect("Cannot create required dirs");
|
||||||
|
fs::write(path, data::get_object(object_id.clone(), "".to_owned()))
|
||||||
|
.expect("Cannot write required object");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_ignored(path: &String) -> bool {
|
fn is_ignored(path: &String) -> bool {
|
||||||
if path.contains(".rgit") {
|
if path.contains(".rgit") {
|
||||||
true
|
true
|
||||||
|
@ -52,3 +68,36 @@ fn is_ignored(path: &String) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn tree_entries(oid: String) -> Vec<(String, String, String)> {
|
||||||
|
let mut entries: Vec<(String, String, String)> = vec![];
|
||||||
|
let tree_data = data::get_object(oid, "tree".to_owned());
|
||||||
|
for line in tree_data.split_terminator("\n") {
|
||||||
|
let items: Vec<&str> = line.splitn(3, " ").collect();
|
||||||
|
entries.push((
|
||||||
|
items[0].to_owned(), // _type
|
||||||
|
items[1].to_owned(), // oid
|
||||||
|
items[2].to_owned(), // name
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_tree(oid: String, base_path: String) -> HashMap<String, String> {
|
||||||
|
let mut result = HashMap::new();
|
||||||
|
for entry in tree_entries(oid) {
|
||||||
|
// _type, oid, name
|
||||||
|
assert!(entry.2.find("/").is_none());
|
||||||
|
assert!(entry.2 != "..");
|
||||||
|
assert!(entry.2 != ".");
|
||||||
|
let path = base_path.clone() + entry.2.as_str();
|
||||||
|
if entry.0 == "blob".to_owned() {
|
||||||
|
result.insert(path.clone(), entry.1.clone());
|
||||||
|
} else if entry.0 == "tree".to_owned() {
|
||||||
|
result.extend(get_tree(entry.1, format!("{}/", path)));
|
||||||
|
} else {
|
||||||
|
panic!("Unknown tree entry: {}", entry.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ pub fn get_object(hash: String, expected: String) -> String {
|
||||||
|
|
||||||
if expected != "".to_owned() {
|
if expected != "".to_owned() {
|
||||||
// Compare the type
|
// Compare the type
|
||||||
|
content.pop();
|
||||||
assert_eq!(expected, content);
|
assert_eq!(expected, content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -23,6 +23,11 @@ fn main() {
|
||||||
SubCommand::with_name("write-tree")
|
SubCommand::with_name("write-tree")
|
||||||
.about("write the current working directory to the database"),
|
.about("write the current working directory to the database"),
|
||||||
)
|
)
|
||||||
|
.subcommand(
|
||||||
|
SubCommand::with_name("read-tree")
|
||||||
|
.about("writes a given tree to the working directory")
|
||||||
|
.arg(Arg::with_name("oid").index(1).required(true)),
|
||||||
|
)
|
||||||
.get_matches();
|
.get_matches();
|
||||||
|
|
||||||
match matches.subcommand_name() {
|
match matches.subcommand_name() {
|
||||||
|
@ -30,6 +35,7 @@ fn main() {
|
||||||
Some("hash-object") => hash_object(matches),
|
Some("hash-object") => hash_object(matches),
|
||||||
Some("cat-file") => cat_file(matches),
|
Some("cat-file") => cat_file(matches),
|
||||||
Some("write-tree") => write_tree(),
|
Some("write-tree") => write_tree(),
|
||||||
|
Some("read-tree") => read_tree(matches),
|
||||||
_ => println!("unknown sub command"),
|
_ => println!("unknown sub command"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,3 +69,10 @@ fn cat_file(matches: ArgMatches) {
|
||||||
fn write_tree() {
|
fn write_tree() {
|
||||||
println!("{}", base::write_tree(".".to_owned()));
|
println!("{}", base::write_tree(".".to_owned()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_tree(matches: ArgMatches) {
|
||||||
|
if let Some(cmd_matches) = matches.subcommand_matches("read-tree") {
|
||||||
|
let oid = cmd_matches.value_of("oid").unwrap();
|
||||||
|
base::read_tree(oid.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue