Tim Hockin
Tim Hockin

Reputation: 3662

detecting a changed tag on a remote

I have a git repo which I am watching or changes. One of the things I want to know is whether a tag has changed upstream. Specifically, I think the tag resolves to abc123 (git rev-list -n1 tagname) but the upstream has deleted the tag and recreated it at def456.

Even after I git remote update, my local rev-list shows me abc123.

I found git ls-remote origin tagname, but that shows me a hash that is not abc123 nor def456.

To make matters a little more complicated, I don't actually know whether the user has given me a rev like "HEAD" or a rev like "tagname" or a rev like "abc123def456". rev-list is great in that it takes all of these, but not wrt a remote.

Is there a way to say "what hash would XYZ resolve to in this specific remote" without knowing what XYZ means?

Upvotes: 1

Views: 156

Answers (2)

torek
torek

Reputation: 489083

You have essentially just two options, assuming only standard Git tools (if you have non-Git tools, especially ones you can program, you can of course do whatever you like). These two options are:

  1. Use git fetch as already described in ElpieKay's answer.
  2. Sticking with git ls-remote, note that git ls-remote resolves tags1 for you:

    $ git ls-remote origin
    [snip]
    aaa74e8c5b085572ee6bf3381167c1d428c8d685    refs/heads/pu
    8bb94d66bf85d73f8866611161fb6022d68fdf13    refs/heads/todo
    d5aef6e4d58cfe1549adef5b436f3ace984e8c86    refs/tags/gitgui-0.10.0
    3d654be48f65545c4d3e35f5d3bbed5489820930    refs/tags/gitgui-0.10.0^{}
    33682a5e98adfd8ba4ce0e21363c443bd273eb77    refs/tags/gitgui-0.10.1
    729ffa50f75a025935623bfc58d0932c65f7de2f    refs/tags/gitgui-0.10.1^{}
    [snip]
    

If you save all of this output, you can scan through it for branch and tag names.

Branch names are simply references of the form refs/heads/*: in this case the remote Git has branches pu and todo, for instance. Since branch names always point to commit IDs, the hashes to the left of these names are commit hashes.

Tag names are simply references of the form refs/tags/*: in this case, the tag list begins with numerous gitgui-* tags. Each of these is an annotated tag, so git ls-remote shows not only the tag object ID such as d5aef6e4d58cfe1549adef5b436f3ace984e8c86, but also that tag object's target, 3d654be48f65545c4d3e35f5d3bbed5489820930. This is the second line of output, showing refs/tags/gitgui-0.10.0^{}, which is gitrevisions syntax:

A suffix ^ followed by an empty brace pair means the object could be a tag, and dereference the tag recursively until a non-tag object is found.

Note that if you do wish to "re-fetch" tags via git fetch, you can tell your Git to force-update your tags, or force-update the other Git's tags into a private namespace of your own ("remote tags", if you will: see Git - Checkout a remote tag when two remotes have the same tag name). To make Git force-update your current tags, add +refs/tags/*:refs/tags/* to your fetch refspecs (either on the command line, or in a fetch = configuration entry). Overwriting your current tags does, of course, have the obvious drawback that you no longer have the old tags.

Upvotes: 0

ElpieKay
ElpieKay

Reputation: 30888

As we know, there are two kinds of tags, annotated tag(created via -a, -s or -u) and lightweight tag. The annotated tag, like a commit, a blob or a tree, is an git object that has its own hash sha1. The lightweight tag is simply a name for an object. A tag usually points to a commit object, but it can also point to a tag object, a blob object or a tree object.

Supposing tagA is an annotated tag pointing to current tip of master and tagB is a lightweight tag pointing to the same commit, git rev-list -n1 <tagA> or git rev-list -n1 <tagB> can show the sha1 of that commit. git ls-remote origin <tagA> shows tagA's own sha1 instead of that commit's, but git ls-remote origin <tagB> shows the sha1 of that commit.

If you want to find out what the tag points to, you could run git fetch origin <tagname> first, which passes it to FETCH_HEAD. git rev-list -n1 FETCH_HEAD can list the commit sha1 it points to in the remote, if it does point to a commit.

Upvotes: 2

Related Questions