Skip to content

Commit 16aa6f7

Browse files
author
Stephan Dilly
committed
support showing tags in log, speed up log by cloning less (#47)
1 parent ec6180a commit 16aa6f7

File tree

3 files changed

+71
-10
lines changed

3 files changed

+71
-10
lines changed

asyncgit/src/sync/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod hunks;
77
mod logwalker;
88
mod reset;
99
pub mod status;
10+
mod tags;
1011
pub mod utils;
1112

1213
pub use commits_info::{get_commits_info, CommitInfo};
@@ -16,6 +17,7 @@ pub use logwalker::LogWalker;
1617
pub use reset::{
1718
reset_stage, reset_workdir_file, reset_workdir_folder,
1819
};
20+
pub use tags::{get_tags, Tags};
1921
pub use utils::{
2022
commit, stage_add_all, stage_add_file, stage_addremoved,
2123
};

asyncgit/src/sync/tags.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use super::utils::repo;
2+
use git2::Error;
3+
use scopetime::scope_time;
4+
use std::collections::HashMap;
5+
6+
/// hashmap of tag target commit hash to tag name
7+
pub type Tags = HashMap<String, String>;
8+
9+
/// returns `Tags` type filled with all tags found in repo
10+
pub fn get_tags(repo_path: &str) -> Result<Tags, Error> {
11+
scope_time!("get_tags");
12+
13+
let mut res = Tags::new();
14+
15+
let repo = repo(repo_path);
16+
17+
for name in repo.tag_names(None)?.iter() {
18+
if let Some(name) = name {
19+
let obj = repo.revparse_single(name)?;
20+
21+
if let Some(tag) = obj.as_tag() {
22+
let target_hash = tag.target_id().to_string();
23+
let tag_name = String::from(name);
24+
res.insert(target_hash, tag_name);
25+
}
26+
}
27+
}
28+
29+
Ok(res)
30+
}

src/tabs/revlog.rs

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use chrono::prelude::*;
88
use crossbeam_channel::Sender;
99
use crossterm::event::Event;
1010
use std::{borrow::Cow, cmp, convert::TryFrom, time::Instant};
11-
use sync::CommitInfo;
11+
use sync::{CommitInfo, Tags};
1212
use tui::{
1313
backend::Backend,
1414
layout::{Alignment, Rect},
@@ -24,29 +24,32 @@ struct LogEntry {
2424
hash: String,
2525
}
2626

27-
impl From<&CommitInfo> for LogEntry {
28-
fn from(c: &CommitInfo) -> Self {
27+
impl From<CommitInfo> for LogEntry {
28+
fn from(c: CommitInfo) -> Self {
2929
let time =
3030
DateTime::<Local>::from(DateTime::<Utc>::from_utc(
3131
NaiveDateTime::from_timestamp(c.time, 0),
3232
Utc,
3333
));
3434
Self {
35-
author: c.author.clone(),
36-
msg: c.message.clone(),
35+
author: c.author,
36+
msg: c.message,
3737
time: time.format("%Y-%m-%d %H:%M:%S").to_string(),
38-
hash: c.hash[0..7].to_string(),
38+
hash: c.hash,
3939
}
4040
}
4141
}
4242

4343
const COLOR_SELECTION_BG: Color = Color::Blue;
4444

45+
const STYLE_TAG: Style = Style::new().fg(Color::Yellow);
4546
const STYLE_HASH: Style = Style::new().fg(Color::Magenta);
4647
const STYLE_TIME: Style = Style::new().fg(Color::Blue);
4748
const STYLE_AUTHOR: Style = Style::new().fg(Color::Green);
4849
const STYLE_MSG: Style = Style::new().fg(Color::Reset);
4950

51+
const STYLE_TAG_SELECTED: Style =
52+
Style::new().fg(Color::Yellow).bg(COLOR_SELECTION_BG);
5053
const STYLE_HASH_SELECTED: Style =
5154
Style::new().fg(Color::Magenta).bg(COLOR_SELECTION_BG);
5255
const STYLE_TIME_SELECTED: Style =
@@ -56,7 +59,7 @@ const STYLE_AUTHOR_SELECTED: Style =
5659
const STYLE_MSG_SELECTED: Style =
5760
Style::new().fg(Color::Reset).bg(COLOR_SELECTION_BG);
5861

59-
static ELEMENTS_PER_LINE: usize = 8;
62+
static ELEMENTS_PER_LINE: usize = 10;
6063
static SLICE_SIZE: usize = 1000;
6164
static SLICE_OFFSET_RELOAD_THRESHOLD: usize = 100;
6265

@@ -69,6 +72,7 @@ pub struct Revlog {
6972
visible: bool,
7073
first_open_done: bool,
7174
scroll_state: (Instant, f32),
75+
tags: Tags,
7276
}
7377

7478
impl Revlog {
@@ -82,6 +86,7 @@ impl Revlog {
8286
visible: false,
8387
first_open_done: false,
8488
scroll_state: (Instant::now(), 0_f32),
89+
tags: Tags::new(),
8590
}
8691
}
8792

@@ -94,7 +99,12 @@ impl Revlog {
9499

95100
let mut txt = Vec::new();
96101
for (idx, e) in self.items.iter().enumerate() {
97-
Self::add_entry(e, idx == selection, &mut txt);
102+
let tag = if let Some(tag_name) = self.tags.get(&e.hash) {
103+
tag_name.as_str()
104+
} else {
105+
""
106+
};
107+
Self::add_entry(e, idx == selection, &mut txt, tag);
98108
}
99109

100110
let title =
@@ -138,9 +148,14 @@ impl Revlog {
138148
);
139149

140150
if let Ok(commits) = commits {
141-
self.items.extend(commits.iter().map(LogEntry::from));
151+
self.items
152+
.extend(commits.into_iter().map(LogEntry::from));
142153
}
143154
}
155+
156+
if self.tags.is_empty() {
157+
self.tags = sync::get_tags(CWD).unwrap();
158+
}
144159
}
145160

146161
fn move_selection(&mut self, up: bool) {
@@ -190,6 +205,7 @@ impl Revlog {
190205
e: &'a LogEntry,
191206
selected: bool,
192207
txt: &mut Vec<Text<'a>>,
208+
tag: &'a str,
193209
) {
194210
let count_before = txt.len();
195211

@@ -204,7 +220,7 @@ impl Revlog {
204220
};
205221

206222
txt.push(Text::Styled(
207-
Cow::from(e.hash.as_str()),
223+
Cow::from(&e.hash[0..7]),
208224
if selected {
209225
STYLE_HASH_SELECTED
210226
} else {
@@ -229,6 +245,19 @@ impl Revlog {
229245
STYLE_AUTHOR
230246
},
231247
));
248+
txt.push(splitter.clone());
249+
txt.push(Text::Styled(
250+
Cow::from(if tag.is_empty() {
251+
String::from("")
252+
} else {
253+
format!(" {}", tag)
254+
}),
255+
if selected {
256+
STYLE_TAG_SELECTED
257+
} else {
258+
STYLE_TAG
259+
},
260+
));
232261
txt.push(splitter);
233262
txt.push(Text::Styled(
234263
Cow::from(e.msg.as_str()),

0 commit comments

Comments
 (0)