From 43878312908122bddfdfb7f46fa68dda5bb10142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gon=C3=A7alo=20Val=C3=A9rio?= Date: Mon, 23 Nov 2020 22:48:06 +0000 Subject: [PATCH] step fourty five: compare working tree to a commit --- src/base.rs | 20 ++++++++++++++++++++ src/main.rs | 18 ++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/base.rs b/src/base.rs index 8655227..2638790 100644 --- a/src/base.rs +++ b/src/base.rs @@ -2,6 +2,7 @@ use std::collections::{HashMap, HashSet, VecDeque}; use std::fs; use std::io; use std::path::Path; +use walkdir::WalkDir; #[path = "data.rs"] mod data; @@ -304,6 +305,25 @@ pub fn get_tree(oid: String, base_path: String) -> HashMap { result } +pub fn get_working_tree() -> HashMap { + let mut result = HashMap::new(); + + for entry in WalkDir::new(".") { + let item = entry.unwrap(); + let relative_path = item.path().strip_prefix("./").unwrap(); + let metadata = item.metadata().unwrap(); + let path = item.path().to_str().unwrap().to_owned(); + if metadata.is_file() && !is_ignored(&path.clone()) { + let content = fs::read(path.clone()).unwrap(); + result.insert( + relative_path.to_str().unwrap().to_owned(), + data::hash_object(&content, "blob".to_owned()), + ); + } + } + return result; +} + fn empty_current_directory(dir: &str) -> io::Result<()> { // Delete current directory, except the ignored directories and files for entry in fs::read_dir(dir)? { diff --git a/src/main.rs b/src/main.rs index 7bd144f..ec7ed96 100644 --- a/src/main.rs +++ b/src/main.rs @@ -76,6 +76,11 @@ fn main() { .about("Show diff from a commit") .arg(Arg::with_name("oid").index(1).default_value("@")), ) + .subcommand( + SubCommand::with_name("diff") + .about("Compare the working tree with the given commit") + .arg(Arg::with_name("commit").index(1).default_value("@")), + ) .get_matches(); match matches.subcommand_name() { @@ -93,6 +98,7 @@ fn main() { Some("status") => status(), Some("reset") => reset(matches), Some("show") => show(matches), + Some("diff") => difference(matches), _ => println!("unknown sub command"), } } @@ -280,6 +286,18 @@ fn show(matches: ArgMatches) { } } +fn difference(matches: ArgMatches) { + if let Some(cmd_matches) = matches.subcommand_matches("diff") { + let oid = base::get_oid(cmd_matches.value_of("commit").unwrap().to_owned()); + let commit = base::get_commit(oid); + let result = diff::diff_trees( + base::get_tree(commit.tree, "".to_owned()), + base::get_working_tree(), + ); + println!("{}", result); + } +} + fn print_commit(oid: String, commit: &base::Commit, mut refs: HashMap>) { let ref_str = if refs.contains_key(&oid) { refs.get_mut(&oid).unwrap().join(", ")