You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@subversion.apache.org by Rob Hubbard <ro...@softel.co.uk> on 2008/09/26 17:07:19 UTC

Accidental double tag copy

Dear SVN Users,

I have a suggestion / feature request for SVN.


First: the problem
==================

In the past, I've encountered a problem with tag creation. If the SVN 
copy command is accidentally issued twice, something rather nasty 
happens.

Suppose you have a project called "tag_copy_twice" with a few files in a

version-controlled trunk (in some repository svn://repos/) as follows:

    ./tag_copy_twice/trunk/dir/dir_file.txt
    ./tag_copy_twice/trunk/file.txt

You create a tag for version 1.0 as follows, e.g.

    $ svn copy -m"tag v1.0" "svn://repos/tag_copy_twice/trunk" \
        "svn://repos/tag_copy_twice/tag/v1.0"

All is still well and good. You now also have these files:

    ./tag_copy_twice/tag/v1.0/dir/dir_file.txt
    ./tag_copy_twice/tag/v1.0/file.txt

Accidentally issuing the tagging command a second time, you end up with 
this:

    ./tag_copy_twice/tag/v1.0/dir/dir_file.txt
    ./tag_copy_twice/tag/v1.0/file.txt
    ./tag_copy_twice/tag/v1.0/trunk/dir/dir_file.txt
    ./tag_copy_twice/tag/v1.0/trunk/file.txt

This is perfectly reasonable. It's what you asked for. The behaviour 
matches what a shell copy (or cp) command would do. It's certainly not 
an SVN bug.

(I think this is a special case that TortoiseSVN warns about: changes to

areas with "tag" in the URL. I don't think that's the right approach for

SVN: paths should not have special meanings.)

The problem stems from the fact that the copy command means something 
slightly different depending upon whether the target already exists.
An alternative possible cause of this problem is if two engineers create

the same tag at almost the same time.

Fortunately, if you accidentally issuing the tagging command a third 
time, SVN issues an error:

    svn: Path 'tag/v1.0/trunk' already exists

so it doesn't get worse still.


Second: comparison with Bash cp
===============================

Now consider the following Bash shell script (this is nothing to do with

SVN):

    #!/bin/bash

    #rm -Rf to ### dangerous!
    mkdir to

    ### ordinary copy
    cp -R "from" "to/norm"
    ### whoops, did it again!
    cp -R "from" "to/norm"

    ### copy using -t or --target-directory==DIR
    cp -R "from" -t "to/targ1"

    mkdir "to/targ2"
    cp -R "from" -t "to/targ2"
    ### whoops, did it again!
    cp -R "from" -t "to/targ2"

    ### copy using -T or --no-target-directory
    cp -R "from" "to/no_targ" -T
    ### whoops, did it again!
    cp -R "from" "to/no_targ" -T

    find "to" -iname "*.txt"

This outputs something like this (I've rearranged and spaced out the 
output slightly for clarity):

    $ ./copy_test.sh

    to/norm/dir/dir_file.txt
    to/norm/file.txt
    to/norm/from/dir/dir_file.txt
    to/norm/from/file.txt

    cp: accessing `to/targ1': No such file or directory

    to/targ2/from/dir/dir_file.txt
    to/targ2/from/file.txt

    to/no_targ/dir/dir_file.txt
    to/no_targ/file.txt

So:
    * the 'ordinary' cp exhibits the same sort of behaviour as SVN copy
    * 'cp -t' won't perform the copy unless the target directory already

      exists
    * 'cp -T' doesn't create 'from' in the target


Third: suggested solution
=========================

It would be great if SVN copy had these

    --target-directory DIR
    --no-target-directory

switches.

The above switches would help, as they would make the required behaviour

explicit. However, this wouldn't solve the whole problem, as the copy 
operations would still be able to overwrite and/or mix the source 
directories in the target.

Thus perhaps further switch

    --require-empty-target

might be useful for URL to URL copies. The meaning of this would be to 
prevent the copy in its entirety if the target already exists.
The main problem with this approach is that it relies on the issuer of 
the copy command to actively decide to use the switch.

Perhaps a new (versioned) property on directories

    svn:final (or svn:sealed or svn:read-only)

in conjunction with a copy switch

    --mark-final (or --seal or --mark-read-only)

could be implemented. (As usual, I suppose --force should overcome the 
block.) I realise that SVN has a locking mechanism, but I don't think 
that's quite the right thing for this.


I dare say that these suggestions are not ideal, but there is something 
to be solved here. Perhaps someone else might come up with a more 
elegant solution.


Many thanks,
Rob Hubbard.

_______________________________________________
This email has been scanned for Softel by Star.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org


Labels [was: RE: Accidental double tag copy]

Posted by Rob Hubbard <ro...@softel.co.uk>.

> -----Original Message-----
> From: David Weintraub [mailto:qazwart@gmail.com] 

> Basically, a label would simply be an alias to a revision. For
> example:
> 
>     $ svn mklabel REL-1.0 12345
> 
> This would make the label REL-1.0 synonymous with revision 
> 12345. This means you could now do things like this:
> 
>     $ svn diff -rREL-1.0:HEAD
> 
> or
> 
>     $ svn update -rREL-1.0
> 
> I know there are some limitations with this:

> * A label would be across an entire repository. If I have 
> multiple projects, I can have a separate tag directory for 
> each project.
> Creating a label for project "A" would also create a 
> meaningless label for project "B".

Why?

A label *could* be mapped to a pinned URL.

If they're implemented as properties, then should they be
versioned or not?

E.g., would you want labels like "experimental", "stable"?

Should they be stored effectively at the repository root,
(where they're easier to find, but where there will be more
"clutter") or with the directory being labelled?

> I know that Subversion works fine without "labels", and you 
> can provide shell scripts to emulate this stuff, but it would 
> be nice to have something like this built into Subversion. 
> And, developers would find Subversion a bit easier to use and 
> comprehend.

I think there are already all the tools required to "emulate"
labelling (as David has already noted). SVN has tags, versioned
properties and unversioned properties.

With labels, its certainly nice to have meaningful names, such
as "version 1.0.1", but then that can be captured by the name
of the target of the copy. 

----

However, I *do* think that SVN could be vastly improved with
better "support" of tags. Sometimes it would be useful to do an

    svn log

with interleaved tag information: that is, show the history along with
the revisions forming the *sources* of copy commands.

This could perhaps be done by having a (versioned)
    svn:copy-area
property containing a (list of) tag and/or branch areas of interest
associated with a directory

Then a command such as

    svn log --show-copies

could first search up through the tree for an svn:copy-area property,
(probably stopping at the first one found)
perform a log of those areas, noting any copy operations, and display
interleaved log information something like this:

Suppose the "svn:copy-area" for /project/trunk has value

    /project/branches
    /project/tags

then a log "with copies"

    $ svn log --show-copies -r100:200

might result in

 
------------------------------------------------------------------------
  r100 | user | YYYY-MM-DD HH:MM:SS +0000 (Day, DD Mon YYYY) | N lines

  Comment
 
========================================================================
  "v1.0.1"
     A /project/tags/v1.0.1 (from /project/trunk:112)
 
========================================================================
  r125 | user | YYYY-MM-DD HH:MM:SS +0000 (Day, DD Mon YYYY) | N lines

  Comment
 
------------------------------------------------------------------------
  r150 | user | YYYY-MM-DD HH:MM:SS +0000 (Day, DD Mon YYYY) | N lines

  Comment
 
========================================================================
  "feature-x"
     A /project/branches/feature-x (from /project/trunk:170)
 
========================================================================
  r175 | user | YYYY-MM-DD HH:MM:SS +0000 (Day, DD Mon YYYY) | N lines

  Comment
 
------------------------------------------------------------------------

This can of course be scripted, but it would be great to have this sort
of support directly.

I think the sort of syntax David mentioned could also be supported with
an approach similar to this. Other than a new "svn:copy-area" property
I don't think any further "scaffolding" is required. However, providing
the functionality itself is not entirely trivial...

Possibly, it would be better to have the "svn:copy-area" in the
working copy rather than the repository. But this was only intended to
be the beginnings of an idea...


Rob.

_______________________________________________
This email has been scanned for Softel by Star.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org


Re: Accidental double tag copy

Posted by David Weintraub <qa...@gmail.com>.
Actually, all this talk about tags "having no special meaning" brings
up another point that was bandied about this list a few years ago.

The concept was called "labels" (to help distinguish it from "tags").
Basically, a label would simply be an alias to a revision. For
example:

    $ svn mklabel REL-1.0 12345

This would make the label REL-1.0 synonymous with revision 12345. This
means you could now do things like this:

    $ svn diff -rREL-1.0:HEAD

or

    $ svn update -rREL-1.0

I know there are some limitations with this:

* You can't "edit" a label in order to change one program like you can
with a tag. Imagine if I create a release, and realize that I am
missing a few programs. With tags, I can edit the tag and add change a
few files. You can't easily do that with a label.

* A label would be across an entire repository. If I have multiple
projects, I can have a separate tag directory for each project.
Creating a label for project "A" would also create a meaningless label
for project "B".

* There has to be some changes in the back end because you'll now have
to create a label database. Not too bad since it wouldn't affect the
source in the repository.

* You now need a whole slew of commands to make, delete, and list your
repository tags. Older clients would not be able to do this, and
neither will order versions of your repository. We face this issue now
(Features in 1.5 that weren't in 1.4 and whether these are implemented
in the repository, client, or both), but while the other features were
sort of frosting-on-the-cake, this would be a major change, and if
heavily used, would really affect a whole range of developers.

But, at the same time labels would greatly simplify syntax, you could
easily do diffs, updates, and updates to a particular revision without
typing in complex URLs. There is no need to do research to find out
when a tag was created in order to do revision pinning, And, it would
also provide a built in mechanism to prevent accidentally changing the
meaning of a label/tag. No need for a special version of the svn "cp"
or "mv" command to prevent accidental double labeling.

$ svn co -rREL-1.0 svn://localhost/trunk/foo  #Checking out a label
$ cd foo
$ vi program.cpp #Editing a program
$ svn commit    #This will fail since you're not on HEAD!

versus

$ svn co svn://localhost/tags/REL-1.0/foo
$ cd foo
$ vi program.cpp
$ svn commit    #This will work, changing what you think is REL-1.0!

I know that Subversion works fine without "labels", and you can
provide shell scripts to emulate this stuff, but it would be nice to
have something like this built into Subversion. And, developers would
find Subversion a bit easier to use and comprehend.

--
David Weintraub
qazwart@gmail.com

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Accidental double tag copy

Posted by Vincent Lefevre <vi...@vinc17.org>.
On 2008-09-29 05:40:35 -0500, Ryan Schmidt wrote:
> [Running "svn cp $URL/trunk $URL/tags/tagname" twice causes undesirable 
> behavior]
>
> Ok, well you could write a less-restrictive hook script that would  
> prevent adding a directory inside a tag directory that has the same name 
> as the tag directory. For example, if you have a tag "release-1.2.3", the 
> script should prevent the creation of a directory "release-1.2.3" inside 
> it. That would solve the specific problem of trying to create a tag that 
> already exists. You could do the same for branches if you want.

Shouldn't "svn cp" and "svn mv" have a --no-target-directory option
just like GNU cp and mv?

-- 
Vincent Lefèvre <vi...@vinc17.org> - Web: <http://www.vinc17.org/>
100% accessible validated (X)HTML - Blog: <http://www.vinc17.org/blog/>
Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

Re: Accidental double tag copy

Posted by Ryan Schmidt <su...@ryandesign.com>.
On Sep 29, 2008, at 04:00, Rob Hubbard wrote:

[Running "svn cp $URL/trunk $URL/tags/tagname" twice causes  
undesirable behavior]

>> Install a pre-commit hook to allow adds but not modifications
>> in the tags directory and you solve the problem.
>
> That's a good idea. However, it is possible that you might wish to
> create the tag and then adjust, for example, the version  
> information in
> the tag itself. I'm not saying that's good practice, but a hook script
> does prevent the tags area from being used a little flexibly like  
> this.


Ok, well you could write a less-restrictive hook script that would  
prevent adding a directory inside a tag directory that has the same  
name as the tag directory. For example, if you have a tag  
"release-1.2.3", the script should prevent the creation of a  
directory "release-1.2.3" inside it. That would solve the specific  
problem of trying to create a tag that already exists. You could do  
the same for branches if you want.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org

RE: Accidental double tag copy

Posted by Rob Hubbard <ro...@softel.co.uk>.
Thanks for the suggestions Ryan.

> Well, the tags directory does have a special meaning to you and me:  
> it is a place where you copy things to but then never change again.  

Yes, I agree. The tag directory does have a special meaning to users,
but that's by convention, not hard-coded into SVN.
And that's as it should be. (So, I think we agree on this.)

> Install a pre-commit hook to allow adds but not modifications 
> in the tags directory and you solve the problem.

That's a good idea. However, it is possible that you might wish to
create the tag and then adjust, for example, the version information in
the tag itself. I'm not saying that's good practice, but a hook script
does prevent the tags area from being used a little flexibly like this.
(I don't know of a way to implement a '--force' to allow a hook script
to be bypassed.)

> > The problem stems from the fact that the copy command means 
> something 
> > slightly different depending upon whether the target already exists.
> > An alternative possible cause of this problem is if two engineers 
> > create the same tag at almost the same time.
> 
> Two engineers trying to create tag at the same time is a 
> communication problem; not Subversion's domain to solve that.

I agree. I think for official releases this is certainly the case.
SVN commands certainly should not be used instead of communication.
But, suppose that tags are also used to trigger 'informal' test builds;
this might occur often enough that it's not worth having a formalised
process in place. Then I think it is reasonable to ask for SVN to
provide a little additional support.

It is not SVN's job to enforce good practice, only to encourage it.
SVN should be a flexible tool, allowing a team to implement whatever
mechanisms and processes suit the needs of that team.

(To illustrate what I mean, consider that SVN provides a locking
mechanism. This helps prevent two authors both editing a bitmap at the
same time. The same could be achieved by team communication and
process. The fact that SVN has a locking mechanism, though, helps, and
this mechanism can be used as *part* of a process or team communication
system.)


Thus whilst I agree with all the points you have made, I don't think
you have given reason why my suggestions should *not* be implemented.

My suggestions a usefulness beyond the particular circumstances I have
used here to motivate them.

Thus I still think it would be useful to have the
    --target-directory DIR
    --no-target-directory
as with the Bash shell copy command.

Likewise, I think it would also still be useful to have some mechanism
whereby a branch or tag area, or indeed any directory, can be given
protection from having loads of files 'accidentally' copied into it.
Usually, if you copy many files into an area already containing lots of
files, that is a mistake. It would be nice if the *default* copy
behaviour prevented this, somehow.

What I don't have is a good suggestion for how to do this.
My inclination would be for copy to not perform such copies without
an explicit, e.g.,
	--combine-trees
switch. That suggestion would not be backwards compatible, but would,
I think, be useful, and in all other respects an advantage.

I'd certainly welcome other suggestions.

Thanks,
Rob.

Rob Hubbard

_______________________________________________
This email has been scanned for Softel by Star.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org


Re: Accidental double tag copy

Posted by Ryan Schmidt <su...@ryandesign.com>.
On Sep 26, 2008, at 12:07, Rob Hubbard wrote:

> In the past, I've encountered a problem with tag creation. If the SVN
> copy command is accidentally issued twice, something rather nasty
> happens.
>
> Suppose you have a project called "tag_copy_twice" with a few files  
> in a
>
> version-controlled trunk (in some repository svn://repos/) as follows:
>
>     ./tag_copy_twice/trunk/dir/dir_file.txt
>     ./tag_copy_twice/trunk/file.txt
>
> You create a tag for version 1.0 as follows, e.g.
>
>     $ svn copy -m"tag v1.0" "svn://repos/tag_copy_twice/trunk" \
>         "svn://repos/tag_copy_twice/tag/v1.0"
>
> All is still well and good. You now also have these files:
>
>     ./tag_copy_twice/tag/v1.0/dir/dir_file.txt
>     ./tag_copy_twice/tag/v1.0/file.txt
>
> Accidentally issuing the tagging command a second time, you end up  
> with
> this:
>
>     ./tag_copy_twice/tag/v1.0/dir/dir_file.txt
>     ./tag_copy_twice/tag/v1.0/file.txt
>     ./tag_copy_twice/tag/v1.0/trunk/dir/dir_file.txt
>     ./tag_copy_twice/tag/v1.0/trunk/file.txt
>
> This is perfectly reasonable. It's what you asked for. The behaviour
> matches what a shell copy (or cp) command would do. It's certainly not
> an SVN bug.
>
> (I think this is a special case that TortoiseSVN warns about:  
> changes to
> areas with "tag" in the URL. I don't think that's the right  
> approach for
> SVN: paths should not have special meanings.)

Well, the tags directory does have a special meaning to you and me:  
it is a place where you copy things to but then never change again.  
Install a pre-commit hook to allow adds but not modifications in the  
tags directory and you solve the problem.


> The problem stems from the fact that the copy command means something
> slightly different depending upon whether the target already exists.
> An alternative possible cause of this problem is if two engineers  
> create
> the same tag at almost the same time.

Two engineers trying to create tag at the same time is a  
communication problem; not Subversion's domain to solve that.


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org