//! Spawning `git` from hive-c0re: the binary lookup and the credential //! handoff. use tokio::process::Command; /// Spawn `git` honoring the `HYPERHIVE_GIT` env var (absolute path baked in /// by the NixOS module), falling back to bare `git` (PATH lookup) otherwise. /// /// `kill_on_drop(true)`: if the caller's future is dropped before the child /// exits — e.g. a `tokio::time::timeout` around startup migration fires — the /// git child is killed instead of orphaned (left retrying an unreachable /// forge). No-op on normal completion, where the child has already exited. #[must_use] pub fn git_command() -> Command { let exe = std::env::var("HYPERHIVE_GIT").unwrap_or_else(|_| "git".into()); let mut cmd = Command::new(exe); cmd.kill_on_drop(true); cmd } /// [`git_command`] carrying HTTP credentials **in its environment**. /// /// `auth_header` is an `Authorization:` line (see /// `forge::basic_auth_header`) handed to git as `http.extraHeader` /// through `GIT_CONFIG_*`, which git reads exactly like a config file. The /// alternative — userinfo in the remote URL — puts the secret in `argv`, and /// `/proc//cmdline` is world-readable while `/proc//environ` is /// owner-only. Same credential, materially smaller audience. /// /// `GIT_CONFIG_COUNT` needs git >= 2.31; `HYPERHIVE_GIT` points at a pinned /// nixpkgs git well past that. #[must_use] pub fn git_command_authed(auth_header: &str) -> Command { let mut cmd = git_command(); cmd.env("GIT_CONFIG_COUNT", "1") .env("GIT_CONFIG_KEY_0", "http.extraHeader") .env("GIT_CONFIG_VALUE_0", auth_header); cmd }