fn github_up_to_date(
    repo: &mut git2::Repository,
    url: &str,
    reference: &GitReference,
    config: &Config,
) -> CargoResult<bool> {
    let url = Url::parse(url)?;
    if url.host_str() != Some("github.com") {
        return Ok(false);
    }

    let github_branch_name = match reference {
        GitReference::Branch(branch) => branch,
        GitReference::Tag(tag) => tag,
        GitReference::DefaultBranch => "HEAD",
        GitReference::Rev(rev) => {
            if rev.starts_with("refs/") {
                rev
            } else {
                debug!("can't use github fast path with `rev = \"{}\"`", rev);
                return Ok(false);
            }
        }
    };

    // This expects GitHub urls in the form `github.com/user/repo` and nothing
    // else
    let mut pieces = url
        .path_segments()
        .ok_or_else(|| anyhow!("no path segments on url"))?;
    let username = pieces
        .next()
        .ok_or_else(|| anyhow!("couldn't find username"))?;
    let repository = pieces
        .next()
        .ok_or_else(|| anyhow!("couldn't find repository name"))?;
    if pieces.next().is_some() {
        anyhow::bail!("too many segments on URL");
    }

    // Trim off the `.git` from the repository, if present, since that's
    // optional for GitHub and won't work when we try to use the API as well.
    let repository = repository.strip_suffix(".git").unwrap_or(repository);

    let url = format!(
        "https://api.github.com/repos/{}/{}/commits/{}",
        username, repository, github_branch_name,
    );
    let mut handle = config.http()?.borrow_mut();
    debug!("attempting GitHub fast path for {}", url);
    handle.get(true)?;
    handle.url(&url)?;
    handle.useragent("cargo")?;
    let mut headers = List::new();
    headers.append("Accept: application/vnd.github.3.sha")?;
    headers.append(&format!("If-None-Match: \"{}\"", reference.resolve(repo)?))?;
    handle.http_headers(headers)?;
    handle.perform()?;
    Ok(handle.response_code()? == 304)
}
/// Updating the index is done pretty regularly so we want it to be as fast as
/// possible. For registries hosted on GitHub (like the crates.io index) there's
/// a fast path available to use [1] to tell us that there's no updates to be
/// made.
///
/// This function will attempt to hit that fast path and verify that the `oid`
/// is actually the current branch of the repository. If `true` is returned then
/// no update needs to be performed, but if `false` is returned then the
/// standard update logic still needs to happen.
///
/// [1]: https://developer.github.com/v3/repos/commits/#get-the-sha-1-of-a-commit-reference
///
/// Note that this function should never cause an actual failure because it's
/// just a fast path. As a result all errors are ignored in this function and we
/// just return a `bool`. Any real errors will be reported through the normal
/// update path above.
Updating the index is done pretty regularly so we want it to be as fast as
possible. For registries hosted on GitHub (like the crates.io index) there's
a fast path available to use [1] to tell us that there's no updates to be
made.

This function will attempt to hit that fast path and verify that the `oid`
is actually the current branch of the repository. If `true` is returned then
no update needs to be performed, but if `false` is returned then the
standard update logic still needs to happen.



Note that this function should never cause an actual failure because it's
just a fast path. As a result all errors are ignored in this function and we
just return a `bool`. Any real errors will be reported through the normal
update path above.
Updating the index is done pretty regularly so we want it to be as fast as possible . For registries hosted on GitHub ( like the crates . io index ) there ' s a fast path available to use [ 1 ] to tell us that there ' s no updates to be made . This function will attempt to hit that fast path and verify that the ` oid ` is actually the current branch of the repository . If ` true ` is returned then no update needs to be performed but if ` false ` is returned then the standard update logic still needs to happen . Note that this function should never cause an actual failure because it ' s just a fast path . As a result all errors are ignored in this function and we just return a ` bool ` . Any real errors will be reported through the normal update path above .
fn github_up_to_date(
    repo: &mut git2::Repository,
    url: &str,
    reference: &GitReference,
    config: &Config,
) -> CargoResult<bool> {
    let url = Url::parse(url)?;
    if url.host_str() != Some("github.com") {
        return Ok(false);
    }
    let github_branch_name = match reference {
        GitReference::Branch(branch) => branch,
        GitReference::Tag(tag) => tag,
        GitReference::DefaultBranch => "HEAD",
        GitReference::Rev(rev) => {
            if rev.starts_with("refs/") {
                rev
            } else {
                debug!("can't use github fast path with `rev = \"{}\"`", rev);
                return Ok(false);
            }
        }
    };
    // This expects GitHub urls in the form `github.com/user/repo` and nothing
    // else
    let mut pieces = url
        .path_segments()
        .ok_or_else(|| anyhow!("no path segments on url"))?;
    let username = pieces
        .next()
        .ok_or_else(|| anyhow!("couldn't find username"))?;
    let repository = pieces
        .next()
        .ok_or_else(|| anyhow!("couldn't find repository name"))?;
    if pieces.next().is_some() {
        anyhow::bail!("too many segments on URL");
    }
    // Trim off the `.git` from the repository, if present, since that's
    // optional for GitHub and won't work when we try to use the API as well.
    let repository = repository.strip_suffix(".git").unwrap_or(repository);
    let url = format!(
        "https://api.github.com/repos/{}/{}/commits/{}",
        username, repository, github_branch_name,
    );
    let mut handle = config.http()?.borrow_mut();
    debug!("attempting GitHub fast path for {}", url);
    handle.get(true)?;
    handle.url(&url)?;
    handle.useragent("cargo")?;
    let mut headers = List::new();
    headers.append("Accept: application/vnd.github.3.sha")?;
    headers.append(&format!("If-None-Match: \"{}\"", reference.resolve(repo)?))?;
    handle.http_headers(headers)?;
    handle.perform()?;
    Ok(handle.response_code()? == 304)
}
fn github_up_to_date ( repo : & mut git2 :: Repository , url : & str , reference : & GitReference , config : & Config , ) -> CargoResult < bool > { let url = Url :: parse ( url ) ? ; if url . host_str ( ) != Some ( " " ) { return Ok ( false ) ; } let github_branch_name = match reference { GitReference :: Branch ( branch ) => branch , GitReference :: Tag ( tag ) => tag , GitReference :: DefaultBranch => " " , GitReference :: Rev ( rev ) => { if rev . starts_with ( " " ) { rev } else { debug ! ( " \" \" " rev ) ; return Ok ( false ) ; } } } ; // This expects GitHub urls in the form `github.com/user/repo` and nothing // else let mut pieces = url . path_segments ( ) . ok_or_else ( | | anyhow ! ( " " ) ) ? ; let username = pieces . next ( ) . ok_or_else ( | | anyhow ! ( " " ) ) ? ; let repository = pieces . next ( ) . ok_or_else ( | | anyhow ! ( " " ) ) ? ; if pieces . next ( ) . is_some ( ) { anyhow :: bail ! ( " " ) ; } // Trim off the `.git` from the repository, if present, since that's // optional for GitHub and won't work when we try to use the API as well. let repository = repository . strip_suffix ( " " ) . unwrap_or ( repository ) ; let url = format ! ( " " username repository github_branch_name ) ; let mut handle = config . http ( ) ? . borrow_mut ( ) ; debug ! ( " " url ) ; handle . get ( true ) ? ; handle . url ( & url ) ? ; handle . useragent ( " " ) ? ; let mut headers = List :: new ( ) ; headers . append ( " " ) ? ; headers . append ( & format ! ( " \" \" " reference resolve ( repo ) ) ) ? ; handle . http_headers ( headers ) ? ; handle . perform ( ) ? ; Ok ( handle . response_code ( ) ? == 304 ) }
Updating the index is done pretty regularly so we want it to be as fast as
possible.
Updating the index is done pretty regularly so we want it to be as fast as possible .
repo
&mut git2::Repository
url
&str
reference
&GitReference
config
&Config
repo
&mut git2::Repository
url
&str
reference
&GitReference
config
&Config