threads / discuss / 43514

Re: can I remove or move a tag in a remote repository?

Subject: Re: can I remove or move a tag in a remote repository?

## tl;dr

9 messages between Nov 19, 2006 and Nov 29, 2006.

replies: 8people: 6as markdown or json

Jim Meyering· Nov 19, 2006, 18:42 UTC · lore

can I remove or move a tag in a remote repository?

Hello,

Periodically, I sync the coreutils git repository to an otherwise read-only CVS repo, and use a cheap git tag named "cvs-head" to keep track of the point to which the latest sync operation has run. Then, after every sync-git-to-cvs operation, I run this:

  git-tag -f -m "most recent version that has been sync'd to cvs" cvs-head $sha1
Also periodically, I push my git working dir/repo to a public place,
  http://git.sv.gnu.org/gitweb/?p=coreutils.git;a=summary

----------------- Just today, I have finally pushed tags to that public repo, including the "cvs-head" one (before there were no tags in the remote repo). But now, I've just done a local sync-to-cvs operation, which has resulted in moving that tag to point to a different point in the git repo.

Here's the problem: When I try to push the new tags, git-push fails:

  $ git-push -f --tags ssh+git://git.sv.gnu.org/srv/git/coreutils master:refs/heads/master
  updating 'refs/tags/cvs-head'
    from 2fd3fd29a8b40be695bc2327c8cd3bd33e521100
    to   db18f53ffb221e9957124d8af81c11a7e350ac3b
  ...
  Total 1, written 1 (delta 0), reused 0 (delta 0)
  Unpacking 1 objects
  error: denying non-fast forward; you should pull first
I get the same error also when using --force.
Perhaps I shouldn't push the cvs-head tag at all.
A few questions:
  - is there a way to say "push all tags matching /COREUTILS-*/"
      or to say "push all tags, except the ones on this list"?
  - is there a way to remove the cvs-head tag from the remote directory?
      Note: I don't have shell access there.  I can request that someone
      with shell access do it, but shouldn't have to resort to that.
  - is there some way to make "git push" do what I want, and update the
      offending tag in the remote repo?
Thanks for listening,
Jakub Narebski· Nov 19, 2006, 18:54 UTC · re: Jim Meyering · lore
Jim Meyering wrote:
Show 12 quoted lines
> When I try to push the new tags, git-push fails:
> 
>   $ git-push -f --tags ssh+git://git.sv.gnu.org/srv/git/coreutils master:refs/heads/master
>   updating 'refs/tags/cvs-head'
>     from 2fd3fd29a8b40be695bc2327c8cd3bd33e521100
>     to   db18f53ffb221e9957124d8af81c11a7e350ac3b
>   ...
>   Total 1, written 1 (delta 0), reused 0 (delta 0)
>   Unpacking 1 objects
>   error: denying non-fast forward; you should pull first
> 
> I get the same error also when using --force.

Possibly remote side has receive.denyNonFastForwards set (it should not I think if it is public published bare repository). But even then there should be no fast-forward check on tags...

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Andreas Ericsson· Nov 28, 2006, 11:08 UTC · re: Jim Meyering · lore
Jim Meyering wrote:
> 
> Perhaps I shouldn't push the cvs-head tag at all.

Possibly not, although it's nice to let others that use git to know where you've cut the release.

> A few questions:
>   - is there a way to say "push all tags matching /COREUTILS-*/"
>       or to say "push all tags, except the ones on this list"?

Here's a snippet from the default update hook we use on all our repos. We explicitly deny any non-annotated tags from being pushed to the central server and let rogue devs know why the push failed by writing the error message to stderr so that it gets sent over the wire. I believe this is still the default update-hook shipped with git. ---%<---%<----%<--- ref_type=$(git cat-file -t "$3")

# Only allow annotated tags in a shared repo
# Remove this code to treat dumb tags the same as everything else
case "$1","$ref_type" in
refs/tags/*,commit)
     echo "*** Un-annotated tags are not allowed in this repo" >&2
     echo "*** Use 'git tag [ -a | -s ]' for tags you want to 
propagate." >&2
     exit 1;;
---%<---%<---%<---
Show 6 quoted lines
>   - is there a way to remove the cvs-head tag from the remote directory?
>       Note: I don't have shell access there.  I can request that someone
>       with shell access do it, but shouldn't have to resort to that.
>   - is there some way to make "git push" do what I want, and update the
>       offending tag in the remote repo?
> 

I'm not sure if execution reaches the update hook when you're uploading a tag that already exists. If it is, you could simply remove the offending tag in the update-hook and exit 0 to make it work properly. You can test this without shell-access on the remote system by setting up a repo on your local machine, making some dummy commit, cloning it and then hacking away on the hook while pushing to it from your local repo.

Other than that, push your tags manually by naming them explicitly on the push-line, like so: $ git push $remote_repo $tag_name

This is what I do whenever we cut a release. With a one tag per release, it's not very troublesome at all, and the update-hook sends a nicely formatted message of the changes since the last release (last tag really, but it amounts to the same thing for us) to everyone involved.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Junio C Hamano· Nov 28, 2006, 21:46 UTC · re: Jim Meyering · lore
Jim Meyering <jim@meyering.net> writes:
Show 13 quoted lines
> Here's the problem:
> When I try to push the new tags, git-push fails:
>
>   $ git-push -f --tags ssh+git://git.sv.gnu.org/srv/git/coreutils master:refs/heads/master
>   updating 'refs/tags/cvs-head'
>     from 2fd3fd29a8b40be695bc2327c8cd3bd33e521100
>     to   db18f53ffb221e9957124d8af81c11a7e350ac3b
>   ...
>   Total 1, written 1 (delta 0), reused 0 (delta 0)
>   Unpacking 1 objects
>   error: denying non-fast forward; you should pull first
>
> I get the same error also when using --force.

I think this is due to overeager receive.denyNonFastForwards configuration setting at the repository you are pushing into.

I _think_ what receive-pack does in this case is totally wrong. It should either:

 (1) deny overwriting existing tags -- tags are meant to be
     immutable so it should not allow them to be "updated"
     regardless of fast-forwardness, or
 (2) allow overwriting things under refs/tags/ without any
     fast-forward checking.  After all, a tag could point at a
     tree or a blob, and there is no fast-forwardness among
     trees.

The client side check in "git fetch" takes the latter viewpoint, and I think we should be consistent with it.

Johannes, what do you think? Does the following patch look sane to you?

---
diff --git a/receive-pack.c b/receive-pack.c
index 1a141dc..6c3de47 100644
--- a/receive-pack.c
+++ b/receive-pack.c
@@ -120,7 +120,7 @@ static int update(struct command *cmd)
 			     "but I can't find it!", new_hex);
 	}
 	if (deny_non_fast_forwards && !is_null_sha1(new_sha1) &&
-	    !is_null_sha1(old_sha1)) {
+	    !is_null_sha1(old_sha1) && !strncmp(name, "refs/heads/", 11)) {
 		struct commit *old_commit, *new_commit;
 		struct commit_list *bases, *ent;
 
Johannes Schindelin· Nov 29, 2006, 09:54 UTC · re: Junio C Hamano · lore
Hi,
On Tue, 28 Nov 2006, Junio C Hamano wrote:
Show 36 quoted lines
> Jim Meyering <jim@meyering.net> writes:
> 
> > Here's the problem:
> > When I try to push the new tags, git-push fails:
> >
> >   $ git-push -f --tags ssh+git://git.sv.gnu.org/srv/git/coreutils master:refs/heads/master
> >   updating 'refs/tags/cvs-head'
> >     from 2fd3fd29a8b40be695bc2327c8cd3bd33e521100
> >     to   db18f53ffb221e9957124d8af81c11a7e350ac3b
> >   ...
> >   Total 1, written 1 (delta 0), reused 0 (delta 0)
> >   Unpacking 1 objects
> >   error: denying non-fast forward; you should pull first
> >
> > I get the same error also when using --force.
> 
> I think this is due to overeager receive.denyNonFastForwards
> configuration setting at the repository you are pushing into.
> 
> I _think_ what receive-pack does in this case is totally wrong.
> It should either:
> 
>  (1) deny overwriting existing tags -- tags are meant to be
>      immutable so it should not allow them to be "updated"
>      regardless of fast-forwardness, or
> 
>  (2) allow overwriting things under refs/tags/ without any
>      fast-forward checking.  After all, a tag could point at a
>      tree or a blob, and there is no fast-forwardness among
>      trees.
> 
> The client side check in "git fetch" takes the latter viewpoint,
> and I think we should be consistent with it.
> 
> Johannes, what do you think?  Does the following patch look sane
> to you?
It does if you agree that (2) is correct.

But I don't agree. cvs-head really should be a head IMHO, not a tag, because cvs-head really tracks a branch.

I also think that git-fetch silently updating tags is wrong. Rather, it should warn that the tags are different. But I've been wrong before.

Ciao, Dscho

Jim Meyering· Nov 29, 2006, 10:55 UTC · re: Johannes Schindelin · lore
Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> On Tue, 28 Nov 2006, Junio C Hamano wrote:
...
>> I think this is due to overeager receive.denyNonFastForwards
>> configuration setting at the repository you are pushing into.
Junio, thank you for following up on this!
Show 14 quoted lines
>> I _think_ what receive-pack does in this case is totally wrong.
>> It should either:
>>
>>  (1) deny overwriting existing tags -- tags are meant to be
>>      immutable so it should not allow them to be "updated"
>>      regardless of fast-forwardness, or
>>
>>  (2) allow overwriting things under refs/tags/ without any
>>      fast-forward checking.  After all, a tag could point at a
>>      tree or a blob, and there is no fast-forwardness among
>>      trees.
>>
>> The client side check in "git fetch" takes the latter viewpoint,
>> and I think we should be consistent with it.
Show 10 quoted lines
>> Johannes, what do you think?  Does the following patch look sane
>> to you?
>
> It does if you agree that (2) is correct.
>
> But I don't agree. cvs-head really should be a head IMHO, not a tag,
> because cvs-head really tracks a branch.
>
> I also think that git-fetch silently updating tags is wrong. Rather, it
> should warn that the tags are different. But I've been wrong before.

AFAIK, no one wants git-fetch to update tags _silently_. I expected it give a diagnostic and fail by default -- and it already does that. Pushing moved tags is serious business. I was hoping to be able to use --force to override that fail-safe.

My goal is to maintain a symbolic reference "cvs-head" that points to the newest git trunk node that's been mirrored to a CVS repository. Without even considering any other option, I chose to use a lightweight tag for that purpose, since I have a conceptual view that it's a label I can move from one referent to another. It strikes me as counter-intuitive to use a temporary git "branch" that way. Would that even work, removing it and recreating it all the time? Hmm.. or maybe you mean to create the branch once and then to merge from the trunk repeatedly. That seems like unnecessary work, when all I want is a movable label.

I admit that I like the idea of release tags being immutable, but even there, it's happened that I've made-but-not-published a release, then realized that it wasn't quite complete. I was glad to be able to go back and re-tag after making corrections.

I wouldn't mind having a way to specify that a pushed tag is *not*
Johannes Schindelin· Nov 29, 2006, 11:45 UTC · re: Jim Meyering · lore
Hi,
On Wed, 29 Nov 2006, Jim Meyering wrote:
Show 7 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>
> > I also think that git-fetch silently updating tags is wrong. Rather, it
> > should warn that the tags are different. But I've been wrong before.
> 
> AFAIK, no one wants git-fetch to update tags _silently_. I expected it 
> give a diagnostic and fail by default -- and it already does that.
Umm. I just tested it, and it said "updating tag" without failing.
> Pushing moved tags is serious business.  I was hoping to be able to use 
> --force to override that fail-safe.

Hmmm. Probably Junio's patch is correct after all, since tags are special creatures: you do not expect them to change, but if, they can change arbitrarily (as opposed to branches, which should evolve linearly).

> My goal is to maintain a symbolic reference "cvs-head" that points
> to the newest git trunk node that's been mirrored to a CVS repository.
But is that not just tracking another branch?
Show 5 quoted lines
> Without even considering any other option, I chose to use a lightweight
> tag for that purpose, since I have a conceptual view that it's a label I
> can move from one referent to another.  It strikes me as counter-intuitive
> to use a temporary git "branch" that way.  Would that even work, removing
> it and recreating it all the time?

Yes, it would. Remember: a branch in git is just a named ref. It literally used to be a 41-byte file pointing to the tip of the branch in the ancestor graph. And you can update it with git-update-ref.

So, a branch in git is very much the movable label you are looking for.

Ciao, Dscho

Jakub Narebski· Nov 29, 2006, 13:46 UTC · re: Johannes Schindelin · lore
Johannes Schindelin wrote:
Show 11 quoted lines
>> Without even considering any other option, I chose to use a lightweight
>> tag for that purpose, since I have a conceptual view that it's a label I
>> can move from one referent to another.  It strikes me as counter-intuitive
>> to use a temporary git "branch" that way.  Would that even work, removing
>> it and recreating it all the time?
> 
> Yes, it would. Remember: a branch in git is just a named ref. It 
> literally used to be a 41-byte file pointing to the tip of the branch in 
> the ancestor graph. And you can update it with git-update-ref.
> 
> So, a branch in git is very much the movable label you are looking for.

And even if cvs-head does not fast-forward, remember that pu branch also doesn't fast-forward (usually).

-- 
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
Andy Whitcroft· Nov 29, 2006, 11:47 UTC · re: Jim Meyering · lore
Jim Meyering wrote:
Show 47 quoted lines
> Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
>> On Tue, 28 Nov 2006, Junio C Hamano wrote:
> ...
>>> I think this is due to overeager receive.denyNonFastForwards
>>> configuration setting at the repository you are pushing into.
> 
> Junio, thank you for following up on this!
> 
>>> I _think_ what receive-pack does in this case is totally wrong.
>>> It should either:
>>>
>>>  (1) deny overwriting existing tags -- tags are meant to be
>>>      immutable so it should not allow them to be "updated"
>>>      regardless of fast-forwardness, or
>>>
>>>  (2) allow overwriting things under refs/tags/ without any
>>>      fast-forward checking.  After all, a tag could point at a
>>>      tree or a blob, and there is no fast-forwardness among
>>>      trees.
>>>
>>> The client side check in "git fetch" takes the latter viewpoint,
>>> and I think we should be consistent with it.
> 
>>> Johannes, what do you think?  Does the following patch look sane
>>> to you?
>> It does if you agree that (2) is correct.
>>
>> But I don't agree. cvs-head really should be a head IMHO, not a tag,
>> because cvs-head really tracks a branch.
>>
>> I also think that git-fetch silently updating tags is wrong. Rather, it
>> should warn that the tags are different. But I've been wrong before.
> 
> AFAIK, no one wants git-fetch to update tags _silently_.
> I expected it give a diagnostic and fail by default -- and it already
> does that.  Pushing moved tags is serious business.  I was hoping to be
> able to use --force to override that fail-safe.
> 
> My goal is to maintain a symbolic reference "cvs-head" that points
> to the newest git trunk node that's been mirrored to a CVS repository.
> Without even considering any other option, I chose to use a lightweight
> tag for that purpose, since I have a conceptual view that it's a label I
> can move from one referent to another.  It strikes me as counter-intuitive
> to use a temporary git "branch" that way.  Would that even work, removing
> it and recreating it all the time?  Hmm.. or maybe you mean to create the
> branch once and then to merge from the trunk repeatedly.  That seems
> like unnecessary work, when all I want is a movable label.

Well remember that all heads are simply references into the DAG, they are all labels. 'heads' you are allowed to move and change, commit to etc, but they are still just name -> sha1 mechanisms.

If the merge is a ff then there is no work. You could always use 'reset' instead to move the branch to the right place in the DAG.

Show 8 quoted lines
> 
> I admit that I like the idea of release tags being immutable, but even
> there, it's happened that I've made-but-not-published a release, then
> realized that it wasn't quite complete.  I was glad to be able to go
> back and re-tag after making corrections.
> 
> I wouldn't mind having a way to specify that a pushed tag is *not*
> immutable, with the default being it is immutable.

← back to recent threads