1use std::ffi::OsString;
5use std::process::ExitCode;
6
7pub mod argv;
8pub mod attributes;
9pub mod clone;
10pub mod delegate;
11pub mod git;
12pub mod interrupt;
13pub mod plan;
14pub mod scratch_index;
15pub mod source;
16pub mod sprout;
17pub mod stats;
18pub mod tree;
19pub mod verify;
20
21use argv::{AddCommand, Invocation};
22use stats::Stats;
23
24pub fn run(args: Vec<OsString>) -> ExitCode {
26 let mut stats = Stats::default();
27
28 let (git_args, reason) = match argv::parse(&args) {
29 Invocation::Version => {
30 println!("git-sprout {}", env!("CARGO_PKG_VERSION"));
31 return ExitCode::SUCCESS;
32 }
33 Invocation::Delegate { git_args, reason } => (git_args, reason.to_string()),
34 Invocation::Add(add) => match decline(&add) {
35 Some(reason) => (add.git_args(), reason),
36 None => return sprout::add(&add, &mut stats),
37 },
38 };
39
40 stats.fall_back(reason);
41 stats.emit();
42 delegate::exec_git(&git_args)
43}
44
45fn decline(add: &AddCommand) -> Option<String> {
47 if add.no_cow {
48 return Some("--no-cow".to_string());
49 }
50 if std::env::var_os("SPROUT_DISABLE").is_some_and(|value| value == "1") {
51 return Some("SPROUT_DISABLE=1".to_string());
52 }
53 if !add.checkout {
54 return Some("--no-checkout".to_string());
55 }
56 if add.orphan {
57 return Some("--orphan".to_string());
58 }
59 if head_is_unborn(add) {
60 return Some("no commits yet".to_string());
61 }
62 None
63}
64
65fn head_is_unborn(add: &AddCommand) -> bool {
72 add.commit_ish.is_none()
73 && git::Git::new(add.globals.clone())
74 .capture(None, ["rev-parse", "--verify", "--quiet", "HEAD"])
75 .is_ok_and(|output| output.is_empty())
76}