diff --git a/src/commands.rs b/src/commands.rs index 20fb95656..63ce336f9 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -979,8 +979,8 @@ fn log_template(settings: &UserSettings) -> String { label(if(open, "open"), "commit: " commit_id "\n" "change: " change_id "\n" - "author: " author.name() " <" author.email() ">\n" - "committer: " committer.name() " <" committer.email() ">\n" + "author: " author.name() " <" author.email() "> " author.timestamp() "\n" + "committer: " committer.name() " <" committer.email() "> " committer.timestamp() "\n" "git refs: " git_refs "\n" "open: " open "\n" "pruned: " pruned "\n" @@ -1005,7 +1005,7 @@ fn graph_log_template(settings: &UserSettings) -> String { commit_id.short() " " change_id.short() " " author.email() - " " committer.email() + " " label("timestamp", author.timestamp()) " " git_refs if(pruned, label("pruned", " pruned")) if(obsolete, label("obsolete", " obsolete")) diff --git a/src/styler.rs b/src/styler.rs index 9e9ab6859..175e1b3d8 100644 --- a/src/styler.rs +++ b/src/styler.rs @@ -85,7 +85,9 @@ fn config_colors(user_settings: &UserSettings) -> HashMap { result.insert(String::from("commit_id open"), String::from("green")); result.insert(String::from("change_id"), String::from("magenta")); result.insert(String::from("author"), String::from("yellow")); + result.insert(String::from("author timestamp"), String::from("cyan")); result.insert(String::from("committer"), String::from("yellow")); + result.insert(String::from("committer timestamp"), String::from("cyan")); result.insert(String::from("git_refs"), String::from("magenta")); result.insert(String::from("pruned"), String::from("red")); result.insert(String::from("obsolete"), String::from("red")); diff --git a/src/template_parser.rs b/src/template_parser.rs index 06e8175be..6b727ddaf 100644 --- a/src/template_parser.rs +++ b/src/template_parser.rs @@ -14,6 +14,7 @@ extern crate pest; +use chrono::{FixedOffset, TimeZone, Utc}; use jujube_lib::commit::Commit; use jujube_lib::repo::RepoRef; use jujube_lib::store::{CommitId, Signature}; @@ -93,6 +94,20 @@ impl TemplateProperty for SignatureEmail { } } +struct SignatureTimestamp; + +impl TemplateProperty for SignatureTimestamp { + fn extract(&self, context: &Signature) -> String { + let utc = Utc + .timestamp( + context.timestamp.timestamp.0 as i64 / 1000, + (context.timestamp.timestamp.0 % 1000) as u32 * 1000000, + ) + .with_timezone(&FixedOffset::east(context.timestamp.tz_offset * 60)); + utc.format("%Y-%m-%d %H:%M:%S.%3f %:z").to_string() + } +} + fn parse_method_chain<'a, I: 'a>( pair: Pair, input_property: Property<'a, I>, @@ -177,6 +192,7 @@ fn parse_signature_method<'a>(method: Pair) -> Property<'a, Signature> { // `author % (name "<" email ">")`)? "name" => Property::String(Box::new(SignatureName)), "email" => Property::String(Box::new(SignatureEmail)), + "timestamp" => Property::String(Box::new(SignatureTimestamp)), name => panic!("no such commit id method: {}", name), }; let chain_method = inner.last().unwrap();