As described in issue #2915, in 1.6 when a merge target is a missing
subtree due to its removal by non-svn means, we try to record
mergeinfo such that the missing subtree doesn't have (or inherit)
mergeinfo describing the merge:
(If you already have a vague idea of how this works you can skip to
'You might suggest that it makes more sense' below for the RFC)
### A file is missing in our merge target
1.6.13-dev>svn st
! A_COPY\D\H\psi
### No initial mergeinfo
1.6.13-dev>svn pg svn:mergeinfo -vR
### Merge tries to apply change to missing file, but can't
### and reports it as skipped
1.6.13-dev>svn merge ^^/A A_COPY -r2:4
--- Merging r3 through r4 into 'A_COPY':
U A_COPY\D\G\rho
Skipped missing target: 'A_COPY\D\H\psi'
Summary of conflicts:
Skipped paths: 1
### Merge target gets mergeinfo describing the merge
### performed and the missing file gets empty "override"
### mergeinfo so it doesn't inherit the target's mergeinfo
1.6.13-dev>svn st
M A_COPY
M A_COPY\D\G\rho
!M A_COPY\D\H\psi
1.6.13-dev>svn pg svn:mergeinfo -vR
Properties on 'A_COPY\D\H\psi':
svn:mergeinfo
Properties on 'A_COPY':
svn:mergeinfo
/A:3-4
If the missing subtree was a directory we obviously can't set its
properties, so we treat this as a tree conflict:
1.6.13-dev>svn st
! A_COPY\D\H
1.6.13-dev>svn merge ^^/A A_COPY -r2:4
--- Merging r3 through r4 into 'A_COPY':
U A_COPY\D\G\rho
C A_COPY\D\H
Summary of conflicts:
Tree conflicts: 1
1.6.13-dev>svn st
M A_COPY
M A_COPY\D\G\rho
! C A_COPY\D\H
> local delete, incoming edit upon merge
~~~~~
You might suggest that it makes more sense to simply throw an error
when a mergeinfo aware merge hits a missing subtree rather than
jumping through these hoops. I wouldn't disagree, but an even better
solution was suggested to me recently by Bert: Restore the missing
subtrees. With wcng's single DB this should be easy with
svn_wc_restore().
Does anyone see a reason we should not restore missing subtrees
encountered during a merge?
Assuming for a moment there is general agreement about the goodness of
this approach, which sounds better:
A) Check for missing subtrees at the start of the merge and restore
them prior to any editor drives. This would be easy enough to do in
libsvn_client/merge.c:get_mergeinfo_paths() which we call at the start
of a merges to collect information about subtrees "interesting" from a
merge-tracking perspective. The drawback here is that we need to
detect all the missing subtrees and that means a new call to
svn_io_check_path/apr_stat for every path in the merge target. Since
99.99%* of merges don't involve missing subtrees, we are imposing a
needless performance penalty on most users.
B) Restore the missing subtrees on-the-fly when the svn_delta_editor_t
callbacks (i.e. open_directory, open_file) actually encounter a
missing subtree. This keeps the svn_io_check_path() calls to a
minimum. The drawback is that missing subtrees untouched by the
editor are still missing after the merge.
Any preference or suggestions for a superior solution are appreciated.
Thanks,
Paul
* Yes, completely invented fact, but I feel pretty safe saying it.
Received on 2010-08-06 16:31:51 CEST