⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reporter.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
                proplist_change_fn_t *change_fn,                void *object, apr_pool_t *pool){  svn_fs_root_t *s_root;  apr_hash_t *s_props, *t_props, *r_props;  apr_array_header_t *prop_diffs;  int i;  svn_revnum_t crev;  const char *uuid;  svn_string_t *cr_str, *cdate, *last_author;  svn_boolean_t changed;  const svn_prop_t *pc;  svn_lock_t *lock;  /* Fetch the created-rev and send entry props. */  SVN_ERR(svn_fs_node_created_rev(&crev, b->t_root, t_path, pool));  if (SVN_IS_VALID_REVNUM(crev))    {      /* Transmit the committed-rev. */      cr_str = svn_string_createf(pool, "%ld", crev);      SVN_ERR(change_fn(b, object,                        SVN_PROP_ENTRY_COMMITTED_REV, cr_str, pool));      SVN_ERR(svn_fs_revision_proplist(&r_props, b->repos->fs, crev, pool));      /* Transmit the committed-date. */      cdate = apr_hash_get(r_props, SVN_PROP_REVISION_DATE,                           APR_HASH_KEY_STRING);      if (cdate || s_path)        SVN_ERR(change_fn(b, object, SVN_PROP_ENTRY_COMMITTED_DATE,                           cdate, pool));      /* Transmit the last-author. */      last_author = apr_hash_get(r_props, SVN_PROP_REVISION_AUTHOR,                                 APR_HASH_KEY_STRING);      if (last_author || s_path)        SVN_ERR(change_fn(b, object, SVN_PROP_ENTRY_LAST_AUTHOR,                          last_author, pool));      /* Transmit the UUID. */      SVN_ERR(svn_fs_get_uuid(b->repos->fs, &uuid, pool));      if (uuid || s_path)        SVN_ERR(change_fn(b, object, SVN_PROP_ENTRY_UUID,                          svn_string_create(uuid, pool), pool));    }  /* Update lock properties. */  if (lock_token)    {      SVN_ERR(svn_fs_get_lock(&lock, b->repos->fs, t_path, pool));      /* Delete a defunct lock. */      if (! lock || strcmp(lock_token, lock->token) != 0)        SVN_ERR(change_fn(b, object, SVN_PROP_ENTRY_LOCK_TOKEN,                          NULL, pool));    }  if (s_path)    {      SVN_ERR(get_source_root(b, &s_root, s_rev));      /* Is this deltification worth our time? */      SVN_ERR(svn_fs_props_changed(&changed, b->t_root, t_path, s_root,                                   s_path, pool));      if (! changed)        return SVN_NO_ERROR;      /* If so, go ahead and get the source path's properties. */      SVN_ERR(svn_fs_node_proplist(&s_props, s_root, s_path, pool));    }  else    s_props = apr_hash_make(pool);  /* Get the target path's properties */  SVN_ERR(svn_fs_node_proplist(&t_props, b->t_root, t_path, pool));  /* Now transmit the differences. */  SVN_ERR(svn_prop_diffs(&prop_diffs, t_props, s_props, pool));  for (i = 0; i < prop_diffs->nelts; i++)    {      pc = &APR_ARRAY_IDX(prop_diffs, i, svn_prop_t);      SVN_ERR(change_fn(b, object, pc->name, pc->value, pool));    }  return SVN_NO_ERROR;}/* Make the appropriate edits on FILE_BATON to change its contents and   properties from those in S_REV/S_PATH to those in B->t_root/T_PATH,   possibly using LOCK_TOKEN to determine if the client's lock on the file   is defunct. */static svn_error_t *delta_files(report_baton_t *b, void *file_baton, svn_revnum_t s_rev,            const char *s_path, const char *t_path, const char *lock_token,            apr_pool_t *pool){  svn_boolean_t changed;  svn_fs_root_t *s_root = NULL;  svn_txdelta_stream_t *dstream = NULL;  unsigned char s_digest[APR_MD5_DIGESTSIZE];  const char *s_hex_digest = NULL;  svn_txdelta_window_handler_t dhandler;  void *dbaton;  /* Compare the files' property lists.  */  SVN_ERR(delta_proplists(b, s_rev, s_path, t_path, lock_token,                          change_file_prop, file_baton, pool));  if (s_path)    {      SVN_ERR(get_source_root(b, &s_root, s_rev));      /* Is this delta calculation worth our time?  If we are ignoring         ancestry, then our editor implementor isn't concerned by the         theoretical differences between "has contents which have not         changed with respect to" and "has the same actual contents         as".  We'll do everything we can to avoid transmitting even         an empty text-delta in that case.  */      if (b->ignore_ancestry)        SVN_ERR(svn_repos__compare_files(&changed, b->t_root, t_path,                                         s_root, s_path, pool));      else        SVN_ERR(svn_fs_contents_changed(&changed, b->t_root, t_path, s_root,                                        s_path, pool));      if (!changed)        return SVN_NO_ERROR;      SVN_ERR(svn_fs_file_md5_checksum(s_digest, s_root, s_path, pool));      s_hex_digest = svn_md5_digest_to_cstring(s_digest, pool);    }  /* Send the delta stream if desired, or just a NULL window if not. */  SVN_ERR(b->editor->apply_textdelta(file_baton, s_hex_digest, pool,                                     &dhandler, &dbaton));  if (b->text_deltas)    {      SVN_ERR(svn_fs_get_file_delta_stream(&dstream, s_root, s_path,                                           b->t_root, t_path, pool));      return svn_txdelta_send_txstream(dstream, dhandler, dbaton, pool);    }  else    return dhandler(NULL, dbaton);}/* Determine if the user is authorized to view B->t_root/PATH. */static svn_error_t *check_auth(report_baton_t *b, svn_boolean_t *allowed, const char *path,           apr_pool_t *pool){  if (b->authz_read_func)    return b->authz_read_func(allowed, b->t_root, path,                              b->authz_read_baton, pool);  *allowed = TRUE;  return SVN_NO_ERROR;}/* Create a dirent in *ENTRY for the given ROOT and PATH.  We use this to   replace the source or target dirent when a report pathinfo tells us to   change paths or revisions. */static svn_error_t *fake_dirent(const svn_fs_dirent_t **entry, svn_fs_root_t *root,            const char *path, apr_pool_t *pool){  svn_node_kind_t kind;  svn_fs_dirent_t *ent;  SVN_ERR(svn_fs_check_path(&kind, root, path, pool));  if (kind == svn_node_none)    *entry = NULL;  else    {      ent = apr_palloc(pool, sizeof(**entry));      ent->name = svn_path_basename(path, pool);      SVN_ERR(svn_fs_node_id(&ent->id, root, path, pool));      ent->kind = kind;      *entry = ent;    }  return SVN_NO_ERROR;}/* Emit a series of editing operations to transform a source entry to   a target entry.   S_REV and S_PATH specify the source entry.  S_ENTRY contains the   already-looked-up information about the node-revision existing at   that location.  S_PATH and S_ENTRY may be NULL if the entry does   not exist in the source.  S_PATH may be non-NULL and S_ENTRY may be   NULL if the caller expects INFO to modify the source to an existing   location.   B->t_root and T_PATH specify the target entry.  T_ENTRY contains   the already-looked-up information about the node-revision existing   at that location.  T_PATH and T_ENTRY may be NULL if the entry does   not exist in the target.   DIR_BATON and E_PATH contain the parameters which should be passed   to the editor calls--DIR_BATON for the parent directory baton and   E_PATH for the pathname.  (E_PATH is the anchor-relative working   copy pathname, which may differ from the source and target   pathnames if the report contains a link_path.)   INFO contains the report information for this working copy path, or   NULL if there is none.  This function will internally modify the   source and target entries as appropriate based on the report   information.   If RECURSE is not set, avoid operating on directories.  (Normally   RECURSE is simply taken from B->recurse, but drive() needs to force   us to recurse into the target even if that flag is not set.) */static svn_error_t *update_entry(report_baton_t *b, svn_revnum_t s_rev, const char *s_path,             const svn_fs_dirent_t *s_entry, const char *t_path,             const svn_fs_dirent_t *t_entry, void *dir_baton,             const char *e_path, path_info_t *info, svn_boolean_t recurse,             apr_pool_t *pool){  svn_fs_root_t *s_root;  svn_boolean_t allowed, related;  void *new_baton;  unsigned char digest[APR_MD5_DIGESTSIZE];  const char *hex_digest;  int distance;  /* For non-switch operations, follow link_path in the target. */  if (info && info->link_path && !b->is_switch)    {      t_path = info->link_path;      SVN_ERR(fake_dirent(&t_entry, b->t_root, t_path, pool));    }  if (info && !SVN_IS_VALID_REVNUM(info->rev))    {      /* Delete this entry in the source. */      s_path = NULL;      s_entry = NULL;    }  else if (info && s_path)    {      /* Follow the rev and possibly path in this entry. */      s_path = (info->link_path) ? info->link_path : s_path;      s_rev = info->rev;      SVN_ERR(get_source_root(b, &s_root, s_rev));      SVN_ERR(fake_dirent(&s_entry, s_root, s_path, pool));    }  /* Don't let the report carry us somewhere nonexistent. */  if (s_path && !s_entry)    return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL,                             _("Working copy path '%s' does not exist in "                               "repository"), e_path);  if (!recurse && ((s_entry && s_entry->kind == svn_node_dir)                   || (t_entry && t_entry->kind == svn_node_dir)))    return skip_path_info(b, e_path);  /* If the source and target both exist and are of the same kind,     then find out whether they're related.  If they're exactly the     same, then we don't have to do anything (unless the report has     changes to the source).  If we're ignoring ancestry, then any two     nodes of the same type are related enough for us. */  related = FALSE;  if (s_entry && t_entry && s_entry->kind == t_entry->kind)    {      distance = svn_fs_compare_ids(s_entry->id, t_entry->id);      if (distance == 0 && !any_path_info(b, e_path)          && (!info || (!info->start_empty && !info->lock_token)))        return SVN_NO_ERROR;      else if (distance != -1 || b->ignore_ancestry)        related = TRUE;    }  /* If there's a source and it's not related to the target, nuke it. */  if (s_entry && !related)    {      SVN_ERR(b->editor->delete_entry(e_path, SVN_INVALID_REVNUM, dir_baton,                                      pool));      s_path = NULL;    }  /* If there's no target, we have nothing more to do. */  if (!t_entry)    return skip_path_info(b, e_path);  /* Check if the user is authorized to find out about the target. */  SVN_ERR(check_auth(b, &allowed, t_path, pool));  if (!allowed)    {      if (t_entry->kind == svn_node_dir)        SVN_ERR(b->editor->absent_directory(e_path, dir_baton, pool));      else        SVN_ERR(b->editor->absent_file(e_path, dir_baton, pool));      return skip_path_info(b, e_path);    }  if (t_entry->kind == svn_node_dir)    {      if (related)        SVN_ERR(b->editor->open_directory(e_path, dir_baton, s_rev, pool,                                           &new_baton));      else        SVN_ERR(b->editor->add_directory(e_path, dir_baton, NULL,                                         SVN_INVALID_REVNUM, pool,                                         &new_baton));      SVN_ERR(delta_dirs(b, s_rev, s_path, t_path, new_baton, e_path,                         info ? info->start_empty : FALSE, pool));      return b->editor->close_directory(new_baton, pool);    }  else    {      if (related)        SVN_ERR(b->editor->open_file(e_path, dir_baton, s_rev, pool,                                     &new_baton));      else        SVN_ERR(b->editor->add_file(e_path, dir_baton, NULL,                                    SVN_INVALID_REVNUM, pool, &new_baton));      SVN_ERR(delta_files(b, new_baton, s_rev, s_path, t_path,                          info ? info->lock_token : NULL, pool));      SVN_ERR(svn_fs_file_md5_checksum(digest, b->t_root, t_path, pool));      hex_digest = svn_md5_digest_to_cstring(digest, pool);      return b->editor->close_file(new_baton, hex_digest, pool);    }}/* Emit edits within directory DIR_BATON (with corresponding path   E_PATH) with the changes from the directory S_REV/S_PATH to the   directory B->t_rev/T_PATH.  S_PATH may be NULL if the entry does   not exist in the source. */static svn_error_t *delta_dirs(report_baton_t *b, svn_revnum_t s_rev, const char *s_path,           const char *t_path, void *dir_baton, const char *e_path,           svn_boolean_t start_empty, apr_pool_t *pool){  svn_fs_root_t *s_root;  apr_hash_t *s_entries = NULL, *t_entries;  apr_hash_index_t *hi;  apr_pool_t *subpool;  const svn_fs_dirent_t *s_entry, *t_entry;  void *val;  const char *name, *s_fullpath, *t_fullpath, *e_fullpath;  path_info_t *info;  /* Compare the property lists.  If we're starting empty, pass a NULL     source path so that we add all the properties.          When we support directory locks, we must pass the lock token here. */  SVN_ERR(delta_proplists(b, s_rev, start_empty ? NULL : s_path, t_path,                          NULL, change_dir_prop, dir_baton, pool));  /* Get the list of entries in each of source and target. */  if (s_path && !start_empty)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -