Skip to content

Commit 1bf9f1c

Browse files
committed
Add support for git tags in --start and --end
1 parent 5298e9d commit 1bf9f1c

File tree

2 files changed

+35
-19
lines changed

2 files changed

+35
-19
lines changed

Diff for: src/git.rs

+15-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,21 @@ impl Commit {
2626
}
2727

2828
fn lookup_rev<'rev>(repo: &'rev Repository, rev: &str) -> Result<Git2Commit<'rev>, Error> {
29-
if let Ok(c) = repo.revparse_single(rev)?.into_commit() {
29+
let revision = repo.revparse_single(rev)?;
30+
31+
// Find the merge-base between the revision and master.
32+
// If revision is a normal commit contained in master, the merge-base will be the commit itself.
33+
// If revision is a tag (e.g. a release version), the merge-base will contain the latest master
34+
// commit contained in that tag.
35+
let master_id = repo.revparse_single("origin/master")?.id();
36+
let revision_id = revision
37+
.as_tag()
38+
.map(|tag| tag.target_id())
39+
.unwrap_or_else(|| revision.id());
40+
41+
let common_base = repo.merge_base(master_id, revision_id)?;
42+
43+
if let Ok(c) = repo.find_commit(common_base) {
3044
return Ok(c);
3145
}
3246
bail!("Could not find a commit for revision specifier '{}'", rev)

Diff for: src/github.rs

+20-18
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ use serde::{Deserialize, Serialize};
44

55
use crate::Commit;
66

7+
#[derive(Serialize, Deserialize, Debug)]
8+
struct GithubCommitComparison {
9+
merge_base_commit: GithubCommitElem,
10+
}
711
#[derive(Serialize, Deserialize, Debug)]
812
struct GithubCommitElem {
913
commit: GithubCommit,
@@ -53,11 +57,11 @@ fn headers() -> Result<reqwest::header::HeaderMap, Error> {
5357
}
5458

5559
pub(crate) fn get_commit(sha: &str) -> Result<Commit, Error> {
56-
let url = SingleCommitUrl { sha }.url();
60+
let url = CommitDetailsUrl { sha }.url();
5761
let client = Client::builder().default_headers(headers()?).build()?;
5862
let response: Response = client.get(&url).send()?;
59-
let elem: GithubCommitElem = response.json()?;
60-
elem.git_commit()
63+
let elem: GithubCommitComparison = response.json()?;
64+
elem.merge_base_commit.git_commit()
6165
}
6266

6367
#[derive(Copy, Clone, Debug)]
@@ -89,7 +93,7 @@ struct CommitsUrl<'a> {
8993
since: &'a str,
9094
sha: &'a str,
9195
}
92-
struct SingleCommitUrl<'a> {
96+
struct CommitDetailsUrl<'a> {
9397
sha: &'a str,
9498
}
9599

@@ -110,25 +114,23 @@ impl<'a> ToUrl for CommitsUrl<'a> {
110114
}
111115
}
112116

113-
impl<'a> ToUrl for SingleCommitUrl<'a> {
117+
impl<'a> ToUrl for CommitDetailsUrl<'a> {
114118
fn url(&self) -> String {
115119
// "origin/master" is set as `sha` when there is no `--end=` definition
116120
// specified on the command line. We define the GitHub master branch
117121
// HEAD commit as the end commit in this case
118-
if self.sha == "origin/master" {
119-
format!(
120-
"https://api.github.com/repos/{OWNER}/{REPO}/commits/master",
121-
OWNER = OWNER,
122-
REPO = REPO,
123-
)
122+
let reference = if self.sha == "origin/master" {
123+
"master"
124124
} else {
125-
format!(
126-
"https://api.github.com/repos/{OWNER}/{REPO}/commits/{REF}",
127-
OWNER = OWNER,
128-
REPO = REPO,
129-
REF = self.sha
130-
)
131-
}
125+
self.sha
126+
};
127+
128+
format!(
129+
"https://api.github.com/repos/{OWNER}/{REPO}/compare/master...{REF}",
130+
OWNER = OWNER,
131+
REPO = REPO,
132+
REF = reference
133+
)
132134
}
133135
}
134136

0 commit comments

Comments
 (0)