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