pending merge: more obvious repo state visualization (#943)

fixes #925
This commit is contained in:
Stephan Dilly 2021-10-11 11:08:34 +02:00 committed by GitHub
parent d78b029c21
commit 39400aac92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 38 deletions

View File

@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased ## Unreleased
**rebase merge with conflicts**
![rebase-merge](assets/rebase.png)
## Added ## Added
- support rebasing branches with conflicts ([#895](https://github.com/extrawurst/gitui/issues/895)) - support rebasing branches with conflicts ([#895](https://github.com/extrawurst/gitui/issues/895))
- add a key binding to stage / unstage items [[@alessandroasm](https://github.com/alessandroasm)] ([#909](https://github.com/extrawurst/gitui/issues/909)) - add a key binding to stage / unstage items [[@alessandroasm](https://github.com/alessandroasm)] ([#909](https://github.com/extrawurst/gitui/issues/909))

BIN
assets/rebase.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 KiB

View File

@ -23,11 +23,10 @@ use crossbeam_channel::Sender;
use crossterm::event::Event; use crossterm::event::Event;
use itertools::Itertools; use itertools::Itertools;
use std::convert::Into; use std::convert::Into;
use std::convert::TryFrom;
use tui::{ use tui::{
layout::{Alignment, Constraint, Direction, Layout}, layout::{Alignment, Constraint, Direction, Layout},
style::{Color, Style}, style::{Color, Style},
widgets::Paragraph, widgets::{Block, BorderType, Borders, Paragraph},
}; };
/// what part of the screen is focused /// what part of the screen is focused
@ -80,6 +79,19 @@ impl DrawableComponent for Status {
f: &mut tui::Frame<B>, f: &mut tui::Frame<B>,
rect: tui::layout::Rect, rect: tui::layout::Rect,
) -> Result<()> { ) -> Result<()> {
let repo_unclean = Self::repo_state_unclean();
let rects = if repo_unclean {
Layout::default()
.direction(Direction::Vertical)
.constraints(
[Constraint::Min(1), Constraint::Length(3)]
.as_ref(),
)
.split(rect)
} else {
vec![rect]
};
let chunks = Layout::default() let chunks = Layout::default()
.direction(Direction::Horizontal) .direction(Direction::Horizontal)
.constraints( .constraints(
@ -96,7 +108,7 @@ impl DrawableComponent for Status {
} }
.as_ref(), .as_ref(),
) )
.split(rect); .split(rects[0]);
let left_chunks = Layout::default() let left_chunks = Layout::default()
.direction(Direction::Vertical) .direction(Direction::Vertical)
@ -120,7 +132,10 @@ impl DrawableComponent for Status {
self.index.draw(f, left_chunks[1])?; self.index.draw(f, left_chunks[1])?;
self.diff.draw(f, chunks[1])?; self.diff.draw(f, chunks[1])?;
self.draw_branch_state(f, &left_chunks); self.draw_branch_state(f, &left_chunks);
Self::draw_repo_state(f, left_chunks[0])?;
if repo_unclean {
Self::draw_repo_state(f, rects[1]);
}
Ok(()) Ok(())
} }
@ -221,32 +236,27 @@ impl Status {
let ids = let ids =
sync::mergehead_ids(CWD).unwrap_or_default(); sync::mergehead_ids(CWD).unwrap_or_default();
let ids = format!( format!(
"({})", "Commits: {}",
ids.iter() ids.iter()
.map(sync::CommitId::get_short_string) .map(sync::CommitId::get_short_string)
.join(",") .join(",")
); )
format!("{:?} {}", state, ids)
} }
RepoState::Rebase => { RepoState::Rebase => {
let progress = if let Ok(p) = sync::rebase_progress(CWD) {
if let Ok(p) = sync::rebase_progress(CWD) { format!(
format!( "Step: {}/{} Current Commit: {}",
"[{}] {}/{}", p.current + 1,
p.current_commit p.steps,
.as_ref() p.current_commit
.map(CommitId::get_short_string) .as_ref()
.unwrap_or_default(), .map(CommitId::get_short_string)
p.current + 1, .unwrap_or_default(),
p.steps )
) } else {
} else { String::new()
String::new() }
};
format!("{:?} ({})", state, progress)
} }
_ => format!("{:?}", state), _ => format!("{:?}", state),
} }
@ -255,30 +265,36 @@ impl Status {
fn draw_repo_state<B: tui::backend::Backend>( fn draw_repo_state<B: tui::backend::Backend>(
f: &mut tui::Frame<B>, f: &mut tui::Frame<B>,
r: tui::layout::Rect, r: tui::layout::Rect,
) -> Result<()> { ) {
if let Ok(state) = sync::repo_state(CWD) { if let Ok(state) = sync::repo_state(CWD) {
if state != RepoState::Clean { if state != RepoState::Clean {
let txt = Self::repo_state_text(&state); let txt = Self::repo_state_text(&state);
let txt_len = u16::try_from(txt.len())?;
let w = Paragraph::new(txt) let w = Paragraph::new(txt)
.block(
Block::default()
.border_type(BorderType::Plain)
.borders(Borders::all())
.border_style(
Style::default().fg(Color::Yellow),
)
.title(format!("Pending {:?}", state)),
)
.style(Style::default().fg(Color::Red)) .style(Style::default().fg(Color::Red))
.alignment(Alignment::Left); .alignment(Alignment::Left);
let mut rect = r; f.render_widget(w, r);
rect.x += 1;
rect.width =
rect.width.saturating_sub(2).min(txt_len);
rect.y += rect.height.saturating_sub(1);
rect.height = rect
.height
.saturating_sub(rect.height.saturating_sub(1));
f.render_widget(w, rect);
} }
} }
}
Ok(()) fn repo_state_unclean() -> bool {
if let Ok(state) = sync::repo_state(CWD) {
if state != RepoState::Clean {
return true;
}
}
false
} }
fn can_focus_diff(&self) -> bool { fn can_focus_diff(&self) -> bool {