mirror of
https://github.com/extrawurst/gitui.git
synced 2024-12-29 12:06:26 +03:00
support showing tags in log, speed up log by cloning less (#47)
This commit is contained in:
parent
ec6180af51
commit
16aa6f7c50
@ -7,6 +7,7 @@ mod hunks;
|
||||
mod logwalker;
|
||||
mod reset;
|
||||
pub mod status;
|
||||
mod tags;
|
||||
pub mod utils;
|
||||
|
||||
pub use commits_info::{get_commits_info, CommitInfo};
|
||||
@ -16,6 +17,7 @@ pub use logwalker::LogWalker;
|
||||
pub use reset::{
|
||||
reset_stage, reset_workdir_file, reset_workdir_folder,
|
||||
};
|
||||
pub use tags::{get_tags, Tags};
|
||||
pub use utils::{
|
||||
commit, stage_add_all, stage_add_file, stage_addremoved,
|
||||
};
|
||||
|
30
asyncgit/src/sync/tags.rs
Normal file
30
asyncgit/src/sync/tags.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use super::utils::repo;
|
||||
use git2::Error;
|
||||
use scopetime::scope_time;
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// hashmap of tag target commit hash to tag name
|
||||
pub type Tags = HashMap<String, String>;
|
||||
|
||||
/// returns `Tags` type filled with all tags found in repo
|
||||
pub fn get_tags(repo_path: &str) -> Result<Tags, Error> {
|
||||
scope_time!("get_tags");
|
||||
|
||||
let mut res = Tags::new();
|
||||
|
||||
let repo = repo(repo_path);
|
||||
|
||||
for name in repo.tag_names(None)?.iter() {
|
||||
if let Some(name) = name {
|
||||
let obj = repo.revparse_single(name)?;
|
||||
|
||||
if let Some(tag) = obj.as_tag() {
|
||||
let target_hash = tag.target_id().to_string();
|
||||
let tag_name = String::from(name);
|
||||
res.insert(target_hash, tag_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
}
|
@ -8,7 +8,7 @@ use chrono::prelude::*;
|
||||
use crossbeam_channel::Sender;
|
||||
use crossterm::event::Event;
|
||||
use std::{borrow::Cow, cmp, convert::TryFrom, time::Instant};
|
||||
use sync::CommitInfo;
|
||||
use sync::{CommitInfo, Tags};
|
||||
use tui::{
|
||||
backend::Backend,
|
||||
layout::{Alignment, Rect},
|
||||
@ -24,29 +24,32 @@ struct LogEntry {
|
||||
hash: String,
|
||||
}
|
||||
|
||||
impl From<&CommitInfo> for LogEntry {
|
||||
fn from(c: &CommitInfo) -> Self {
|
||||
impl From<CommitInfo> for LogEntry {
|
||||
fn from(c: CommitInfo) -> Self {
|
||||
let time =
|
||||
DateTime::<Local>::from(DateTime::<Utc>::from_utc(
|
||||
NaiveDateTime::from_timestamp(c.time, 0),
|
||||
Utc,
|
||||
));
|
||||
Self {
|
||||
author: c.author.clone(),
|
||||
msg: c.message.clone(),
|
||||
author: c.author,
|
||||
msg: c.message,
|
||||
time: time.format("%Y-%m-%d %H:%M:%S").to_string(),
|
||||
hash: c.hash[0..7].to_string(),
|
||||
hash: c.hash,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const COLOR_SELECTION_BG: Color = Color::Blue;
|
||||
|
||||
const STYLE_TAG: Style = Style::new().fg(Color::Yellow);
|
||||
const STYLE_HASH: Style = Style::new().fg(Color::Magenta);
|
||||
const STYLE_TIME: Style = Style::new().fg(Color::Blue);
|
||||
const STYLE_AUTHOR: Style = Style::new().fg(Color::Green);
|
||||
const STYLE_MSG: Style = Style::new().fg(Color::Reset);
|
||||
|
||||
const STYLE_TAG_SELECTED: Style =
|
||||
Style::new().fg(Color::Yellow).bg(COLOR_SELECTION_BG);
|
||||
const STYLE_HASH_SELECTED: Style =
|
||||
Style::new().fg(Color::Magenta).bg(COLOR_SELECTION_BG);
|
||||
const STYLE_TIME_SELECTED: Style =
|
||||
@ -56,7 +59,7 @@ const STYLE_AUTHOR_SELECTED: Style =
|
||||
const STYLE_MSG_SELECTED: Style =
|
||||
Style::new().fg(Color::Reset).bg(COLOR_SELECTION_BG);
|
||||
|
||||
static ELEMENTS_PER_LINE: usize = 8;
|
||||
static ELEMENTS_PER_LINE: usize = 10;
|
||||
static SLICE_SIZE: usize = 1000;
|
||||
static SLICE_OFFSET_RELOAD_THRESHOLD: usize = 100;
|
||||
|
||||
@ -69,6 +72,7 @@ pub struct Revlog {
|
||||
visible: bool,
|
||||
first_open_done: bool,
|
||||
scroll_state: (Instant, f32),
|
||||
tags: Tags,
|
||||
}
|
||||
|
||||
impl Revlog {
|
||||
@ -82,6 +86,7 @@ impl Revlog {
|
||||
visible: false,
|
||||
first_open_done: false,
|
||||
scroll_state: (Instant::now(), 0_f32),
|
||||
tags: Tags::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,7 +99,12 @@ impl Revlog {
|
||||
|
||||
let mut txt = Vec::new();
|
||||
for (idx, e) in self.items.iter().enumerate() {
|
||||
Self::add_entry(e, idx == selection, &mut txt);
|
||||
let tag = if let Some(tag_name) = self.tags.get(&e.hash) {
|
||||
tag_name.as_str()
|
||||
} else {
|
||||
""
|
||||
};
|
||||
Self::add_entry(e, idx == selection, &mut txt, tag);
|
||||
}
|
||||
|
||||
let title =
|
||||
@ -138,9 +148,14 @@ impl Revlog {
|
||||
);
|
||||
|
||||
if let Ok(commits) = commits {
|
||||
self.items.extend(commits.iter().map(LogEntry::from));
|
||||
self.items
|
||||
.extend(commits.into_iter().map(LogEntry::from));
|
||||
}
|
||||
}
|
||||
|
||||
if self.tags.is_empty() {
|
||||
self.tags = sync::get_tags(CWD).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn move_selection(&mut self, up: bool) {
|
||||
@ -190,6 +205,7 @@ impl Revlog {
|
||||
e: &'a LogEntry,
|
||||
selected: bool,
|
||||
txt: &mut Vec<Text<'a>>,
|
||||
tag: &'a str,
|
||||
) {
|
||||
let count_before = txt.len();
|
||||
|
||||
@ -204,7 +220,7 @@ impl Revlog {
|
||||
};
|
||||
|
||||
txt.push(Text::Styled(
|
||||
Cow::from(e.hash.as_str()),
|
||||
Cow::from(&e.hash[0..7]),
|
||||
if selected {
|
||||
STYLE_HASH_SELECTED
|
||||
} else {
|
||||
@ -229,6 +245,19 @@ impl Revlog {
|
||||
STYLE_AUTHOR
|
||||
},
|
||||
));
|
||||
txt.push(splitter.clone());
|
||||
txt.push(Text::Styled(
|
||||
Cow::from(if tag.is_empty() {
|
||||
String::from("")
|
||||
} else {
|
||||
format!(" {}", tag)
|
||||
}),
|
||||
if selected {
|
||||
STYLE_TAG_SELECTED
|
||||
} else {
|
||||
STYLE_TAG
|
||||
},
|
||||
));
|
||||
txt.push(splitter);
|
||||
txt.push(Text::Styled(
|
||||
Cow::from(e.msg.as_str()),
|
||||
|
Loading…
Reference in New Issue
Block a user