I'm seeing odd behavior when using svn_client_status2 with version 1.7.7.

  1. I have two checkouts of a single directory, both fully up-to-date.
  2. In the one checkout I add/commit a new file within the directory.
  3.  From the other checkout I call "svn_client_status2" on the
     directory and see the following status structure
     ("svn_wc_status2_t") filled with:

text_status = svn_wc_status_modified
prop_status = svn_wc_status_normal
repo_text_status = svn_wc_status_modified
repo_prop_status = svn_wc_status_none
pristine_text_status = svn_wc_status_normal
pristine_ prop_status = svn_wc_status_normal

I expect the "repo_text_status" to be modified as the directory now contains the new file in the repository. However, locally, the "text_status" shows "svn_wc_status_modified" when I think it should show "svn_wc_status_normal".

When debugging this I see that "svn_wc__status2_from_3" is called prior to my "svn_wc_status_func2_t" callback being called. The "svn_wc_status3_t" structure being converted is filled with:
node_status = svn_wc_status_normal
text_status = svn_wc_status_normal
prop_status = svn_wc_status_normal
repo_node_status = svn_wc_status_modified
repo_text_status = svn_wc_status_modified
repo_prop_status = svn_wc_status_none

Here the "text_status" is "svn_wc_status_normal" as I expect. So somewhere within "svn_wc__status2_from_3" the conversion is messing up. Looking at this function in more detail shows what appears to be the problem:
svn_error_t *
svn_wc__status2_from_3(svn_wc_status2_t **status,
                      const svn_wc_status3_t *old_status,
                      svn_wc_context_t *wc_ctx,
                      const char *local_abspath,
                      apr_pool_t *result_pool,
                      apr_pool_t *scratch_pool)
{
 ...
 (*status)->text_status = old_status->node_status;
 (*status)->prop_status = old_status->prop_status;

 (*status)->repos_text_status = old_status->repos_node_status;
 (*status)->repos_prop_status = old_status->repos_prop_status;

 /* Some values might be inherited from properties */
 if (old_status->node_status == svn_wc_status_modified
     || old_status->node_status == svn_wc_status_conflicted)
   (*status)->text_status = old_status->text_status;

 /* (Currently a no-op, but just make sure it is ok) */
 if (old_status->repos_node_status == svn_wc_status_modified
     || old_status->repos_node_status == svn_wc_status_conflicted)
   (*status)->text_status = old_status->repos_text_status;
...
}

As you can see "text_status" and "repos_text_status" follow similar logic, however the last line appears to be a copy & paste bug, where "text_status" is used it should instead be "repos_text_status". This explains why the "svn_wc_status2_t->text_status" has the value "svn_wc_status_modified" because it's being set to the value of "svn_wc_status3_t->repos_text_status".

This section of code was committed with revision 955787 by rhuijben.

Can anyone confirm my findings are correct, or wrong?

Thank you,
Sean

Reply via email to