Ilya Gazman
Ilya Gazman

Reputation: 32221

Will tag referencing commits unreachable from any branch be lost?

I worked on my project, on branch branch. Then I reverted using

git revert tag-name

Then I did some progress and committed. When I try to push I get this error:

Updates were rejected because the remote contains work that you do not have locally

I do not want to lose my progress before the revert, but want to remove from branch the commits made after, keeping them available for future reference just under the 1.00.00rcXX tag.

I created a clone of the repository, tagged head of branch there, and rewound branch to the revert commit:

git tag -a 1.00.00rcXX -m message
git reset --hard HEAD~1 # remove last commit from current branch

Now I want to force push my changes back to my original repository, so all the commit ahead of branch will be lost.

Will my tag be lost too, as it is based on commits unreachable from branch?

Upvotes: 2

Views: 853

Answers (1)

Palec
Palec

Reputation: 13551

Unreachability and garbage collection

Only really unreachable commits can be garbage-collected, and thus lost forever.

Quoting man gitglossary:

unreachable object

An object which is not reachable from a branch, tag, or any other reference.

As long as the tag exists, the part of history it links to is considered reachable and thus not garbage-collected. The tag keeps those commits “alive”.

Pushing the tag and force-pushing the branch is safe

Git tries to prevent you from making non-fast-forward changes in any branch. You have to pass the -f option to git push to perform push after resetting (rewinding) the branch. If you keep in mind the implications of overwriting history, you can push both the tag referencing original state of the branch and the new head of the branch and you will lose nothing.

Just run this:

git push --tags
git push -f origin your-rewound-branch

Better use branch instead of a tag

By the way, using tag for such a thing is probably not a good idea. Probably you will want to delete that dead-end part of development history someday, which you should not do with tags. Using a branch (head) instead of a tag is more suitable for such a purpose. Just use (maybe with a more descriptive name)

git branch 1.00.00rcXX

instead of

git tag -a 1.00.00rcXX -m message

Upvotes: 3

Related Questions