0

Using git push origin <tag_name> can push tag to remote server, as shown in This Question. However, if local branch containing this tag is ahead of the remote server, this push action will create an anonymous branch containing this tag.

When another developer tries to fetch it, nothing happens. (An anonymous branch won't be fetched!?)

Thus, the questions is: How can I push the branch (better to the point of the tag only) as well, when I want push the tag?

Since I am not yet certain to push all the history of the branch (but am certain to push to the point of the tag, since I want to push the tag), it's more convenient to push the branch only to the point of the tag.

Any solutions?

Community
  • 1
  • 1
Robin Hsu
  • 4,164
  • 3
  • 20
  • 37
  • 1
    It sounds like you want to [create a branch](http://stackoverflow.com/a/10940996/391161) at the current tag (with the same name as the tag, perhaps) and push that branch? – merlin2011 Feb 22 '17 at 07:36
  • It doesn't make sense to push a branch containing a tag because multiple branches may contain the commit referred to by the tag in their history. – merlin2011 Feb 22 '17 at 07:37
  • Well, it should be fine. As long as one branch containing the tag had already been pushed, anonymous branch wont' be created. The question would be refined to: When no branch containing the tag, we want at least one branch (normally the current branch) containing this tag to be pushed as well. Or better: If such case is found, and the current branch does not contain this tag, reports an error. – Robin Hsu Feb 22 '17 at 08:45

2 Answers2

0

By default, git fetch (or git pull) does not fetch tags.

If you want to fetch the remote tags : git fetch --tags

LeGEC
  • 46,477
  • 5
  • 57
  • 104
0

When another developer tries to fetch it, nothing happens. (An anonymous branch won't be fetched!?)

Anonymous branches are problematic. Parts of Git believe they are branches, and parts do not. If they do exist, then every commit is its own anonymous branch.1 It's probably better, for most purposes, to just think of selecting a commit with or without also selecting some or all of its ancestors. Selecting commit bacacab without ancestry gets you the one commit, and selecting it with ancestry makes it act like an anonymous branch.

In any case, what git fetch always copies unchanged—because it must—is composed of the commit objects themselves and the things those refer to: any trees or blobs required, and any earlier commits required.2 For annotated tag objects, Git copies the tag object itself unchanged, and adds the tag's target-object to the set of objects required (to be copied if not already present). How it finds those object IDs is by the names—any reference names, not just branch or tag names—presented by the other Git, the one your Git is fetching from. So this means that there must be a name. But that's a name in the other Git, in the other repository; the name, if any, to use in your repository is something under your control.

As it turns out, there is a bug of sorts where, if Git is fetching just a tag name, and is not instructed to copy the tag name explicitly, it fails to write anything at all (except for the FETCH_HEAD file) in some cases. See my answer to Why is git fetch not fetching any tags? In short, though, if you git fetch --tags, you will get their—the other Git's—tag name copied to a tag of the same name in your own repository, and you can then use that tag name to look up the commit (and its ancestors).


1For that matter, a single commit could be the tip commit of an infinite number of anonymous branches. Who is to say if the lack of a name is the same name as a second lack of a name? Clearly the anonymous branch ending at commit dadf00d is different from the anonymous branch ending at bl00de1f, so no-name definitely doesn't match no-name. So why does, or doesn't, no-name for ac0ffee match no-name for ac0ffee? (This is a rhetorical / philosophical question, meant to make one think about the nature of commits and branch names in Git, rather than to get a concrete answer—though I do have my own concrete answer. :-) )

2This does get modified for shallow clones. Here, commits are copied up to some "depth" value, and then Git inserts a shallow graft, artificially pretending that the commit has no parents (by writing the commit ID to .git/shallow). But the commit is actually copied intact; it's just the graph-walk that gets truncated.

Community
  • 1
  • 1
torek
  • 448,244
  • 59
  • 642
  • 775