Skip to content

Commit 95eeafa

Browse files
committed
Auto merge of #13969 - weihanglo:full-commit-sha, r=epage
fix: check if rev is full commit sha for github fast path
2 parents 37e5f13 + 26c88db commit 95eeafa

File tree

2 files changed

+21
-9
lines changed

2 files changed

+21
-9
lines changed

src/cargo/sources/git/source.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::core::global_cache_tracker;
44
use crate::core::GitReference;
55
use crate::core::SourceId;
66
use crate::core::{Dependency, Package, PackageId};
7+
use crate::sources::git::utils::rev_to_oid;
78
use crate::sources::git::utils::GitRemote;
89
use crate::sources::source::MaybePackage;
910
use crate::sources::source::QueryKind;
@@ -171,14 +172,9 @@ enum Revision {
171172

172173
impl Revision {
173174
fn new(rev: &str) -> Revision {
174-
let oid = git2::Oid::from_str(rev).ok();
175-
match oid {
176-
// Git object ID is supposed to be a hex string of 20 (SHA1) or 32 (SHA256) bytes.
177-
// Its length must be double to the underlying bytes (40 or 64),
178-
// otherwise libgit2 would happily zero-pad the returned oid.
179-
// See rust-lang/cargo#13188
180-
Some(oid) if oid.as_bytes().len() * 2 == rev.len() => Revision::Locked(oid),
181-
_ => Revision::Deferred(GitReference::Rev(rev.to_string())),
175+
match rev_to_oid(rev) {
176+
Some(oid) => Revision::Locked(oid),
177+
None => Revision::Deferred(GitReference::Rev(rev.to_string())),
182178
}
183179
}
184180
}

src/cargo/sources/git/utils.rs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1421,7 +1421,7 @@ fn github_fast_path(
14211421
// to is itself. Don't bother talking to GitHub in that case
14221422
// either. (This ensures that we always attempt to fetch the
14231423
// commit directly even if we can't reach the GitHub API.)
1424-
if let Ok(oid) = rev.parse() {
1424+
if let Some(oid) = rev_to_oid(rev) {
14251425
debug!("github fast path is already a full commit hash {rev}");
14261426
return Ok(FastPathRev::NeedsFetch(oid));
14271427
}
@@ -1614,3 +1614,19 @@ mod tests {
16141614
}
16151615
}
16161616
}
1617+
1618+
/// Turns a full commit hash revision into an oid.
1619+
///
1620+
/// Git object ID is supposed to be a hex string of 20 (SHA1) or 32 (SHA256) bytes.
1621+
/// Its length must be double to the underlying bytes (40 or 64),
1622+
/// otherwise libgit2 would happily zero-pad the returned oid.
1623+
///
1624+
/// See:
1625+
///
1626+
/// * <https://github.com/rust-lang/cargo/issues/13188>
1627+
/// * <https://github.com/rust-lang/cargo/issues/13968>
1628+
pub(super) fn rev_to_oid(rev: &str) -> Option<Oid> {
1629+
Oid::from_str(rev)
1630+
.ok()
1631+
.filter(|oid| oid.as_bytes().len() * 2 == rev.len())
1632+
}

0 commit comments

Comments
 (0)