Your question raises an important issue: "What are the semantics of
sparse directories?" You expected "svn copy" to copy just the parts that
are present in the WC, whereas in fact it copies the whole logical tree.
There is a reason for that, but I think it is not clear how a user
should expect each Subversion command to behave.
In this email I will just address how it works at the moment and how to
achieve the tagging that you wanted. I will start a separate email
thread to discuss the semantics of sparse directories.
Stas Cherkassky wrote:
> I don't want to remove parts of the tree from the repository.
> What I want is, effectively, a way to independently mark separate
> parts of the tree with the same tag.
> (I tried to explain it in my example). I don't see how your method
> (using svn rm) does it.
I'll explain my method using "svn rm" first, and then the method using
"svn copy" with multiple source arguments.
You don't exactly want to remove parts from the repository, but one way
of thinking about what you want to create in the repository (the tagged
data) is a copy of your normal working tree except with some parts
removed. A common and flexible way to create a tree in a Subversion
repository is to create it in a WC and then commit (or in this case
copy) it. That's what my suggestion was for.
svn rm myproj/[everything except dirA and dirB]
svn copy myproj ^/tags/rel_X/
And then if you want to restore your WC to how it was, you can revert
the parts that are scheduled for deletion:
svn revert -R myproj/[everything except dirA and dirB]
Another way of thinking about the task is to ask Subversion to copy only
the parts you want:
$ svn copy --parents myproj/dirA myproj/dirB ^/tags/rel_X/myproj/
Committed revision 2.
$ svn log -vq -c2
r2 | julianfoad | 2010-01-08 10:37:34 +0000 (Fri, 08 Jan 2010)
A /tags/rel_X/myproj/dirA (from /myproj/dirA:1)
A /tags/rel_X/myproj/dirB (from /myproj/dirB:1)
There is a limitation with this form of the copy command. With a single
"svn copy" command, all the specified source objects (dirA and dirB in
this case) are created as direct children of the target directory. There
is no way to extend that example to make myproj/dirC/foo go to
^/tags/rel_X/myproj/dirC/foo at the same time as copying dirA and dirB.
However, you can extend a tag by making a further commit to it with a
second copy command, unless committing to a tag is disabled in your
repository. So you could do:
$ svn mkdir ^/tags/rel_X/myproj -m "New tag. Incomplete."
$ svn copy dirA ^/tags/rel_X/myproj/ -m "Incomplete."
$ svn copy dirB ^/tags/rel_X/myproj/ -m "Incomplete."
$ svn copy --parents dirC/foo ^/tags/rel_X/myproj/dirC/foo
-m "Completed tag for rel_X of myproj."
> If a tag is a property of a file (like in CVS), it's natural operation :
> cvs tag -R dirA -t relX # tags whatever files and versions I have in WC
> and then
> cvs tag -R dirB -t relX
> In the end I have both dirA and dirB tagged with same tag relX.
You can certainly do the equivalent thing in Subversion: it is the "svn
copy" method that I described above.
> If a tag is an object (like in Perforce), and it's property is a list
> of files/versions it applies to, it's also easily achievable in very
> similar manner - 2nd p4 tag call would just add more files to that
> property of the tag object.
That is also like the "svn copy" method that I described above.
> With SVN's implementation of tags (logical directory in repo), it
> would also be possible, had 'svn copy' behave like I suggested.
That is true.
> IMHO, this way is more intuitive - that's what unix copy command would do.
The Unix copy command is not a fair comparison, because a normal Unix
directory is not a temporary working representation of the real data
stored on the server, and so does not have a way to mark certain files
and directories as "excluded from the local working copy". Or, looking
at it another way, if you mark some of the directory's children as
hidden (by renaming them to start with a dot in Unix), then a copy of
the whole directory will still include those hidden items.
Received on 2010-01-13 19:00:59 CET