Home > database >  Pushing tags to a remote Git repository with no push-options
Pushing tags to a remote Git repository with no push-options

Time:12-27

I use Atlassian BitBucket as my remote git server. I have a local git repository that was cloned from the remote. The following commands were executed in the Terminal while the Terminal's active folder was the repository's top folder (i.e. the one containing the .git subfolder).

I started by querying the status of my local repository using the following command.

git status

The resulting output was as follows.

On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

I then created an annotated tag, thus:

git tag -a MyTag -m "This is a tag."

I queried the local repository for its list of tags, thus:

git tag

The resulting output was as follows.

MyTag

I then performed a push, thus:

git push

The resulting output was as follows.

Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 205 bytes | 205.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0), pack-reused 0
To bitbucket.org:User/RemoteRepository.git
 * [new tag]         MyTag -> MyTag

I then queried the remote for its list of tags, thus:

git ls-remote --tags origin

The resulting output was as follows. (I deleted most of the hash numbers in the following listing, for brevity's sake.)

4c...d8 refs/tags/MyTag
fa...a2 refs/tags/MyTag^{}

It should be noted that I'd never added a tag to my repository before carrying out the procedure described above.


Questions

  1. The output of the push operation seems to indicate that the tag was pushed to the remote, however, the push command contained neither the option --tags nor the option --follow-tags. Why, then, did the push operation push the tag MyTag to the remote? Did it in fact push it?

  2. After retrieving the list of tags from the remote, the list of tags contained the tag that I didn't create, namely MyTag^{}. Why? Is it always the case that the tag X^{} is automatically added to the remote whenever the tag X is pushed? Is there a way to avoid this behaviour, and push only the tags explicitly created?

CodePudding user response:

  1. The output of the push operation seems to indicate that the tag was pushed to the remote, however the push command contained neither the option --tags nor the option --follow-tags. Why, then, did the push operation push the tag MyTag to the remote? Did it in fact push it?

It did, and the reason is pretty simple: --follow-tags defaults to true, if you don't configure it otherwise. If you have configured it to default to false, an explicit --follow-tags on the command line overrides; if not—if you've either configured it to true or let it default to true—an explcit --no-follow-tags on the command line overrides.

  1. ... retrieving the list of tags from the remote [showed] MyTag^{} ...

This is normal: MyTag^{} is not itself a tag, but is an artifact of the fact that MyTag is an annotated tag, which is an object in its own right.

To make the git fetch's own --follow-tags (which is again the default) work, Git needs to know which tags, if any, point directly at any particular object (usually, any particular commit) that's being brought over. Git "knows" objects by their hash IDs. Under --follow-tags, your own (receiving) git fetch operation should create refs/tags/T if your git fetch brings over the object to which the sender's refs/tags/T points. But how will your Git software know which object that is?

To answer that question, the sending Git software is obligated to send over not only the tag name and corresponding hash ID, but also the target of this tag if this tag is an annotated tag. (If not, the tag name points directly to the object, rather than to the annotated tag that points to the object, so there's no extra step required.) As Git already has a syntax that means "if a reference is an annotated tag, follow a tag to its target", the transport protocols (for fetch and push) simply borrow this existing syntax.

That syntax is to add ^{} to the reference, so that's what you see here.

  • Related