Push the current branch to the remote.
(&self, git_repo: &GitRepository)
| 250 | |
| 251 | /// Push the current branch to the remote. |
| 252 | fn push_to_remote(&self, git_repo: &GitRepository) -> CliResult<()> { |
| 253 | let head = git_repo.head().map_err(|e| CliError::GitError { |
| 254 | message: format!("Failed to get HEAD: {}", e), |
| 255 | })?; |
| 256 | let branch_name = head.shorthand().unwrap_or("HEAD"); |
| 257 | let refspec = format!("refs/heads/{}:refs/heads/{}", branch_name, branch_name); |
| 258 | |
| 259 | let mut remote = git_repo |
| 260 | .find_remote(&self.remote) |
| 261 | .map_err(|e| CliError::GitError { |
| 262 | message: format!("Remote '{}' not found: {}", self.remote, e), |
| 263 | })?; |
| 264 | |
| 265 | let mut push_options = git2::PushOptions::new(); |
| 266 | let mut callbacks = git2::RemoteCallbacks::new(); |
| 267 | callbacks.credentials(|_url, username_from_url, allowed_types| { |
| 268 | if allowed_types.contains(git2::CredentialType::SSH_KEY) { |
| 269 | let user = username_from_url.unwrap_or("git"); |
| 270 | git2::Cred::ssh_key_from_agent(user) |
| 271 | } else if allowed_types.contains(git2::CredentialType::DEFAULT) { |
| 272 | git2::Cred::default() |
| 273 | } else { |
| 274 | Err(git2::Error::from_str("no suitable credential type")) |
| 275 | } |
| 276 | }); |
| 277 | push_options.remote_callbacks(callbacks); |
| 278 | |
| 279 | remote |
| 280 | .push(&[&refspec], Some(&mut push_options)) |
| 281 | .map_err(|e| CliError::GitError { |
| 282 | message: format!("Push failed: {}", e), |
| 283 | })?; |
| 284 | |
| 285 | Ok(()) |
| 286 | } |
| 287 | } |
| 288 | |
| 289 | #[cfg(test)] |