Recap
-----
Last fall Greg Hudson and Karl, in discussing Jonathan Gilbert's
"takeover" patch, supported the idea that svn co should tolerate
obstructing paths by default. Fast forward to the middle of last month, I
proposed using Jonathan's patch as the basis for a new patch that would do
just that. There was some immediate committer support for this proposal
(dlr, lundblad, and zhakov).
In the interest of full disclosure, shortly after that immediate support,
a number of other folks (John Peacock, Alan Barrett, Molle Bestefich,
Michael Sweet, Jonathan, and Julian) started suggesting alternatives...but
I'd seen Jonathan's takeover subcommand wither and died last fall because
no consensus was reached and I didn't want that to occur again. No
disrespect intended to those who wanted another approach, but IMHO I had
reasonable support for my proposal and that is what this patch is about.
Default or --force?
-------------------
The original proposal was for svn co to tolerate obstructions by default,
but eventually I decided to require the --force option. Someone pointed
out that the svnbook description of --force made a fairly compelling case:
"Forces a particular command or operation to run. There are some
operations that Subversion will prevent you from doing in normal usage,
but you can pass the force switch to tell Subversion "I know what I'm
doing as well as the possible repercussions of doing it, so let me at
'em". This switch is the programmatic equivalent of doing your own
electrical work with the power on?if you don't know what you're doing,
you're likely to get a nasty shock."
Isn't this exactly what this patch does? Anyway, consider me
convinced...for now :-)
(If this approach is acceptable Mark has a follow-up patch for JavaHL.)
A Note on Terminology
---------------------
The patch and the log use variations of the terms "obstruction" and
"takeover".
I think(?) we all understand the former to be a file or directory that
already exists when a svn checkout attempts to add the same path and the
co fails with a SVN_ERR_WC_OBSTRUCTED_UPDATE error.
The latter was originally proposed by Jonathan Gilbert as a new
subcommand, the nuances of which were discussed and debated on the dev
list. Here I use it here simply to mean the process by which a forced
checkout tolerates obstructing paths, treating the existing obstruction as
a modification to the resulting working copy.
Use Cases
---------
"svn co --force URL WC_PATH" behaves exactly as "svn co URL WC_PATH" does
now except when the co attempts to add some path PATH where URL/PATH ==
WC_PATH/PATH. In these cases there is an obstruction and these are
handled as follows:
======================================================================
***** USE CASE A: Dir obstructs a file *****
URL/PATH WC_PATH/PATH
TYPE TYPE RESULT
----------------------------------------------------------------------
FILE DIR CO FAILS: "svn: Failed to takeover
file '/WC_PATH/PATH': a non-file
object of the same name already
exists"
======================================================================
***** USE CASE B: File obstructs a dir *****
URL/PATH WC_PATH/PATH
TYPE TYPE RESULT
----------------------------------------------------------------------
DIR FILE CO FAILS: "svn: Failed to takeover
dir '/WC_PATH/PATH': a non-dir
object of the same name already
exists"
======================================================================
***** USE CASE C: Identical file obstructs a file *****
TRANSLATED
FILE
URL/PATH WC_PATH/PATH CONTENTS
TYPE TYPE IDENTICAL? RESULT
----------------------------------------------------------------------
FILE FILE YES Text of WC_PATH/PATH is left as
is. Text-time field in entries
equal to modified date of
WC_PATH/PATH.
======================================================================
***** USE CASE D: Different file obstructs a file *****
TRANSLATED
FILE
URL/PATH WC_PATH/PATH CONTENTS
TYPE TYPE IDENTICAL? RESULT
----------------------------------------------------------------------
FILE FILE NO Text of WC_PATH/PATH is left as
is. Text-time field in entries
equal to committed-date field.
======================================================================
***** USE CASE E: Versioned dir obstructs a dir *****
URL & REV
OF
VERSIONED
DIR THE
URL/PATH WC_PATH/PATH SAME AS
TYPE TYPE URL/PATH? RESULT
----------------------------------------------------------------------
DIR VERSIONED YES WC_PATH/PATH properties are
DIR updated. Modified children of
WC_PATH/PATH are left as is.
Missing children are added unless
they are scheduled for deletion.
See Open Questions below.
======================================================================
***** USE CASE F: Versioned dir of different URL obstructs a dir *****
URL & REV
OF
VERSIONED
DIR THE
URL/PATH WC_PATH/PATH SAME AS
TYPE TYPE URL/PATH? RESULT
----------------------------------------------------------------------
DIR VERSIONED NO, CO FAILS: "svn: Failed to forcibly
DIR DIFFERENT add directory 'WC_PATH/PATH'
URL Dir in repos and wc': a versioned
directory of the same name already
exists but which points to a
diffent URL"
======================================================================
***** USE CASE G: Out of date versioned dir obstructs a dir *****
URL & REV
OF
VERSIONED
DIR THE
URL/PATH WC_PATH/PATH SAME AS
TYPE TYPE URL/PATH? RESULT
----------------------------------------------------------------------
DIR VERSIONED NO, SAME CO FAILS: "svn: Revision x doesn't
DIR URL BUT match existing revision y in
DIFFERENT 'WC_PATH/PATH'"
REV See Open Questions below.
======================================================================
***** USE CASE H: Dir obstructs a dir *****
URL & REV
OF
VERSIONED
DIR THE
URL/PATH WC_PATH/PATH SAME AS
TYPE TYPE URL/PATH? RESULT
----------------------------------------------------------------------
DIR UNVERSIONED N/A WC_PATH/PATH becomes versioned.
DIR
======================================================================
New Tests
---------
This patch includes a tentative set of new Python tests: checkout_tests.py
USE TEST IN CHECKOUT_TESTS.PY
CASES
======================================================================
checkout_with_obstructions
A forced_checkout_of_file_with_dir_obstructions
B forced_checkout_of_dir_with_file_obstructions
C forced_checkout_with_faux_obstructions
D, H forced_checkout_with_real_obstructions
D forced_checkout_with_real_obstructions_and_unversioned_nodes
D, E forced_checkout_with_versioned_obstructions_same_URL
F forced_checkout_with_versioned_obstructions_different_URL
======================================================================
Note: When a file or dir exists prior to a forced checkout and obstructs
during the co, it is reported as
"T WC_PATH/PATH"
rather than
"A WC_PATH/PATH"
"T" of course stands for takenover. This applies to use cases C, D, E,
and H.
Open Questions
--------------
I'm uncertain what the ideal behavior is in use cases E and G.
For use case E, this patch has problems with property mods. Is it best to
simply fail whenever a versioned directory obstructs? Should it be more
like an update, including potential conflicts?
For use case G, assuming we even want to allow obstructing versioned
directories, I see three options:
1) Allow forced checkouts with obstructing versioned directories
only if the obstructing directories are up to date with the
repository HEAD.
2) Update the obstructing directory to HEAD.
3) Skip over the obstructing directory leaving it exactly as is.
What This Patch Doesn't Do (Yet)
--------------------------------
A few people have mentioned that perhaps missing paths should be scheduled
for deletion and non-obstructing paths scheduled for addition. This patch
does neither as it wasn't in my original proposal and I wanted to keep
this first patch as simple as possible.
Ok, if you've gotten this far, thanks! Any and all feedback is
appreciated.
Paul B.
[[[
Checkout tolerates obstructing paths when used with --force option.
This patch is a modification and expansion of one originally posted
by Jonathan Gilbert <o2w9gs702@sneakemail.com> against the 1.2.0 tag.
See the various "Takeover" threads on the dev mailing list.
This patch adds the --force option to svn checkout. With this option
a checkout into a local tree that has obstructing paths will succeed
rather than generating a SVN_ERR_WC_OBSTRUCTED_UPDATE error.
* build.conf
(test-scripts): Add checkout_tests.py.
* subversion/include/svn_client.h
(svn_client_checkout3): New.
(svn_client_checkout2): Deprecate.
* subversion/include/svn_wc.h
(svn_wc_notify_action_t): New 'takeover' action.
(svn_wc_get_update_editor3): New.
(svn_wc_get_update_editor2): Deprecate.
* subversion/libsvn_client/checkout.c
(svn_client__checkout_internal): New argument to identify use of
--force option. Update calls to svn_client__update_internal.
(svn_client_checkout3): New.
(svn_client_checkout): Reimplement as wrapper around
svn_client_checkout3.
(svn_client_checkout): Update call to svn_client__checkout_internal.
* subversion/libsvn_client/client.h
(svn_client__update_internal, svn_client__checkout_internal): New
argument to identify calls made as part of forced co.
* subversion/libsvn_client/copy.c
(repos_to_wc_copy): Update call to svn_client__update_internal.
* subversion/libsvn_client/externals.c
(switch_external, handle_external_item_change): Update calls to
svn_client__checkout_internal and svn_client__update_internal.
* subversion/libsvn_client/update.c
(svn_client__update_internal): New argument. Replace call to
svn_wc_get_update_editor2 with svn_wc_get_update_editor3.
(svn_client_update2, svn_client_update): Update calls to
svn_client__update_internal.
* subversion/libsvn_wc/update_editor.c
(struct edit_baton): New member forced_checkout.
(struct file_baton): New member taken_over.
(make_file_baton): Initialize new file_baton member.
(add_directory): Allow obstructing directories during forced co.
Support notification for directory 'takeover' as well as 'add'.
(add_or_open_file): Allow obstructing files during forced co.
(change_file_prop): Cache the last-changed-date propval for
obstructing files.
(merge_file): New argument to differentiate between takeovers
and 'normal' updates/checkouts. Handle the various takeover
scenarios.
(close_file): Update call to merge_file. Support notification for
file 'takeover' as well as 'add'.
(make_editor): New argument used to initialize the new forced_checkout
member in the returned edit_baton.
(svn_wc_get_update_editor3): New.
(svn_wc_get_update_editor2, svn_wc_get_switch_editor2): Update calls
to make_editor.
* subversion/svn/checkout-cmd.c
(svn_cl__checkout): Replace call to svn_wc_get_update_editor2 with
svn_wc_get_update_editor3. Cleanup text-time field in entries for
obstructing files with no modifications.
* subversion/svn/main.c
(svn_cl__cmd_table): Enable --force option with svn co.
* subversion/svn/notify.c
(notify): Handle new 'takeover' action.
* subversion/tests/cmdline/checkout_tests.py: New.
]]]
_____________________________________________________________________________
Scanned for SoftLanding Systems, Inc. and SoftLanding Europe Plc by IBM Email Security Management Services powered by MessageLabs.
_____________________________________________________________________________
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Thu May 4 22:44:04 2006