git_global/subcommands/
staged.rs

1//! The `staged` subcommand: shows `git status -s` for staged changes in all
2//! known repos with such changes.
3
4use std::sync::{mpsc, Arc};
5use std::thread;
6
7use crate::config::Config;
8use crate::errors::Result;
9use crate::repo::Repo;
10use crate::report::Report;
11
12/// Runs the `staged` subcommand.
13pub fn execute(mut config: Config) -> Result<Report> {
14    let include_untracked = config.show_untracked;
15    let repos = config.get_repos();
16    let n_repos = repos.len();
17    let mut report = Report::new(&repos);
18    report.pad_repo_output();
19    // TODO: limit number of threads, perhaps with mpsc::sync_channel(n)?
20    let (tx, rx) = mpsc::channel();
21    for repo in repos {
22        let tx = tx.clone();
23        let repo = Arc::new(repo);
24        thread::spawn(move || {
25            let path = repo.path();
26            let mut status_opts = ::git2::StatusOptions::new();
27            status_opts
28                .show(::git2::StatusShow::Index)
29                .include_untracked(include_untracked)
30                .include_ignored(false);
31            let lines = repo.get_status_lines(status_opts);
32            tx.send((path, lines)).unwrap();
33        });
34    }
35    for _ in 0..n_repos {
36        let (path, lines) = rx.recv().unwrap();
37        let repo = Repo::new(path.to_string());
38        for line in lines {
39            report.add_repo_message(&repo, line);
40        }
41    }
42    Ok(report)
43}