/* An editor function.  */
static svn_error_t *
delete_entry(const char *path,
             svn_revnum_t base_revision,
             void *parent_baton,
             apr_pool_t *pool)
{
  struct item_baton *ib = parent_baton;
  struct edit_baton *eb = ib->edit_baton;
  svn_client_diff_summarize_t *sum;
  svn_node_kind_t kind;

  /* We need to know if this is a directory or a file */
  SVN_ERR(svn_ra_check_path(eb->ra_session,
                            path,
                            eb->revision,
                            &kind,
                            pool));

  sum = apr_pcalloc(pool, sizeof(*sum));
  sum->summarize_kind = svn_client_diff_summarize_kind_deleted;
  sum->path = path;
  sum->node_kind = kind;

  SVN_ERR(eb->summarize_func(sum, eb->summarize_func_baton, pool));

  if (kind == svn_node_dir)
        SVN_ERR(diff_deleted_dir(path,
                                 eb->revision,
                                 eb->ra_session,
                                 eb,
                                 eb->cancel_func,
                                 eb->cancel_baton,
                                 pool));

  return SVN_NO_ERROR;
}
Beispiel #2
0
/* An svn_delta_editor_t function.  */
static svn_error_t *
delete_entry(const char *path,
             svn_revnum_t base_revision,
             void *parent_baton,
             apr_pool_t *pool)
{
  struct dir_baton *pb = parent_baton;
  struct edit_baton *eb = pb->edit_baton;
  svn_node_kind_t kind;
  svn_wc_notify_state_t state = svn_wc_notify_state_inapplicable;
  svn_wc_notify_action_t action = svn_wc_notify_skip;
  svn_boolean_t tree_conflicted = FALSE;
  apr_pool_t *scratch_pool;

  /* Skip *everything* within a newly tree-conflicted directory,
   * and directories the children of which should be skipped. */
  if (pb->skip || pb->tree_conflicted || pb->skip_children)
    return SVN_NO_ERROR;

  scratch_pool = svn_pool_create(eb->pool);

  /* We need to know if this is a directory or a file */
  SVN_ERR(svn_ra_check_path(eb->ra_session, path, eb->revision, &kind,
                            scratch_pool));

  switch (kind)
    {
    case svn_node_file:
      {
        SVN_ERR(diff_deleted_file(&state, &tree_conflicted, path, eb,
                                  scratch_pool));
        break;
      }
    case svn_node_dir:
      {
        SVN_ERR(diff_deleted_dir(&state, &tree_conflicted, path, eb,
                                 scratch_pool));
        break;
      }
    default:
      break;
    }

  if ((state != svn_wc_notify_state_missing)
      && (state != svn_wc_notify_state_obstructed)
      && !tree_conflicted)
    {
      action = svn_wc_notify_update_delete;
    }

  if (eb->notify_func)
    {
      const char *deleted_path = apr_pstrdup(eb->pool, path);
      deleted_path_notify_t *dpn = apr_pcalloc(eb->pool, sizeof(*dpn));

      dpn->kind = kind;
      dpn->action = tree_conflicted ? svn_wc_notify_tree_conflict : action;
      dpn->state = state;
      dpn->tree_conflicted = tree_conflicted;
      apr_hash_set(eb->deleted_paths, deleted_path, APR_HASH_KEY_STRING, dpn);
    }

  svn_pool_destroy(scratch_pool);

  return SVN_NO_ERROR;
}
/* ### TODO: Handle depth. */
static svn_error_t *
diff_deleted_dir(const char *dir,
                 svn_revnum_t revision,
                 svn_ra_session_t *ra_session,
                 void *edit_baton,
                 svn_cancel_func_t cancel_func,
                 void *cancel_baton,
                 apr_pool_t *pool)
{
  struct edit_baton *eb = edit_baton;
  apr_hash_t *dirents;
  apr_pool_t *iterpool = svn_pool_create(pool);
  apr_hash_index_t *hi;

  if (cancel_func)
    SVN_ERR(cancel_func(cancel_baton));

  SVN_ERR(svn_ra_get_dir2(ra_session,
                          &dirents,
                          NULL, NULL,
                          dir,
                          revision,
                          SVN_DIRENT_KIND,
                          pool));

  for (hi = apr_hash_first(pool, dirents); hi;
       hi = apr_hash_next(hi))
    {
      const char *path;
      const char *name = svn__apr_hash_index_key(hi);
      svn_dirent_t *dirent = svn__apr_hash_index_val(hi);
      svn_node_kind_t kind;
      svn_client_diff_summarize_t *sum;

      svn_pool_clear(iterpool);

      path = svn_relpath_join(dir, name, iterpool);

      SVN_ERR(svn_ra_check_path(eb->ra_session,
                                path,
                                eb->revision,
                                &kind,
                                iterpool));

      sum = apr_pcalloc(iterpool, sizeof(*sum));
      sum->summarize_kind = svn_client_diff_summarize_kind_deleted;
      sum->path = path;
      sum->node_kind = kind;

      SVN_ERR(eb->summarize_func(sum,
                                 eb->summarize_func_baton,
                                 iterpool));

      if (dirent->kind == svn_node_dir)
        SVN_ERR(diff_deleted_dir(path,
                                 revision,
                                 ra_session,
                                 eb,
                                 cancel_func,
                                 cancel_baton,
                                 iterpool));
    }

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}
Beispiel #4
0
/* ### TODO: Handle depth. */
static svn_error_t *
diff_deleted_dir(svn_wc_notify_state_t *state_p,
                 svn_boolean_t *tree_conflicted_p,
                 const char *dir,
                 struct edit_baton *eb,
                 apr_pool_t *pool)
{
  apr_hash_t *dirents;
  apr_pool_t *iterpool = svn_pool_create(pool);
  apr_hash_index_t *hi;

  SVN_ERR_ASSERT(SVN_IS_VALID_REVNUM(eb->revision));

  if (eb->cancel_func)
    SVN_ERR(eb->cancel_func(eb->cancel_baton));

  SVN_ERR(eb->diff_callbacks->dir_deleted(
                        state_p, tree_conflicted_p, dir,
                        eb->diff_cmd_baton, pool));

  /* The "old" dir will be skipped by the repository report.  If required,
   * crawl it recursively, diffing each file against the empty file.  This
   * is a workaround for issue 2333 "'svn diff URL1 URL2' not reverse of
   * 'svn diff URL2 URL1'". */
  if (! eb->walk_deleted_repos_dirs)
    {
      svn_pool_destroy(iterpool);
      return SVN_NO_ERROR;
    }

  SVN_ERR(svn_ra_get_dir2(eb->ra_session,
                          &dirents,
                          NULL, NULL,
                          dir,
                          eb->revision,
                          SVN_DIRENT_KIND,
                          pool));

  for (hi = apr_hash_first(pool, dirents); hi;
       hi = apr_hash_next(hi))
    {
      const char *path;
      const char *name = svn__apr_hash_index_key(hi);
      svn_dirent_t *dirent = svn__apr_hash_index_val(hi);

      svn_pool_clear(iterpool);

      path = svn_relpath_join(dir, name, iterpool);

      if (dirent->kind == svn_node_file)
        {
          SVN_ERR(diff_deleted_file(NULL, NULL, path, eb, iterpool));
        }

      if (dirent->kind == svn_node_dir)
        {
          SVN_ERR(diff_deleted_dir(NULL, NULL, path, eb, iterpool));
        }
    }

  svn_pool_destroy(iterpool);
  return SVN_NO_ERROR;
}