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

Previous thread: Re: Git manuals by Jakub Narebski on Sunday, November 19, 2006 - 11:16 am. (2 messages)

Next thread: Re: can I remove or move a tag in a remote repository? by Jakub Narebski on Sunday, November 19, 2006 - 11:54 am. (1 message)
From: Jim Meyering
Date: Sunday, November 19, 2006 - 11:42 am

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,

Jim
-

From: Andreas Ericsson
Date: Tuesday, November 28, 2006 - 4:08 am

Possibly not, although it's nice to let others that use git to know 


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;;

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
Tel: +46 8-230225                  Fax: +46 8-230231
-

From: Junio C Hamano
Date: Tuesday, November 28, 2006 - 2:46 pm

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;
 

-

From: Johannes Schindelin
Date: Wednesday, November 29, 2006 - 2:54 am

Hi,


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

-

From: Jim Meyering
Date: Wednesday, November 29, 2006 - 3:55 am

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*
immutable, with the default being it is immutable.
-

From: Johannes Schindelin
Date: Wednesday, November 29, 2006 - 4:45 am

Hi,



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 


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

-

From: Andy Whitcroft
Date: Wednesday, November 29, 2006 - 4:47 am

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

-apw
-

Previous thread: Re: Git manuals by Jakub Narebski on Sunday, November 19, 2006 - 11:16 am. (2 messages)

Next thread: Re: can I remove or move a tag in a remote repository? by Jakub Narebski on Sunday, November 19, 2006 - 11:54 am. (1 message)