diff --git a/Cargo.lock b/Cargo.lock index 44f6ea7..4755d6b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,6 +66,17 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "auth-git2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41e7771d4ab6635cbd685ce8db215b29c78a468098126de77c57f3b2e6eb3757" +dependencies = [ + "dirs", + "git2", + "terminal-prompt", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -204,6 +215,15 @@ dependencies = [ "dirs-sys", ] +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs-sys" version = "0.4.1" @@ -269,6 +289,7 @@ dependencies = [ name = "fj" version = "0.1.0" dependencies = [ + "auth-git2", "clap", "directories", "eyre", @@ -1206,6 +1227,16 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "terminal-prompt" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572818b3472910acbd5dff46a3413715c18e934b071ab2ba464a7b2c2af16376" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "thiserror" version = "1.0.43" diff --git a/Cargo.toml b/Cargo.toml index 45276b0..de514fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +auth-git2 = "0.5.3" clap = { version = "4.3.11", features = ["derive"] } directories = "5.0.1" eyre = "0.6.8" diff --git a/src/repo.rs b/src/repo.rs index 54a4eb9..8ca89e0 100644 --- a/src/repo.rs +++ b/src/repo.rs @@ -70,7 +70,7 @@ pub enum RepoCommand { // flags #[clap(long, short)] description: Option, - #[clap(long, short)] + #[clap(long, short = 'P')] private: bool, /// Sets the new repo to be the `origin` remote of the current local repo. #[clap(long, short)] @@ -120,10 +120,22 @@ impl RepoCommand { if set_upstream.is_some() || push { let repo = git2::Repository::open(".")?; + let upstream = set_upstream.as_deref().unwrap_or("origin"); let mut remote = repo.remote(upstream, new_repo.clone_url.as_str())?; + if push { - remote.push::<&str>(&[], None)?; + let head = repo.head()?; + if !head.is_branch() { + eyre::bail!("HEAD is not on a branch; cannot push to remote"); + } + let branch_shorthand = head.shorthand().ok_or_else(|| eyre!("branch name invalid utf-8"))?.to_owned(); + let branch_name = std::str::from_utf8(head.name_bytes())?.to_owned(); + let mut current_branch = git2::Branch::wrap(head); + current_branch.set_upstream(Some(&dbg!(format!("{upstream}/{branch_shorthand}"))))?; + + let auth = auth_git2::GitAuthenticator::new(); + auth.push(&repo, &mut remote, &[&branch_name])?; } } }