Skip to content

Add support for git tags in --start and --end #147

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion src/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,21 @@ impl Commit {
}

fn lookup_rev<'rev>(repo: &'rev Repository, rev: &str) -> Result<Git2Commit<'rev>, Error> {
if let Ok(c) = repo.revparse_single(rev)?.into_commit() {
let revision = repo.revparse_single(rev)?;

// Find the merge-base between the revision and master.
// If revision is a normal commit contained in master, the merge-base will be the commit itself.
// If revision is a tag (e.g. a release version), the merge-base will contain the latest master
// commit contained in that tag.
let master_id = repo.revparse_single("origin/master")?.id();
let revision_id = revision
.as_tag()
.map(|tag| tag.target_id())
.unwrap_or_else(|| revision.id());

let common_base = repo.merge_base(master_id, revision_id)?;

if let Ok(c) = repo.find_commit(common_base) {
return Ok(c);
}
bail!("Could not find a commit for revision specifier '{}'", rev)
Expand Down
38 changes: 20 additions & 18 deletions src/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ use serde::{Deserialize, Serialize};

use crate::Commit;

#[derive(Serialize, Deserialize, Debug)]
struct GithubCommitComparison {
merge_base_commit: GithubCommitElem,
}
#[derive(Serialize, Deserialize, Debug)]
struct GithubCommitElem {
commit: GithubCommit,
Expand Down Expand Up @@ -53,11 +57,11 @@ fn headers() -> Result<reqwest::header::HeaderMap, Error> {
}

pub(crate) fn get_commit(sha: &str) -> Result<Commit, Error> {
let url = SingleCommitUrl { sha }.url();
let url = CommitDetailsUrl { sha }.url();
let client = Client::builder().default_headers(headers()?).build()?;
let response: Response = client.get(&url).send()?;
let elem: GithubCommitElem = response.json()?;
elem.git_commit()
let elem: GithubCommitComparison = response.json()?;
elem.merge_base_commit.git_commit()
}

#[derive(Copy, Clone, Debug)]
Expand Down Expand Up @@ -89,7 +93,7 @@ struct CommitsUrl<'a> {
since: &'a str,
sha: &'a str,
}
struct SingleCommitUrl<'a> {
struct CommitDetailsUrl<'a> {
sha: &'a str,
}

Expand All @@ -110,25 +114,23 @@ impl<'a> ToUrl for CommitsUrl<'a> {
}
}

impl<'a> ToUrl for SingleCommitUrl<'a> {
impl<'a> ToUrl for CommitDetailsUrl<'a> {
fn url(&self) -> String {
// "origin/master" is set as `sha` when there is no `--end=` definition
// specified on the command line. We define the GitHub master branch
// HEAD commit as the end commit in this case
if self.sha == "origin/master" {
format!(
"https://api.github.com/repos/{OWNER}/{REPO}/commits/master",
OWNER = OWNER,
REPO = REPO,
)
let reference = if self.sha == "origin/master" {
"master"
} else {
format!(
"https://api.github.com/repos/{OWNER}/{REPO}/commits/{REF}",
OWNER = OWNER,
REPO = REPO,
REF = self.sha
)
}
self.sha
};

format!(
"https://api.github.com/repos/{OWNER}/{REPO}/compare/master...{REF}",
OWNER = OWNER,
REPO = REPO,
REF = reference
)
}
}

Expand Down
12 changes: 10 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,18 @@ struct Opts {
)]
command_args: Vec<OsString>,

#[structopt(long = "start", help = "Left bound for search (*without* regression)")]
#[structopt(
long = "start",
help = "Left bound for search (*without* regression). You can use \
a date (YYYY-MM-DD), git tag name (e.g. 1.58.0) or git commit SHA."
)]
start: Option<Bound>,

#[structopt(long = "end", help = "Right bound for search (*with* regression)")]
#[structopt(
long = "end",
help = "Right bound for search (*with* regression). You can use \
a date (YYYY-MM-DD), git tag name (e.g. 1.58.0) or git commit SHA."
)]
end: Option<Bound>,

#[structopt(long = "by-commit", help = "Bisect via commit artifacts")]
Expand Down