What happen to Git tags pointing to a removed commit
GitGit BranchGit TagGit Problem Overview
Say I do the following:
- Create branch
X
- Create Tag
t
(to branchX
) - Push
- Remove branch
X
What happen to tag t
? is it just floating there? is it considered as garbage?
Should I remove all tags pointing at branch before removing the branch itself?
Reference
From Git Basics - Tagging:
> Git uses two main types of tags: lightweight and annotated. A > lightweight tag is very much like a branch that doesn’t change – it’s > just a pointer to a specific commit.
Git Solutions
Solution 1 - Git
> What happen to tag t?
Let's say you created branch x
from a commit E
and then tagged that commit with tag t
. E.g.
x (branch)
|
V
A-----B------C------D------E
^
|
t (tag)
If you remove branch x
nothing happens to tag t
.
git branch -D x
The tag still points to commit E
.
A-----B------C------D------E
^
|
t (tag)
> is it considered as garbage?
No, because the commit is still referenced by tag t
.
> What if the commit is removed?
You do not remove commits. You remove pointers to commits and if commits are no longer referenced git will garbage collect them some day (depending on your configuration).
See git gc
Even if you removed all ordinary refs, like branches and tags, the commits will still be referenced in the reflog for some time and you can access them, e.g. re-create a branch, tag them or cherry-pick and so on.
You can see the reflog using git reflog
. Also take a look at gc.reflogExpireUnreachable
and gc.reflogExpire
EDIT
If somehow git's object database is corrupted. Either a file from .git/objects
was deleted (e.g. you accidentially deleted it using your file explorer or a command-line command) or a ref points to a non-existent git object (like a commit, tree or blob object), you will get errors if git tries to access these objects.
Here is a list of errors that might occur when git tries to access an object that does not exist or if a non-existent object is referenced.
-
commit
fatal: Could not parse object '<ref-name>'.
example:
fatal: Could not parse object 'master'.
-
tree
fatal: unable to read tree <tree-sha1>
example:
fatal: unable to read tree 13a3e0908e4f6fc7526056377673a5987e753fc8
-
blob
error: unable to read sha1 file of <blob-name> (<blob-sha1>)
example:
error: unable to read sha1 file of test.txt (e69de29bb2d1d6434b8b29ae775ad8c2e48c5391)
Take a look at Git Internals for a deeper understanding.
Solution 2 - Git
I'm not addressing the specific scenario in the OP's question, but rather the question in the title: What happens to a git tag pointing to a removed commit?
If somehow you did manage to remove a commit that was referenced by a tag (not sure how you could do that - see René Link's answer), the tag would just be a pointer to an invalid commit (you can test this by manually editing a tag from .git/refs/tags).
In such case, output of git tag
would be something like this:
$ git tag
error: refs/tags/v1.0 does not point to a valid object!
v1.1
...etc
Checkout would also produce error:
$ git checkout v1.0
fatal: reference is not a tree: v1.0
So the answer to a question "What happens to a git tag that references a removed commit?" is... nothing. It will remain there, pointing to an invalid reference, until you remove it with git tag -d <tag>
.
Solution 3 - Git
If you delete a branch that a tag was created from, this will have no effect on the tag. A tag does not hold a reference of where it was created from.
If you want to know more about tags vs. branches I would recommend looking at this question: https://stackoverflow.com/questions/1457103/how-is-a-tag-different-from-a-branch-which-should-i-use-here