From 8606e1111d52de9518bd63cba0f4f18ffaab3db5 Mon Sep 17 00:00:00 2001 From: "Daniel Szoke (via Pi Coding Agent)" Date: Thu, 25 Jun 2026 11:32:35 +0200 Subject: [PATCH] fix(vcs): Upgrade git2 to address RustSec advisories Upgrade git2 to 0.21.0 to pick up fixes for the open RustSec advisories covering Remote::list() and blame APIs. The [git2 changelog](https://github.com/rust-lang/git2-rs/blob/main/CHANGELOG.md#changed) documents changed method signatures in 0.21.0. Update the VCS and code mappings callers because several git2 methods now return Result values instead of optional values. Closes #3338 Closes [CLI-334](https://linear.app/getsentry/issue/CLI-334) Closes #3339 Closes [CLI-335](https://linear.app/getsentry/issue/CLI-335) --- Cargo.lock | 5 ++--- Cargo.toml | 2 +- src/commands/code_mappings/upload.rs | 14 +++++++++----- src/utils/vcs.rs | 23 ++++++++++------------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7fa7281372..025e390bb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1288,15 +1288,14 @@ dependencies = [ [[package]] name = "git2" -version = "0.20.4" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" +checksum = "ddddbf932745a6be37109b6112d3ee09696106f848449069d3a57bba937ab82e" dependencies = [ "bitflags 2.11.1", "libc", "libgit2-sys", "log", - "url", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 99092a8382..0b6090b684 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ flate2 = { version = "1.0.25", default-features = false, features = [ "rust_backend", ] } futures-util = "0.3" -git2 = { version = "0.20.4", default-features = false } +git2 = { version = "0.21.0", default-features = false } glob = "0.3.1" http = "1.4.0" if_chain = "1.0.2" diff --git a/src/commands/code_mappings/upload.rs b/src/commands/code_mappings/upload.rs index b27ee8c1e7..ade2652a01 100644 --- a/src/commands/code_mappings/upload.rs +++ b/src/commands/code_mappings/upload.rs @@ -170,11 +170,15 @@ fn resolve_git_remote(repo: &git2::Repository) -> Option { /// Finds the remote whose URL matches the given repository name (e.g. "owner/repo"). fn find_remote_for_repo(repo: &git2::Repository, repo_name: &str) -> Option { let remotes = repo.remotes().ok()?; - let found = remotes.iter().flatten().find(|name| { - vcs::git_repo_remote_url(repo, name) - .map(|url| vcs::get_repo_from_remote_preserve_case(&url) == repo_name) - .unwrap_or(false) - })?; + let found = remotes + .iter() + .filter_map(Result::ok) + .flatten() + .find(|name| { + vcs::git_repo_remote_url(repo, name) + .map(|url| vcs::get_repo_from_remote_preserve_case(&url) == repo_name) + .unwrap_or(false) + })?; debug!("Found remote '{found}' matching repo '{repo_name}'"); Some(found.to_owned()) } diff --git a/src/utils/vcs.rs b/src/utils/vcs.rs index 2fd89b372d..52fb5658f5 100644 --- a/src/utils/vcs.rs +++ b/src/utils/vcs.rs @@ -255,10 +255,7 @@ pub fn git_repo_remote_url( cached_remote: &str, ) -> Result { let remote = repo.find_remote(cached_remote)?; - remote - .url() - .map(|url| url.to_owned()) - .ok_or_else(|| git2::Error::from_str("No remote URL found")) + remote.url().map(|url| url.to_owned()) } pub fn git_repo_head_ref(repo: &git2::Repository) -> Result { @@ -269,7 +266,7 @@ pub fn git_repo_head_ref(repo: &git2::Repository) -> Result { if head.is_branch() { head.shorthand() .map(|s| s.to_owned()) - .ok_or_else(|| anyhow::anyhow!("No HEAD reference found")) + .with_context(|| "No HEAD reference found") } else { // In detached HEAD state, return an error to indicate no valid branch reference Err(anyhow::anyhow!( @@ -287,7 +284,7 @@ pub fn git_repo_base_ref(repo: &git2::Repository, remote_name: &str) -> Result Result Result> { let remotes = repo.remotes()?; - let remote_names: Vec<&str> = remotes.iter().flatten().collect(); + let remote_names: Vec<&str> = remotes.iter().filter_map(Result::ok).flatten().collect(); if remote_names.is_empty() { return Ok(None); @@ -469,7 +466,7 @@ fn find_matching_rev( // mode we want to also check for matching URLs. if_chain! { if let Ok(remote) = repo.find_remote(&remote_name.unwrap_or_else(|| "origin".to_owned())); - if let Some(url) = remote.url(); + if let Ok(url) = remote.url(); then { if !discovery || is_matching_url(url, &reference_url) { debug!(" found match: {url} == {}, {r:?}", &reference_url); @@ -501,7 +498,7 @@ fn find_matching_submodule( ) -> Result> { // in discovery mode we want to find that repo in associated submodules. for submodule in repo.submodules()? { - if let Some(submodule_url) = submodule.url() { + if let Ok(Some(submodule_url)) = submodule.url() { debug!(" found submodule with URL {submodule_url}"); if is_matching_url(submodule_url, &reference_url) { debug!( @@ -792,9 +789,9 @@ pub fn generate_patch_set( for (index, commit) in commits.iter().enumerate() { let mut git_commit = GitCommit { id: commit.id().to_string(), - author_name: commit.author().name().map(|s| s.to_owned()), - author_email: commit.author().email().map(|s| s.to_owned()), - message: commit.message().map(|s| s.to_owned()), + author_name: commit.author().name().ok().map(|s| s.to_owned()), + author_email: commit.author().email().ok().map(|s| s.to_owned()), + message: commit.message().ok().map(|s| s.to_owned()), repository: repository.to_owned(), timestamp: get_commit_time(commit.author().when()), patch_set: vec![], @@ -1375,7 +1372,7 @@ mod tests { ( c.author().name().unwrap().to_owned(), c.author().email().unwrap().to_owned(), - c.summary(), + c.summary().unwrap(), ) }) .collect::>());