iDev
iDev

Reputation: 2411

Remotely find git commit and tag info on a branch

Is it possible to determine SHA values and Git tags remotely i.e without cloning git repo?

I want to determine if there is n commits happened to the repo and then trigger a job. However, cloning each repo or maintaining one will be time consuming.

Upvotes: 1

Views: 29

Answers (1)

torek
torek

Reputation: 487755

You can get some of the information you want with git ls-remote. This has your Git call up some other Git and ask the other Git to list its branch and tag names, and the corresponding hash IDs.

Your subject line asks for:

git commit and tag info on a branch

but this phrase is ill-formed. "Tag info", in particular—whatever you mean by that phrase—is never "on a branch"; at most, a tag name coincides with a branch name, or the tagged object is reachable from one or more branch names. Since one commit can be on dozens of branches, it's not unusual for a tag name to identify a commit that is on1 multiple branches.

A branch name is a name whose fully-spelled-out form starts with refs/heads/: for instance, branch master is really refs/heads/master. A tag name is a name whose fully-spelled-out form starts with refs/tags/: for instance, tag v2.1 is really refs/tags/v2.1. The git ls-remote command has their Git tell your Git their full names—so the ones with refs/heads/ are their branch names, for instance—and their corresponding hash IDs.

Each name just holds one hash ID. Two different names can hold two different hash IDs, or the same hash ID.

Branch names are constrained: they always hold the hash ID of some existing, valid commit. Tag names often hold the hash ID of an annotated tag object rather than that of a commit. When a tag name holds the hash ID of a tag object, you'll get two output lines. Here is a snippet of output from git ls-remote:

274b9cc25322d9ee79aa8e6d4e86f0ffe5ced925        refs/heads/master
...
74d2a8cf12bf102a8cedaf66736503bb3fe88dfb        refs/tags/v2.2.0
b260d265e189728b26e50506ac6ffab6a7d588da        refs/tags/v2.2.0^{}
3fabc04268de1cec1628265810769e33dae44cd8        refs/tags/v2.2.0-rc0
4ace7ff4557350b7e0b57d024a2ea311b332e01d        refs/tags/v2.2.0-rc0^{}

This tells us that their Git's master identifies commit 274b9cc25322d9ee79aa8e6d4e86f0ffe5ced925. Their Git's v2.2.0 identifies tag object 74d2a8cf12bf102a8cedaf66736503bb3fe88dfb which in turn identifies another object, in this case b260d265e189728b26e50506ac6ffab6a7d588da.

It's not possible to tell from this alone what the type of object b260d265e189728b26e50506ac6ffab6a7d588da is, but in fact it's a commit. (To find that out, we have that Git transfer the objects to our Git and then use git cat-file -t.)

I want to determine if there is n commits happened to the repo ...

If n here stands for a number, you can't do that: counting commits requires that you have the commits.

If n here stands for new, you can't quite do that. Suppose you find that they have a branch name B that identifies commit C1 right now. Tomorrow, you query their repository and find that they have branch name B but it identifies commit C2 right now. You can tell that the branch name has moved, but you do not know for certain that it moved "forwards" to have new commits. It may have moved "backwards" to discard commits, or "sideways" so that some old commits are gone and some new commits are now reachable.

cloning each repo or maintaining one will be time consuming ...

Cloning a repository can take a while, depending on your network speed. In most cases, though, updating a clone is quite fast, especially if the clone is one made with --bare or --mirror so that there is no work-tree to update. Hence this is usually the way to go.

Some build systems do a fresh clone each time but use shallow clones to avoid bringing over most objects. This can be a successful method of dealing with otherwise large repositories.


1I use the phrase on a branch here in the sense that the commit is reachable from the branch tip, as identified by that branch name. Another way to describe this is that the commit is contained in the branch. For much more on this subject, see Think Like (a) Git.

Upvotes: 3

Related Questions