(output: &str)
| 156 | } |
| 157 | |
| 158 | fn parse_remote_git_status(output: &str) -> GitStatus { |
| 159 | let mut current_branch = "HEAD".to_string(); |
| 160 | let mut ahead = 0; |
| 161 | let mut behind = 0; |
| 162 | let mut staged = Vec::new(); |
| 163 | let mut unstaged = Vec::new(); |
| 164 | let mut untracked = Vec::new(); |
| 165 | |
| 166 | for line in output.lines() { |
| 167 | if let Some(branch) = line.strip_prefix("## ") { |
| 168 | let mut branch_part = branch.split("...").next().unwrap_or(branch).trim(); |
| 169 | if let Some((name, _)) = branch_part.split_once(' ') { |
| 170 | branch_part = name; |
| 171 | } |
| 172 | if !branch_part.is_empty() { |
| 173 | current_branch = branch_part.to_string(); |
| 174 | } |
| 175 | |
| 176 | if let Some(meta_start) = branch.find('[') { |
| 177 | if let Some(meta_end) = branch[meta_start + 1..].find(']') { |
| 178 | let meta = &branch[meta_start + 1..meta_start + 1 + meta_end]; |
| 179 | for part in meta.split(',').map(str::trim) { |
| 180 | if let Some(value) = part.strip_prefix("ahead ") { |
| 181 | ahead = value.parse().unwrap_or(0); |
| 182 | } else if let Some(value) = part.strip_prefix("behind ") { |
| 183 | behind = value.parse().unwrap_or(0); |
| 184 | } |
| 185 | } |
| 186 | } |
| 187 | } |
| 188 | continue; |
| 189 | } |
| 190 | |
| 191 | let Some((path, status, index_status, workdir_status)) = parse_remote_status_line(line) |
| 192 | else { |
| 193 | continue; |
| 194 | }; |
| 195 | |
| 196 | if status == "?" { |
| 197 | untracked.push(path); |
| 198 | continue; |
| 199 | } |
| 200 | |
| 201 | let file = GitFileStatus { |
| 202 | path, |
| 203 | status, |
| 204 | index_status, |
| 205 | workdir_status, |
| 206 | }; |
| 207 | |
| 208 | if file.index_status.is_some() { |
| 209 | staged.push(file.clone()); |
| 210 | } |
| 211 | if file.workdir_status.is_some() { |
| 212 | unstaged.push(file); |
| 213 | } |
| 214 | } |
| 215 |
no test coverage detected