|
1 | 1 | use assignment::FileAssignment;
|
2 |
| -use bstr::BString; |
| 2 | +use bstr::{BString, ByteSlice}; |
3 | 3 | use but_core::ui::{TreeChange, TreeStatus};
|
4 | 4 | use but_hunk_assignment::HunkAssignment;
|
5 | 5 | use but_settings::AppSettings;
|
@@ -67,37 +67,8 @@ pub(crate) fn worktree(repo_path: &Path, _json: bool, show_files: bool) -> anyho
|
67 | 67 | Ok(())
|
68 | 68 | }
|
69 | 69 |
|
70 |
| -pub fn print_group( |
71 |
| - project: &Project, |
72 |
| - group: Option<StackDetails>, |
73 |
| - assignments: Vec<FileAssignment>, |
74 |
| - changes: &[TreeChange], |
75 |
| - show_files: bool, |
76 |
| - stack_mark: &mut Option<ColoredString>, |
77 |
| - ctx: &mut CommandContext, |
78 |
| -) -> anyhow::Result<()> { |
79 |
| - let binding = group |
80 |
| - .clone() |
81 |
| - .map(|g| g.derived_name) |
82 |
| - .unwrap_or("UNASSIGNED".to_string()); |
83 |
| - let name = binding.as_str(); |
84 |
| - |
85 |
| - let id = if let Some(_group) = &group { |
86 |
| - CliId::branch(name) |
87 |
| - } else { |
88 |
| - CliId::unassigned() |
89 |
| - } |
90 |
| - .to_string() |
91 |
| - .underline() |
92 |
| - .blue(); |
93 |
| - println!( |
94 |
| - "╭ {} [{}] {}", |
95 |
| - id, |
96 |
| - name.green().bold(), |
97 |
| - stack_mark.clone().unwrap_or_default() |
98 |
| - ); |
99 |
| - *stack_mark = None; // Only show the stack mark for the first branch |
100 |
| - for fa in &assignments { |
| 70 | +fn print_assignments(assignments: &Vec<FileAssignment>, changes: &[TreeChange]) { |
| 71 | + for fa in assignments { |
101 | 72 | let state = status_from_changes(changes, fa.path.clone());
|
102 | 73 | let path = match &state {
|
103 | 74 | Some(state) => path_with_color(state, fa.path.to_string()),
|
@@ -134,61 +105,97 @@ pub fn print_group(
|
134 | 105 | }
|
135 | 106 | println!("│ {id} {path} {status} {locks}");
|
136 | 107 | }
|
137 |
| - if group.is_some() && !assignments.is_empty() { |
138 |
| - println!("│"); |
139 |
| - } |
140 |
| - let commits = match &group { |
141 |
| - Some(g) => g |
142 |
| - .branch_details |
143 |
| - .iter() |
144 |
| - .flat_map(|d| d.commits.iter().cloned()) |
145 |
| - .collect::<Vec<_>>(), |
146 |
| - None => Vec::new(), |
147 |
| - }; |
148 |
| - for commit in &commits { |
149 |
| - let marked = crate::mark::commit_marked(ctx, commit.id.to_string()).unwrap_or_default(); |
150 |
| - let mark = if marked { |
151 |
| - Some("◀ Marked ▶".red().bold()) |
152 |
| - } else { |
153 |
| - None |
154 |
| - }; |
155 |
| - let conflicted_str = if commit.has_conflicts { |
156 |
| - "{conflicted}".red() |
157 |
| - } else { |
158 |
| - "".normal() |
159 |
| - }; |
160 |
| - println!( |
161 |
| - "● {}{} {} {} {}", |
162 |
| - &commit.id.to_string()[..2].blue().underline(), |
163 |
| - &commit.id.to_string()[2..7].blue(), |
164 |
| - conflicted_str, |
165 |
| - commit |
166 |
| - .message |
| 108 | +} |
| 109 | + |
| 110 | +pub fn print_group( |
| 111 | + project: &Project, |
| 112 | + group: Option<StackDetails>, |
| 113 | + assignments: Vec<FileAssignment>, |
| 114 | + changes: &[TreeChange], |
| 115 | + show_files: bool, |
| 116 | + stack_mark: &mut Option<ColoredString>, |
| 117 | + ctx: &mut CommandContext, |
| 118 | +) -> anyhow::Result<()> { |
| 119 | + if let Some(group) = &group { |
| 120 | + let mut first = true; |
| 121 | + for branch in &group.branch_details { |
| 122 | + let id = CliId::branch(branch.name.to_str()?) |
167 | 123 | .to_string()
|
168 |
| - .replace('\n', " ") |
169 |
| - .chars() |
170 |
| - .take(50) |
171 |
| - .collect::<String>(), |
172 |
| - mark.unwrap_or_default() |
173 |
| - ); |
174 |
| - if show_files { |
175 |
| - let commit_details = but_api::diff::commit_details(project.id, commit.id.into())?; |
176 |
| - for change in &commit_details.changes.changes { |
177 |
| - let cid = CliId::committed_file(&change.path.to_string(), commit.id) |
178 |
| - .to_string() |
179 |
| - .blue() |
180 |
| - .underline(); |
181 |
| - let path = path_with_color(&change.status, change.path.to_string()); |
182 |
| - let status_letter = status_letter(&change.status); |
183 |
| - println!("│ {cid} {path} {status_letter}"); |
| 124 | + .underline() |
| 125 | + .blue(); |
| 126 | + let notch = if first { "╭" } else { "├" }; |
| 127 | + if !first { |
| 128 | + println!("│"); |
| 129 | + } |
| 130 | + println!( |
| 131 | + "{} {} [{}] {}", |
| 132 | + notch, |
| 133 | + id, |
| 134 | + branch.name.to_string().green().bold(), |
| 135 | + stack_mark.clone().unwrap_or_default() |
| 136 | + ); |
| 137 | + *stack_mark = None; // Only show the stack mark for the first branch |
| 138 | + if first { |
| 139 | + print_assignments(&assignments, changes); |
| 140 | + } |
| 141 | + first = false; |
| 142 | + for commit in &branch.commits { |
| 143 | + let marked = |
| 144 | + crate::mark::commit_marked(ctx, commit.id.to_string()).unwrap_or_default(); |
| 145 | + let mark = if marked { |
| 146 | + Some("◀ Marked ▶".red().bold()) |
| 147 | + } else { |
| 148 | + None |
| 149 | + }; |
| 150 | + let conflicted_str = if commit.has_conflicts { |
| 151 | + "{conflicted}".red() |
| 152 | + } else { |
| 153 | + "".normal() |
| 154 | + }; |
| 155 | + println!( |
| 156 | + "● {}{} {} {} {}", |
| 157 | + &commit.id.to_string()[..2].blue().underline(), |
| 158 | + &commit.id.to_string()[2..7].blue(), |
| 159 | + conflicted_str, |
| 160 | + commit |
| 161 | + .message |
| 162 | + .to_string() |
| 163 | + .replace('\n', " ") |
| 164 | + .chars() |
| 165 | + .take(50) |
| 166 | + .collect::<String>(), |
| 167 | + mark.unwrap_or_default() |
| 168 | + ); |
| 169 | + if show_files { |
| 170 | + let commit_details = |
| 171 | + but_api::diff::commit_details(project.id, commit.id.into())?; |
| 172 | + for change in &commit_details.changes.changes { |
| 173 | + let cid = CliId::committed_file(&change.path.to_string(), commit.id) |
| 174 | + .to_string() |
| 175 | + .blue() |
| 176 | + .underline(); |
| 177 | + let path = path_with_color(&change.status, change.path.to_string()); |
| 178 | + let status_letter = status_letter(&change.status); |
| 179 | + println!("│ {cid} {path} {status_letter}"); |
| 180 | + } |
| 181 | + if commit_details.changes.changes.is_empty() { |
| 182 | + println!("│ {}", "(no changes)".dimmed().italic()); |
| 183 | + } |
| 184 | + } |
184 | 185 | }
|
185 |
| - if commit_details.changes.changes.is_empty() { |
186 |
| - println!("│ {}", "(no changes)".dimmed().italic()); |
| 186 | + if branch.commits.is_empty() { |
| 187 | + println!("│ {}", "(no commits)".dimmed().italic()); |
187 | 188 | }
|
188 | 189 | }
|
189 |
| - } |
190 |
| - if group.is_some() && commits.is_empty() { |
191 |
| - println!("│ {}", "(no commits)".dimmed().italic()); |
| 190 | + } else { |
| 191 | + let id = CliId::branch("UNASSIGNED").to_string().underline().blue(); |
| 192 | + println!( |
| 193 | + "╭ {} [{}] {}", |
| 194 | + id, |
| 195 | + "UNASSIGNED".to_string().green().bold(), |
| 196 | + stack_mark.clone().unwrap_or_default() |
| 197 | + ); |
| 198 | + print_assignments(&assignments, changes); |
192 | 199 | }
|
193 | 200 | println!("┊");
|
194 | 201 | Ok(())
|
|
0 commit comments