1use crate::{find_upstream_git, scan_path, Options};
2use std::path::{Path, PathBuf};
3use std::process::Command;
4
5pub fn run() -> anyhow::Result<()> {
7 let options = Options::parse();
8 let upgit = find_upstream_git()?;
9
10 let exepath = if options.upstream {
11 upgit.clone()
12 } else {
13 find_override_path(options.args.iter())?.unwrap_or_else(|| upgit.clone())
14 };
15
16 let status = Command::new(exepath)
17 .env("GIT_OVERRIDE_UPSTREAM", &upgit)
18 .args(&options.args)
19 .status()?;
20
21 handle_exit_status(&upgit, status)
22}
23
24fn find_override_path<'a, I>(mut args: I) -> anyhow::Result<Option<PathBuf>>
25where
26 I: Iterator<Item = &'a String>,
27{
28 if let Some(subcmd) = args.find(|a| !a.starts_with('-')) {
29 let candidate = format!("git-{}", subcmd);
30 Ok(scan_path(candidate)?.into_iter().next())
31 } else {
32 Ok(None)
33 }
34}
35
36fn handle_exit_status(upgit: &Path, status: std::process::ExitStatus) -> anyhow::Result<()> {
37 if status.success() {
38 Ok(())
39 } else {
40 let code = status.code().ok_or_else(|| {
41 errormsg!(
42 "No exit status code from executing upstream git {:?}",
43 upgit,
44 )
45 })?;
46 std::process::exit(code);
47 }
48}