question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Best way to get tags on a commit?

See original GitHub issue

I have come up with the following solution. It is far from optimal. It reads all the tags in the repo just to find out the tags on one commit.

I feel there must be a better way but haven’t figured it out yet from looking at the api docs.

If there is a much better approach for this I would be happy to submit an PR to the examples folder for it after.

import * as Git from "nodegit"

type TagWithCommits = {
  commit: Git.Object
  tags: Git.Reference[]
}

async function getTaggedCommits(
  repo: Git.Repository,
): Promise<TagWithCommits[]> {
  const refs: Git.Reference[] = await (repo.getReferences as any)()
  const commitsWithTags: Record<string, TagWithCommits> = {}

  for (const ref of refs) {
    if (!ref.isTag()) continue
    const commit = await ref.peel(Git.Object.TYPE.COMMIT)
    const id = commit.id().tostrS()
    let entry = commitsWithTags[id]
    if (!entry) {
      commitsWithTags[id] = entry = { tags: [], commit }
    }
    entry.tags.push(ref)
  }

  return Object.values(commitsWithTags)
}

async function getTagsOnCommit(c: Git.Commit): Promise<Git.Reference[]> {
  const repo = c.owner()
  const taggedCommits = await getTaggedCommits(repo)
  const taggedCommit = taggedCommits.filter(
    tc => tc.commit.id().tostrS() === c.id().tostrS(),
  )

  if (taggedCommit.length > 1) {
    throw new Error(
      "Found multiple tagged commit matches which should be impossible",
    )
  } else if (taggedCommit.length === 1) {
    return taggedCommit[0].tags
  } else {
    return []
  }
}

Git.Repository.open(".")
  .then(async repo => {
    const commit = await repo.getHeadCommit()
    const tagsOnCommit = await getTagsOnCommit(commit)

    if (tagsOnCommit.length) {
      console.log(
        "The current commit (%s) has tags: %s",
        commit,
        tagsOnCommit.map(r => r.shorthand()).join(", "),
      )
    } else {
      console.log("The current commit (%s) has no tags", commit)
    }
  })
  .catch(console.error)

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:1
  • Comments:5 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
implausiblecommented, Mar 10, 2021

This library is lower level than I think is being expected here. Tags as stored in the .git repository are flat files that list what sha they point to. In order for git to run git tag --points-at HEAD, git has to internally walk the entire refs tree in the .git folder and read every entry and then parse which pont to the particular oid you asked it to check against. This solution is the only way for any git-like library to perform the action we’re asking to do here.

I would be willing to accept a PR to NodeGit to wrap this behavior up as a convenience function though.

0reactions
philjacksoncommented, Mar 10, 2021

@implausible thanks for the explanation, will optimise my end.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to find the tag associated with a given git commit?
Check the documentation for git describe . It finds the nearest tag to a given commit (that is a tag which points to...
Read more >
Git - Tagging - Git SCM
Another way to tag commits is with a lightweight tag. This is basically the commit checksum stored in a file — no other...
Read more >
How to tag a Git commit id by example - TheServerSide.com
Tag the commit with this command: git tag -a M1 e3afd034 -m "Tag Message" · Specify the tag in the git push command::...
Read more >
How To Create Git Tags - devconnected
In order to create a Git tag for a specific commit, use the “git tag” command with the tag name and the commit...
Read more >
How to List, Create, Remove, and Show Tags in Git
You can also tag past commits using the git tag commit. In order to do this, you'll need to specify the commit's checksum...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found