示例#1
0
svn_error_t *
svn_fs_paths_changed(apr_hash_t **changed_paths_p, svn_fs_root_t *root,
                     apr_pool_t *pool)
{
  apr_hash_t *changed_paths_new_structs;
  apr_hash_index_t *hi;

  SVN_ERR(svn_fs_paths_changed2(&changed_paths_new_structs, root, pool));
  *changed_paths_p = apr_hash_make(pool);
  for (hi = apr_hash_first(pool, changed_paths_new_structs);
       hi;
       hi = apr_hash_next(hi))
    {
      const void *vkey;
      apr_ssize_t klen;
      void *vval;
      svn_fs_path_change2_t *val;
      svn_fs_path_change_t *change;
      apr_hash_this(hi, &vkey, &klen, &vval);
      val = vval;
      change = apr_palloc(pool, sizeof(*change));
      change->node_rev_id = val->node_rev_id;
      change->change_kind = val->change_kind;
      change->text_mod = val->text_mod;
      change->prop_mod = val->prop_mod;
      apr_hash_set(*changed_paths_p, vkey, klen, change);
    }
  return SVN_NO_ERROR;
}
示例#2
0
static PyObject *fs_root_paths_changed(FileSystemRootObject *self)
{
	apr_pool_t *temp_pool;
	apr_hash_t *changed_paths;
	const char *key;
	apr_ssize_t klen;
	apr_hash_index_t *idx;
	PyObject *ret;
	temp_pool = Pool(NULL);
	if (temp_pool == NULL)
		return NULL;
#if ONLY_SINCE_SVN(1, 6)
	RUN_SVN_WITH_POOL(temp_pool,
					  svn_fs_paths_changed2(&changed_paths, self->root, temp_pool));
#else
	RUN_SVN_WITH_POOL(temp_pool,
					  svn_fs_paths_changed(&changed_paths, self->root, temp_pool));
#endif
	ret = PyDict_New();
	if (ret == NULL) {
		apr_pool_destroy(temp_pool);
		return NULL;
	}

	for (idx = apr_hash_first(temp_pool, changed_paths); idx != NULL;
		 idx = apr_hash_next(idx)) {
		PyObject *py_val;
#if ONLY_SINCE_SVN(1, 6)
		svn_fs_path_change2_t *val;
#else
		svn_fs_path_change_t *val;
#endif
		apr_hash_this(idx, (const void **)&key, &klen, (void **)&val);
#if ONLY_SINCE_SVN(1, 6)
		py_val = py_fs_path_change2(val);
#else
		py_val = py_fs_path_change(val);
#endif
		if (py_val == NULL) {
			apr_pool_destroy(temp_pool);
			PyObject_Del(ret);
			return NULL;
		}
		if (PyDict_SetItemString(ret, key, py_val) != 0) {
			apr_pool_destroy(temp_pool);
			PyObject_Del(ret);
			Py_DECREF(py_val);
			return NULL;
		}

		Py_DECREF(py_val);
	}
	apr_pool_destroy(temp_pool);
	return ret;
}
/* Build the node-origins index any newly added items introduced in
   REVISION in FS.  Set *COUNT to the number of new items found.  */
static svn_error_t *
index_revision_adds(int *count, svn_fs_t *fs,
                    svn_revnum_t revision, apr_pool_t *pool)
{
  svn_fs_root_t *root;
  apr_hash_t *changes;
  apr_hash_index_t *hi;
  apr_pool_t *subpool;

  *count = 0;
  SVN_ERR(svn_fs_revision_root(&root, fs, revision, pool));
  SVN_ERR(svn_fs_paths_changed2(&changes, root, pool));

  /* No paths changed in this revision?  Nothing to do.  */
  if (apr_hash_count(changes) == 0)
    return SVN_NO_ERROR;

  subpool = svn_pool_create(pool);
  for (hi = apr_hash_first(pool, changes); hi; hi = apr_hash_next(hi))
    {
      const void *path;
      void *val;
      svn_fs_path_change2_t *change;

      svn_pool_clear(subpool);
      apr_hash_this(hi, &path, NULL, &val);
      change = val;
      if ((change->change_kind == svn_fs_path_change_add)
          || (change->change_kind == svn_fs_path_change_replace))
        {
          if (! (change->copyfrom_path
                            && SVN_IS_VALID_REVNUM(change->copyfrom_rev)))
            {
              svn_revnum_t origin;
              SVN_ERR(svn_fs_node_origin_rev(&origin, root, path, subpool));
              (*count)++;
            }
        }
    }
  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}
示例#4
0
static svn_error_t *
do_resources(const dav_svn_repos *repos,
             svn_fs_root_t *root,
             svn_revnum_t revision,
             ap_filter_t *output,
             apr_bucket_brigade *bb,
             apr_pool_t *pool)
{
  apr_hash_t *changes;
  apr_hash_t *sent = apr_hash_make(pool);
  apr_hash_index_t *hi;
  apr_pool_t *subpool = svn_pool_create(pool);

  /* Fetch the paths changed in this revision.  This will contain
     everything except otherwise-unchanged parent directories of added
     and deleted things.  Also, note that deleted things don't merit
     responses of their own -- they are considered modifications to
     their parent.  */
  SVN_ERR(svn_fs_paths_changed2(&changes, root, pool));

  for (hi = apr_hash_first(pool, changes); hi; hi = apr_hash_next(hi))
    {
      const void *key;
      void *val;
      const char *path;
      svn_fs_path_change2_t *change;
      svn_boolean_t send_self;
      svn_boolean_t send_parent;

      svn_pool_clear(subpool);
      apr_hash_this(hi, &key, NULL, &val);
      path = key;
      change = val;

      /* Figure out who needs to get sent. */
      switch (change->change_kind)
        {
        case svn_fs_path_change_delete:
          send_self = FALSE;
          send_parent = TRUE;
          break;

        case svn_fs_path_change_add:
        case svn_fs_path_change_replace:
          send_self = TRUE;
          send_parent = TRUE;
          break;

        case svn_fs_path_change_modify:
        default:
          send_self = TRUE;
          send_parent = FALSE;
          break;
        }

      if (send_self)
        {
          /* If we haven't already sent this path, send it (and then
             remember that we sent it). */
          if (! apr_hash_get(sent, path, APR_HASH_KEY_STRING))
            {
              svn_node_kind_t kind;
              SVN_ERR(svn_fs_check_path(&kind, root, path, subpool));
              SVN_ERR(send_response(repos, root, path,
                                    kind == svn_node_dir,
                                    output, bb, subpool));
              apr_hash_set(sent, path, APR_HASH_KEY_STRING, (void *)1);
            }
        }
      if (send_parent)
        {
          /* If it hasn't already been sent, send the parent directory
             (and then remember that you sent it).  Allocate parent in
             pool, not subpool, because it stays in the sent hash
             afterwards. */
          const char *parent = svn_path_dirname(path, pool);
          if (! apr_hash_get(sent, parent, APR_HASH_KEY_STRING))
            {
              SVN_ERR(send_response(repos, root, parent,
                                    TRUE, output, bb, subpool));
              apr_hash_set(sent, parent, APR_HASH_KEY_STRING, (void *)1);
            }
        }
    }

  svn_pool_destroy(subpool);

  return SVN_NO_ERROR;
}
示例#5
0
/* Inspect the data and/or prop reps of revision REVNUM in FS.  Store
 * reference count tallies in passed hashes (allocated in RESULT_POOL).
 *
 * If PROP_REPS or DATA_REPS is NULL, the respective kind of reps are not
 * tallied.
 *
 * Print progress report to STDERR unless QUIET is true.
 *
 * Use SCRATCH_POOL for temporary allocations.
 */
static svn_error_t *
process_one_revision(svn_fs_t *fs,
                     svn_revnum_t revnum,
                     svn_boolean_t quiet,
                     apr_hash_t *prop_reps,
                     apr_hash_t *data_reps,
                     apr_hash_t *both_reps,
                     apr_pool_t *result_pool,
                     apr_pool_t *scratch_pool)
{
  svn_fs_root_t *rev_root;
  apr_hash_t *paths_changed;
  apr_hash_index_t *hi;

  if (! quiet)
    SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
                                "processing r%ld\n", revnum));

  /* Get the changed paths. */
  SVN_ERR(svn_fs_revision_root(&rev_root, fs, revnum, scratch_pool));
  SVN_ERR(svn_fs_paths_changed2(&paths_changed, rev_root, scratch_pool));

  /* Iterate them. */
  /* ### use iterpool? */
  for (hi = apr_hash_first(scratch_pool, paths_changed);
       hi; hi = apr_hash_next(hi))
    {
      const char *path;
      const svn_fs_path_change2_t *change;
      const svn_fs_id_t *node_rev_id1, *node_rev_id2;
      const svn_fs_id_t *the_id;

      node_revision_t *node_rev;

      path = svn__apr_hash_index_key(hi);
      change = svn__apr_hash_index_val(hi);
      if (! quiet)
        SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool,
                                    "processing r%ld:%s\n", revnum, path));

      if (change->change_kind == svn_fs_path_change_delete)
        /* Can't ask for reps of PATH at REVNUM if the path no longer exists
         * at that revision! */
        continue;

      /* Okay, we have two node_rev id's for this change: the txn one and
       * the revision one.  We'll use the latter. */
      node_rev_id1 = change->node_rev_id;
      SVN_ERR(svn_fs_node_id(&node_rev_id2, rev_root, path, scratch_pool));

      SVN_ERR_ASSERT(svn_fs_fs__id_txn_id(node_rev_id1) != NULL);
      SVN_ERR_ASSERT(svn_fs_fs__id_rev(node_rev_id2) != SVN_INVALID_REVNUM);

      the_id = node_rev_id2;

      /* Get the node_rev using the chosen node_rev_id. */
      SVN_ERR(svn_fs_fs__get_node_revision(&node_rev, fs, the_id, scratch_pool));

      /* Maybe record the sha1's. */
      SVN_ERR(record(prop_reps, node_rev->prop_rep, result_pool));
      SVN_ERR(record(data_reps, node_rev->data_rep, result_pool));
      SVN_ERR(record(both_reps, node_rev->prop_rep, result_pool));
      SVN_ERR(record(both_reps, node_rev->data_rep, result_pool));
    }

  return SVN_NO_ERROR;
}