[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Creating sparse working copy retroactively from existing disjoint working copies

From: Robert Whitaker <capnwhit_at_yahoo.com>
Date: Wed, 15 Aug 2012 23:00:53 -0700 (PDT)

========
QUESTION
========
Is it possible to retroactively convert a "disjoint" working copy
into a "sparse" working copy?

=======
SUMMARY
=======
I have not been able to do this, and a new feature request may be
to add an "include" option to the --set-depth flag. The --set-depth
flag already has an "exclude" option so adding an "include" option
seems symmetric and may solve this problem.

==========
BACKGROUND
==========
I have tried doing this with the --set-depth and --force flags and I
can _ALMOST_ get it to work... but I have come to a dead end... I
have read the Subversion manual and I have searched previous posts...
Hopefully somebody on this list can point me to the right solution,
and if no solution exists, then maybe this can be turned into a
feature request for the "include" option.

=================
PROBLEM STATEMENT
=================
The following "statements" define the problem I am trying to solve:

---o---
STATEMENT 1:
---o---
Assume I have the following repository structure (the example was
borrowed from the Subversion manual):

mom/son
mom/son/grandson
mom/daughter
mom/daughter/granddaughter1
mom/daughter/granddaughter1/bunny1.txt
mom/daughter/granddaughter1/bunny2.txt
mom/daughter/granddaughter2
mom/daughter/fishie.txt
mom/kitty1.txt
mom/doggie1.txt

---o---
STATEMENT 2:
---o---
Assume I only care about "granddaughter1" as shown below:

mom/daughter/granddaughter1/bunny1.txt
mom/daughter/granddaughter1/bunny2.txt

---o---
STATEMENT 3:
---o---
Assume I didn't know about sparse checkouts (or about the --depth
flag) and assume I had created my working copy by creating all the
intermediary directories using "mkdir" as follows

$ mkdir -p /svn-test/mom/daughter

$ cd /svn-test/mom/daughter

$ svn co svn://REPOSITORY/mom/daughter/granddaughter1
A granddaughter1/bunny1.txt
A granddaughter1/bunny2.txt
Checked out revision 85792.

---o---
STATEMENT 4:
---o---
Of course, I can _NOT_ run "svn status" for the "mom" directory
because said directory is not part of the working copy:

$ svn status /svn-test/mom
svn: warning: '/svn-test/mom' is not a working copy

---o---
STATEMENT 5:
---o---
This is our problem statement: Assume I want to modify the above
working copy in-place and turn it into a sparse checkout. The end
result should be that I can run "svn status" from all intermediary
directories.

==================
ATTEMPTED SOLUTION
==================
In the steps below I attempt to solve our problem using the --depth
flag and I almost get it to work...

---o---
STEP 0:
---o---
For completeness, and for the benefit of those who may be following
these steps at home, here is the output of the "find" command which
shows the current directory structure:

$ find /svn-test
/svn-test
/svn-test/mom
/svn-test/mom/daughter
/svn-test/mom/daughter/granddaughter1
/svn-test/mom/daughter/granddaughter1/.svn
/svn-test/mom/daughter/granddaughter1/.svn/entries
/svn-test/mom/daughter/granddaughter1/.svn/prop-base
/svn-test/mom/daughter/granddaughter1/.svn/props
/svn-test/mom/daughter/granddaughter1/.svn/text-base
/svn-test/mom/daughter/granddaughter1/.svn/text-base/bunny1.txt.svn-base
/svn-test/mom/daughter/granddaughter1/.svn/text-base/bunny2.txt.svn-base
/svn-test/mom/daughter/granddaughter1/.svn/tmp
/svn-test/mom/daughter/granddaughter1/.svn/tmp/prop-base
/svn-test/mom/daughter/granddaughter1/.svn/tmp/props
/svn-test/mom/daughter/granddaughter1/.svn/tmp/text-base
/svn-test/mom/daughter/granddaughter1/bunny1.txt
/svn-test/mom/daughter/granddaughter1/bunny2.txt

---o---
STEP 1:
---o---
As expected running "svn status" does not work on "mom" yet:

$ svn status /svn-test/mom
svn: warning: '/svn-test/mom' is not a working copy

---o---
STEP 2:
---o---
In order to create our working copy "in-place" we first do an
svn "checkout" and set the --depth flag to empty for the "mom"
directory:

$ svn co --depth empty svn://REPOSITORY/mom /svn-test/mom
Checked out revision 85792.

---o---
STEP 3:
---o---
At this point, running "svn status" works OK on "mom", and it
correctly reports that "daugher" is unversioned. So far so good:

$ svn status /svn-test/mom
? /svn-test/mom/daughter

---o---
STEP 4:
---o---
The output of the "find" command is very encouraging and it shows
that "mom" is now an svn working copy directory and the "mom/.svn"
directory exists. All that we need to do is convince "mom" that
"daughter" is part of the working copy:

$ find /svn-test
/svn-test
/svn-test/mom
/svn-test/mom/.svn
/svn-test/mom/.svn/entries
/svn-test/mom/.svn/prop-base
/svn-test/mom/.svn/props
/svn-test/mom/.svn/text-base
/svn-test/mom/.svn/tmp
/svn-test/mom/.svn/tmp/prop-base
/svn-test/mom/.svn/tmp/props
/svn-test/mom/.svn/tmp/text-base
/svn-test/mom/daughter
/svn-test/mom/daughter/granddaughter1
/svn-test/mom/daughter/granddaughter1/.svn
/svn-test/mom/daughter/granddaughter1/.svn/entries
/svn-test/mom/daughter/granddaughter1/.svn/prop-base
/svn-test/mom/daughter/granddaughter1/.svn/props
/svn-test/mom/daughter/granddaughter1/.svn/text-base
/svn-test/mom/daughter/granddaughter1/.svn/text-base/bunny1.txt.svn-base
/svn-test/mom/daughter/granddaughter1/.svn/text-base/bunny2.txt.svn-base
/svn-test/mom/daughter/granddaughter1/.svn/tmp
/svn-test/mom/daughter/granddaughter1/.svn/tmp/prop-base
/svn-test/mom/daughter/granddaughter1/.svn/tmp/props
/svn-test/mom/daughter/granddaughter1/.svn/tmp/text-base
/svn-test/mom/daughter/granddaughter1/bunny1.txt
/svn-test/mom/daughter/granddaughter1/bunny2.txt

---o---
STEP 5:
---o---
Now that "mom" is an svn directory, we can use the "svn update"
command and set the --depth flag to empty for the "mom/daughter"
directory... our first attempt shows an error deliberately for
instructional purposes. The command fails because an unversioned
directory named "daughter" already exists:

$ svn update --depth empty /svn-test/mom/daughter
svn: Failed to add directory '/svn-test/mom/daughter': an unversioned
directory of the same name already exists

---o---
STEP 6:
---o---
We now try again but with the --force flag, and this works OK, and
I get the "E" status because svn recognizes that "daughter" was an
"Existing" directory:

$ svn update --depth empty --force /svn-test/mom/daughter
E /svn-test/mom/daughter
Updated to revision 85792.

---o---
STEP 7:
---o---
This current step is symmetric with STEP 3. In STEP 3 we were able
to run the "svn status" command on "mom", and it correctly reported
that "daugher" was unversioned. Now in STEP 7 we are able to run the
"svn status" command on "mom/daughter", and it correctly reports that
the "granddaughter1" directory is unversioned. So far so good:

$ svn status /svn-test/mom/daughter
? /svn-test/mom/daughter/granddaughter1

---o---
STEP 8:
---o---
This current step is symmetric with STEP 4. Once again, the output of
the "find" command is encouraging and it shows that "daughter" is now
an svn directory and all the intermediary ".svn" directories exist:

$ find /svn-test
/svn-test
/svn-test/mom
/svn-test/mom/.svn
/svn-test/mom/.svn/entries
/svn-test/mom/.svn/prop-base
/svn-test/mom/.svn/props
/svn-test/mom/.svn/text-base
/svn-test/mom/.svn/tmp
/svn-test/mom/.svn/tmp/prop-base
/svn-test/mom/.svn/tmp/props
/svn-test/mom/.svn/tmp/text-base
/svn-test/mom/daughter
/svn-test/mom/daughter/.svn
/svn-test/mom/daughter/.svn/entries
/svn-test/mom/daughter/.svn/prop-base
/svn-test/mom/daughter/.svn/props
/svn-test/mom/daughter/.svn/text-base
/svn-test/mom/daughter/.svn/tmp
/svn-test/mom/daughter/.svn/tmp/prop-base
/svn-test/mom/daughter/.svn/tmp/props
/svn-test/mom/daughter/.svn/tmp/text-base
/svn-test/mom/daughter/granddaughter1
/svn-test/mom/daughter/granddaughter1/.svn
/svn-test/mom/daughter/granddaughter1/.svn/entries
/svn-test/mom/daughter/granddaughter1/.svn/prop-base
/svn-test/mom/daughter/granddaughter1/.svn/props
/svn-test/mom/daughter/granddaughter1/.svn/text-base
/svn-test/mom/daughter/granddaughter1/.svn/text-base/bunny1.txt.svn-base
/svn-test/mom/daughter/granddaughter1/.svn/text-base/bunny2.txt.svn-base
/svn-test/mom/daughter/granddaughter1/.svn/tmp
/svn-test/mom/daughter/granddaughter1/.svn/tmp/prop-base
/svn-test/mom/daughter/granddaughter1/.svn/tmp/props
/svn-test/mom/daughter/granddaughter1/.svn/tmp/text-base
/svn-test/mom/daughter/granddaughter1/bunny1.txt
/svn-test/mom/daughter/granddaughter1/bunny2.txt

---o---
STEP 9:
---o---
In STEP 4 all that we needed to do was convince "mom" that "daughter"
was part of the working copy. We first attempted this in STEP 5 (but
we had a deliberate error) and we finally accomplished this using the
--force flag in STEP 6. In STEP 8 above all that we need to do is
convince "daughter" that "granddaughter1" part of the working copy,
and we will attempt this below in STEP 10:

---o---
STEP 10:
---o---
This current step is symmetric with STEP 6. We now use the --force
flag and we try to use "svn update" on the "granddaughter1" directory:

$ svn update --depth empty --force /svn-test/mom/daughter/granddaughter1
At revision 85792.

---o---
STEP 11:
---o---
Notice that I got the "E" status in STEP 6 because svn recognized
that "daughter" was an "Existing" directory, but notice I did NOT
get an "E" status in STEP 10 above on the "granddaughter1" directory.
This is where our problem starts... If I repeat STEP 7 and try to run
"svn status" on "daughter", it still shows that "granddaughter1" is
unversioned:

$ svn status /svn-test/mom/daughter/
? /svn-test/mom/daughter/granddaughter1

---o---
STEP 12:
---o---
I can modify STEP 10 to use "--depth infinity" since I truly want
all files inside "granddaughter1" but this doesn't work either. I
can _NOT_ connect "daughter" and "granddaughter1". I am basically
stuck!!!

===========
CONCLUSIONS
===========
---o---
CONCLUSION 1:
---o---
The behavior of svn is inconsistent between STEP 6 and STEP 10. In
STEP 6 I was able to tell "mom" that "daughter" was part of the
"mom" working copy, as shown below:

$ svn update --depth empty --force /svn-test/mom/daughter
E /svn-test/mom/daughter
Updated to revision 85792.

But in STEP 10 I can _NOT_ convince "daughter" that "granddaughter1"
is part of the "daughter" working copy, as shown below:

$ svn update --depth empty --force /svn-test/mom/daughter/granddaughter1
At revision 85792.

This is understandable because the state of the directories is
DIFFERENT in both steps. In STEP 6, the "daughter" directory is an
unversioned directory not part of any working copy, but in STEP 10,
the "granddaughter1" directory is _ALREADY_ a working copy itself.

---o---
CONCLUSION 2:
---o---
Due to the fact that "granddaughter1" was already a working copy
itself, the command in STEP 10 acted on "granddaughter1/.svn"
and it did _NOT_ add "granddaughter1" to "daughter/.svn"

---o---
CONCLUSION 3:
---o---
We need a way to tell the "daughter/.svn" working copy to include an
already existing working copy... All that we seem to be missing is we
need to connect the "daughter/.svn" information to the "granddaughter1"
directory.

=================
POSSIBLE SOLUTION
=================
---o---
SOLUTION 1:
---o---
Maybe this problem can be solved with a new "include" option for the
--set-depth flag. Said flag already has an "exclude" option so it would
seem natural (and symmetric) for it to have an "include" option.

For example if we had a consistent working copy we _COULD_ tell
"daughter/.svn" to "exclude" the "granddaughter1" directory as
follows:

$ svn update --set-depth exclude /svn-test/mom/daughter/granddaughter1

THEREFORE: One possible solution to this problem is to create a
new "include" option as follows:

$ svn update --set-depth include /svn-test/mom/daughter/granddaughter1

---o---
SOLUTION 2:
---o---
Another solution (which works but it is a total hack) is to delete the
"granddaughter1/.svn" directory and repeat STEP 10. This is a total
hack and it is presented here only for instructional purposes.

==================
ALTERNATE SOLUTION
==================
Of course there may be an alternate solution which uses existing svn
commands to solve this problem? I would be happy to hear from somebody
about how to solve this problem.

Thanks!
Received on 2012-08-16 08:01:37 CEST

This is an archived mail posted to the Subversion Users mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.