问题
I'm trying to get all commits in a git tag throw github api. I checked in this stack overflow issue but in this way, it asks me to compare between two tags and it returns me only the first commit. I want to get all commits of a specific tag. what I used is
https://api.github.com/repos/:org/:repo/compare/:tag_1...:tag_2
because I want to specific tag I added the same tag
https://api.github.com/repos/RapidAPI/ant-design/compare/3.13.2...3.13.2
it return me the only 2 commits but in the tag I have many commits as you can see here.
回答1:
It wasn't clear what the constraints were tech-wise so here is an example solution using Node that should illustrate what's possible.
I believe the tags returned by /repos/:owner/:name/tags
are not sorted by date created, but instead alphabetically, so I had to filter out the tags that didn't match the version regex to catch some stray inputs. To ensure the order was correct I used the semver
npm package to sort them based on version.
Then it was a matter of just using the Compare endpoint with the two latest tags in the repository.
// API client for working with GitHub data using promises
const { Octokit } = require("@octokit/rest");
// helper function to compare two version strings using semver
const semverGt = require('semver/functions/gt');
const owner = "RapidAPI";
const repo = "ant-design";
const octokit = new Octokit();
octokit.repos
.listTags({
owner,
repo,
})
.then(({ data: tags }) => {
// filter out tags that don't look like releases
const sortedTaggedVersions = tags.filter(t => t.name.match(/\d+.\d+.\d+/))
.sort((a, b) => semverGt(a.name, b.name));
// these are out inputs for locating the commits that are in the latest
// release (aka "head") but are not in the previous release (aka "base")
const head = sortedTaggedVersions[0].name;
const base = sortedTaggedVersions[1].name;
console.log(`Comparing base ${base} and head ${head}...`)
return octokit.repos.compareCommits({
owner,
repo,
base,
head,
});
})
.then(({ data }) => {
console.log(`Found ${data.commits.length} commits:`);
for (const c of data.commits) {
let message = c.commit.message;
// only show first line of commit message to keep output clean
const newline = message.indexOf("\n");
if (newline > -1) {
message = message.substr(0, newline);
}
let author = c.author ? `@${c.author.login}` : null;
if (author == null) {
// use the name from the commit itself if we cannot find a GitHub committer
author = c.commit.author.name;
}
console.log(` - ${c.sha} - ${author} - ${message}`)
}
})
.catch(err => {
console.error("Unable to find commits", err);
});
This is the result:
$ node index.js
Comparing base 3.13.1 and head 3.13.2...
Found 19 commits:
- 4b526bf251fde5d4b6f1fec6d1ec3eb8805b4c75 - @orzyyyy - docs: fix wrong comma
- 736f5b9549a3de6d694786f63f835aa26c29d105 - @pine3ree - doc: handle invalid date in message.info() call
- 0d65f0578de652d2b3f5231088eaeaab95d8a3be - dependabot[bot] - :arrow_up: Update @types/react requirement from ~16.7.13 to ~16.8.1
- c895c809f91e7ce817d9a42c4e0fd3ea5311d198 - @gyh9457 - improve tabs demo (#14701)
- 163140189f57c225dd49758f4ea2b8116f201dc9 - @ashearer - Fix quote rendering (#14708)
- 31d55e43b358c148640a7991b444c56e1cf25456 - @ycjcl868 - upd: version
- 976a6a5c5a2adb3c407e953b95df08f6810e0cd5 - @Josephus-P - Fixed typos and improved grammar
- b6f81340baeec20caa8511693ea4ec7d7d0c0ba7 - @Josephus-P - small change
- 777c56a515159a2eb7e809695def53d66aebfc10 - @zombieJ - mock test
- 6f040b6c4090fbc060bf2a06a7a01b900f4fe890 - @ycjcl868 - fix: strict check input
- 6cdc203a2fc58b5c89ea7bfe0ef361e7afdf95e6 - @ycjcl868 - Merge pull request #14725 from ant-design/fix-form-test
- 99eeefc25d38a2e2060c23de0f8446fd90729911 - @imhele - correct type in Switch (#14727)
- 2b558af9600c0d0fa56467b8de0522b2a4277232 - @zombieJ - update silder snapshot (#14732)
- b3834e48b1e009adbd142a7e2c38a129729170de - @imhele - Table: fix showing only first page (#14724)
- 991b47f421bc3c60d30a8ff1d689615e6b70dbe1 - @zombieJ - update antd-tools version to check (#14738)
- dfc9b24c989c58ffe6a922b45286e09450f85579 - @GabeMedrash - Properly type onMouseEnter and onMouseLeave events
- 5ad97a33d1d65f05a121796210e4fa15f2894c5c - @afc163 - :lipstick: improve home page style in mobile device
- a9a6da47ed44d811e402822ec3933608405c27fb - @thilo-behnke - Input: Clear icon doesn't disappear if value is null (vs undefined or empy string) (#14733)
- dab30ef2ccead39135ff6e4b215259344d812897 - @zombieJ - update changelog (#14746)
This is different to the provided URL from the screenshot https://api.github.com/repos/RapidAPI/ant-design/compare/3.13.2...3.13.2
because it uses the version 3.13.2
for both tags.
回答2:
yes, I would happy to know what is doing when the same tag..
To explain the /repos/:owner/:repo/compare/:base...:head
API I first need to explain the corresponding API in Git itself - how to get a list of commits.
If you were to run git log 3.13.2
it would do a few things:
- figure out that
3.13.2
is a tag (a branch, commit ID, or other aliases could also be used here) - find the commit that belongs to this tag
- list the details about this first commit
- check the first parent of this commit
GOTO 3
It'll then continue to traverse the history of the repository until you decide to exit the process.
But what if we only want to go back to a certain point? This is where "commit ranges" comes into play.
If you were working on the command line to find the commits between two tags, you'd probably use this syntax:
$ git log 3.13.1...3.13.2 --oneline
dab30ef2cc (tag: 3.13.2) update changelog (#14746)
a9a6da47ed Input: Clear icon doesn't disappear if value is null (vs undefined or empy string) (#14733)
5ad97a33d1 :lipstick: improve home page style in mobile device
dfc9b24c98 Properly type onMouseEnter and onMouseLeave events
991b47f421 update antd-tools version to check (#14738)
b3834e48b1 Table: fix showing only first page (#14724)
2b558af960 update silder snapshot (#14732)
99eeefc25d correct type in Switch (#14727)
6cdc203a2f Merge pull request #14725 from ant-design/fix-form-test
6f040b6c40 fix: strict check input
777c56a515 mock test
b6f81340ba small change
976a6a5c5a Fixed typos and improved grammar
31d55e43b3 upd: version
163140189f Fix quote rendering (#14708)
c895c809f9 improve tabs demo (#14701)
0d65f0578d :arrow_up: Update @types/react requirement from ~16.7.13 to ~16.8.1
736f5b9549 doc: handle invalid date in message.info() call
4b526bf251 docs: fix wrong comma
This is what the design of the /repos/:owner/:repo/compare/:base...:head
API is based upon - providing the commit range that you want to query on in the form of two tags. But what happens when you provide the same tag twice?
$ git log 3.13.2...3.13.2 --oneline
No commits are returned, because Git thinks you want to find the range of commits from the same tag - which is an empty set. This is what the GitHub API is doing with your initial API call.
来源:https://stackoverflow.com/questions/61359461/get-all-commits-in-a-git-tag-through-github-api-return-only-the-first-commit