📄 log.c
字号:
/* log.c --- retrieving log messages
*
* ====================================================================
* Copyright (c) 2000-2004 CollabNet. All rights reserved.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at http://subversion.tigris.org/license-1.html.
* If newer versions of this license are posted there, you may use a
* newer version instead, at your option.
*
* This software consists of voluntary contributions made by many
* individuals. For exact contribution history, see the revision
* history and logs, available at http://subversion.tigris.org/.
* ====================================================================
*/
#define APR_WANT_STRFUNC
#include <apr_want.h>
#include "svn_private_config.h"
#include "svn_pools.h"
#include "svn_error.h"
#include "svn_path.h"
#include "svn_fs.h"
#include "svn_repos.h"
#include "svn_string.h"
#include "svn_time.h"
#include "svn_sorts.h"
#include "repos.h"
/* Store as keys in CHANGED the paths of all node in ROOT that show a
* significant change. "Significant" means that the text or
* properties of the node were changed, or that the node was added or
* deleted.
*
* The CHANGED hash set and the key are allocated in POOL;
* the value is (void *) 'U', 'A', 'D', or 'R', for modified, added,
* deleted, or replaced, respectively.
*
* If optional AUTHZ_READ_FUNC is non-NULL, then use it (with
* AUTHZ_READ_BATON and FS) to check whether each changed-path (and
* copyfrom_path) is readable:
*
* - If some paths are readable and some are not, then silently
* omit the unreadable paths from the CHANGED hash, and return
* SVN_ERR_AUTHZ_PARTIALLY_READABLE.
*
* - If absolutely every changed-path (and copyfrom_path) is
* unreadable, then return an empty CHANGED hash and
* SVN_ERR_AUTHZ_UNREADABLE. (This is to distinguish a revision
* which truly has no changed paths from a revision in which all
* paths are unreadable.)
*/
static svn_error_t *
detect_changed (apr_hash_t **changed,
svn_fs_root_t *root,
svn_fs_t *fs,
svn_repos_authz_func_t authz_read_func,
void *authz_read_baton,
apr_pool_t *pool)
{
apr_hash_t *changes;
apr_hash_index_t *hi;
apr_pool_t *subpool = svn_pool_create (pool);
svn_boolean_t found_readable = FALSE;
svn_boolean_t found_unreadable = FALSE;
*changed = apr_hash_make (pool);
SVN_ERR (svn_fs_paths_changed (&changes, root, pool));
if (apr_hash_count (changes) == 0)
/* No paths changed in this revision? Uh, sure, I guess the
revision is readable, then. */
return SVN_NO_ERROR;
for (hi = apr_hash_first (pool, changes); hi; hi = apr_hash_next (hi))
{
const void *key;
void *val;
svn_fs_path_change_t *change;
const char *path;
char action;
svn_log_changed_path_t *item;
svn_pool_clear (subpool);
/* KEY will be the path, VAL the change. */
apr_hash_this (hi, &key, NULL, &val);
path = (const char *) key;
change = val;
/* Skip path if unreadable. */
if (authz_read_func)
{
svn_boolean_t readable;
SVN_ERR (authz_read_func (&readable,
root, path,
authz_read_baton, subpool));
if (! readable)
{
found_unreadable = TRUE;
continue;
}
}
/* At least one changed-path was readable. */
found_readable = TRUE;
switch (change->change_kind)
{
case svn_fs_path_change_reset:
continue;
case svn_fs_path_change_add:
action = 'A';
break;
case svn_fs_path_change_replace:
action = 'R';
break;
case svn_fs_path_change_delete:
action = 'D';
break;
case svn_fs_path_change_modify:
default:
action = 'M';
break;
}
item = apr_pcalloc (pool, sizeof (*item));
item->action = action;
item->copyfrom_rev = SVN_INVALID_REVNUM;
if ((action == 'A') || (action == 'R'))
{
const char *copyfrom_path;
svn_revnum_t copyfrom_rev;
SVN_ERR (svn_fs_copied_from (©from_rev, ©from_path,
root, path, subpool));
if (copyfrom_path && SVN_IS_VALID_REVNUM (copyfrom_rev))
{
svn_boolean_t readable = TRUE;
if (authz_read_func)
{
svn_fs_root_t *copyfrom_root;
SVN_ERR (svn_fs_revision_root (©from_root, fs,
copyfrom_rev, subpool));
SVN_ERR (authz_read_func (&readable,
copyfrom_root, copyfrom_path,
authz_read_baton, subpool));
if (! readable)
found_unreadable = TRUE;
}
if (readable)
{
item->copyfrom_path = apr_pstrdup (pool, copyfrom_path);
item->copyfrom_rev = copyfrom_rev;
}
}
}
apr_hash_set (*changed, apr_pstrdup (pool, path),
APR_HASH_KEY_STRING, item);
}
svn_pool_destroy (subpool);
if (! found_readable)
/* Every changed-path was unreadable. */
return svn_error_create (SVN_ERR_AUTHZ_UNREADABLE,
NULL, NULL);
if (found_unreadable)
/* At least one changed-path was unreadable. */
return svn_error_create (SVN_ERR_AUTHZ_PARTIALLY_READABLE,
NULL, NULL);
/* Every changed-path was readable. */
return SVN_NO_ERROR;
}
/* Implements svn_repos_history_func_t interface. Accumulate history
revisions in the apr_array_header_t * which is the BATON. */
static svn_error_t *
history_to_revs_array (void *baton,
const char *path,
svn_revnum_t revision,
apr_pool_t *pool)
{
apr_array_header_t *revs_array = baton;
APR_ARRAY_PUSH (revs_array, svn_revnum_t) = revision;
return SVN_NO_ERROR;
}
svn_error_t *
svn_repos_get_logs2 (svn_repos_t *repos,
const apr_array_header_t *paths,
svn_revnum_t start,
svn_revnum_t end,
svn_boolean_t discover_changed_paths,
svn_boolean_t strict_node_history,
svn_repos_authz_func_t authz_read_func,
void *authz_read_baton,
svn_log_message_receiver_t receiver,
void *receiver_baton,
apr_pool_t *pool)
{
svn_revnum_t this_rev, head = SVN_INVALID_REVNUM;
apr_pool_t *subpool = svn_pool_create (pool);
svn_fs_t *fs = repos->fs;
apr_array_header_t *revs = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -