On Apr 30, 2012 10:48 AM, "Paul Burba" <ptbu...@gmail.com> wrote: > > On Fri, Apr 27, 2012 at 10:35 PM, Greg Stein <gst...@gmail.com> wrote: > >... > > I've verified this behavior by manually flipping the order of these > > two changes during the editor drive. > > Hi Greg, > > Are you seeing this error on a case-sensitive filesystem? When I flip > the ordering I see the above "bad" behavior too (on Windows) but at > first glance it looks like it should work on a case-sensitive > filesystem.
Mac OS. I don't recall the filesystem on that partition. Whatever is the default. I'll run a test in a bit. > > > I don't think there is anything that says we will see deletes first, > > followed by adds. It just "happens" to have done that so far. But my > > recent work ended up changing that order. Boom. > > Our of curiosity, which recent work is that? The Ev2 shims. Specifically the Ev2 receiver shim, driving the actual Ev1 editor. That drive is performed by the path_driver code against a list of paths that were touched in the Ev2 drive. The paths are first sorted, in order to get correct depth-first dir/file baton behavior. Since Ev2's interface contract says "any order", the sorting was fine. It would be as if somebody drove Ev2 in a slightly different order. However, MU sorts before mu. Boom. > > > Any thoughts on what is going on here? Is there some kind of > > case-conflict check that causes that skip to happen? (or is it > > something else?) > > On Windows what happens when the add of 'MU' comes in before the > deletion of 'mu' is that merge.c:merge_file_added performs an > obstruction check, ultimately calling svn_wc__check_for_obstructions: > > svn_wc__check_for_obstructions(svn_wc_notify_state_t *obstruction_state, > svn_node_kind_t *kind, > svn_boolean_t *added, > svn_boolean_t *deleted, > svn_wc_context_t *wc_ctx, > const char *local_abspath, > svn_boolean_t no_wcroot_check, > apr_pool_t *scratch_pool) > { > svn_wc__db_status_t status; > svn_kind_t db_kind; > svn_node_kind_t disk_kind; > svn_error_t *err; > > *obstruction_state = svn_wc_notify_state_inapplicable; > if (kind) > *kind = svn_node_none; > if (added) > *added = FALSE; > if (deleted) > *deleted = FALSE; > > SVN_ERR(svn_io_check_path(local_abspath, &disk_kind, scratch_pool)); > ^^^^^^ > ### apr_stat considers 'MU' the same as 'mu', > ### so returns disk_kind=svn_node_file... > > err = svn_wc__db_read_info(&status, &db_kind, NULL, NULL, NULL, NULL, NULL, > NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, > NULL, NULL, NULL, NULL, NULL, NULL, NULL, > NULL, NULL, NULL, NULL, NULL, > wc_ctx->db, local_abspath, > scratch_pool, scratch_pool); > ^^^^^^ > ### ...but the DB, being smarter, knows that 'mu' is present, but not 'MU'... > > if (err && err->apr_err == SVN_ERR_WC_PATH_NOT_FOUND) > { > svn_error_clear(err); > > if (disk_kind != svn_node_none) > { > /* Nothing in the DB, but something on disk */ > *obstruction_state = svn_wc_notify_state_obstructed; > ^^^^^^ > ### ...and so we end up here, thinking the addition of 'MU' is > ### obstructed (and rightly so on a case-insensitive filesystem) > ### so it is skipped. Gotcha. And that is the right answer without the larger context. > > return SVN_NO_ERROR; > } > > > ... and the bigger question: how can you get this to > > work when the changes arrive as MU-first, mu-second? > > No simple solution presents itself on a case-insensitive file system, > heck no convoluted solution occurs to me at the moment. Alright. Maybe something along the lines of Stefan2's plan/execute two phase merge could recognize and handle case-only renames. I believe I can fix the shim to do deletes-first. Per else-thread, I'm a little hesitant to bake that into the API contract, but we'll figure out the right answer. Cheers, -g