📄 status.c
字号:
because it is the root of the edit drive. */
SVN_ERR (handle_statii (eb, eb->anchor_status->entry, db->path,
db->statii, FALSE, eb->descend, pool));
if (is_sendable_status (eb->anchor_status, eb))
(eb->status_func) (eb->status_baton, db->path, eb->anchor_status);
eb->anchor_status = NULL;
}
}
return SVN_NO_ERROR;
}
static svn_error_t *
add_file (const char *path,
void *parent_baton,
const char *copyfrom_path,
svn_revnum_t copyfrom_revision,
apr_pool_t *pool,
void **file_baton)
{
struct dir_baton *pb = parent_baton;
struct file_baton *new_fb = make_file_baton (pb, path, pool);
/* Mark parent dir as changed */
pb->text_changed = TRUE;
/* Make this file as added. */
new_fb->added = TRUE;
*file_baton = new_fb;
return SVN_NO_ERROR;
}
static svn_error_t *
open_file (const char *path,
void *parent_baton,
svn_revnum_t base_revision,
apr_pool_t *pool,
void **file_baton)
{
struct dir_baton *pb = parent_baton;
struct file_baton *new_fb = make_file_baton (pb, path, pool);
*file_baton = new_fb;
return SVN_NO_ERROR;
}
static svn_error_t *
apply_textdelta (void *file_baton,
const char *base_checksum,
apr_pool_t *pool,
svn_txdelta_window_handler_t *handler,
void **handler_baton)
{
struct file_baton *fb = file_baton;
/* Mark file as having textual mods. */
fb->text_changed = TRUE;
/* Send back a NULL window handler -- we don't need the actual diffs. */
*handler_baton = NULL;
*handler = svn_delta_noop_window_handler;
return SVN_NO_ERROR;
}
static svn_error_t *
change_file_prop (void *file_baton,
const char *name,
const svn_string_t *value,
apr_pool_t *pool)
{
struct file_baton *fb = file_baton;
if (svn_wc_is_normal_prop (name))
fb->prop_changed = TRUE;
return SVN_NO_ERROR;
}
static svn_error_t *
close_file (void *file_baton,
const char *text_checksum, /* ignored, as we receive no data */
apr_pool_t *pool)
{
struct file_baton *fb = file_baton;
enum svn_wc_status_kind repos_text_status;
enum svn_wc_status_kind repos_prop_status;
/* If nothing has changed, return. */
if (! (fb->added || fb->prop_changed || fb->text_changed))
return SVN_NO_ERROR;
/* If this is a new file, add it to the statushash. */
if (fb->added)
{
repos_text_status = svn_wc_status_added;
repos_prop_status = fb->prop_changed ? svn_wc_status_added : 0;
}
else
{
repos_text_status = fb->text_changed ? svn_wc_status_modified : 0;
repos_prop_status = fb->prop_changed ? svn_wc_status_modified : 0;
}
SVN_ERR (tweak_statushash (fb->dir_baton->statii,
fb->edit_baton->adm_access,
fb->path, FALSE,
repos_text_status,
repos_prop_status));
return SVN_NO_ERROR;
}
static svn_error_t *
close_edit (void *edit_baton,
apr_pool_t *pool)
{
struct edit_baton *eb = edit_baton;
apr_array_header_t *ignores = eb->ignores;
/* If we get here and the root was not opened as part of the edit,
we need to transmit statuses for everything. Otherwise, we
should be done. */
if (eb->root_opened)
goto cleanup;
/* If we have a target, that's the thing we're sending, otherwise
we're sending the anchor. */
if (*eb->target)
{
svn_node_kind_t kind;
const char *full_path = svn_path_join (eb->anchor, eb->target, pool);
SVN_ERR (svn_io_check_path (full_path, &kind, pool));
if (kind == svn_node_dir)
{
svn_wc_adm_access_t *tgt_access;
const svn_wc_entry_t *tgt_entry;
SVN_ERR (svn_wc_entry (&tgt_entry, full_path, eb->adm_access,
FALSE, pool));
if (! tgt_entry)
{
SVN_ERR (get_dir_status (eb, NULL, eb->adm_access, eb->target,
ignores, FALSE, eb->get_all, TRUE,
TRUE, eb->status_func, eb->status_baton,
eb->cancel_func, eb->cancel_baton,
pool));
}
else
{
SVN_ERR (svn_wc_adm_retrieve (&tgt_access, eb->adm_access,
full_path, pool));
SVN_ERR (get_dir_status (eb, NULL, tgt_access, NULL, ignores,
eb->descend, eb->get_all,
eb->no_ignore, FALSE,
eb->status_func, eb->status_baton,
eb->cancel_func, eb->cancel_baton,
pool));
}
}
else
{
SVN_ERR (get_dir_status (eb, NULL, eb->adm_access, eb->target,
ignores, FALSE, eb->get_all, TRUE,
TRUE, eb->status_func, eb->status_baton,
eb->cancel_func, eb->cancel_baton, pool));
}
}
else
{
SVN_ERR (get_dir_status (eb, NULL, eb->adm_access, NULL, ignores,
eb->descend, eb->get_all, eb->no_ignore,
FALSE, eb->status_func, eb->status_baton,
eb->cancel_func, eb->cancel_baton, pool));
}
cleanup:
/* Let's make sure that we didn't harvest any traversal info for the
anchor if we had a target. */
if (*eb->target)
{
apr_hash_set (eb->traversal_info->externals_old,
eb->anchor, APR_HASH_KEY_STRING, NULL);
apr_hash_set (eb->traversal_info->externals_new,
eb->anchor, APR_HASH_KEY_STRING, NULL);
}
return SVN_NO_ERROR;
}
/*** Public API ***/
svn_error_t *
svn_wc_get_status_editor (const svn_delta_editor_t **editor,
void **edit_baton,
svn_revnum_t *edit_revision,
svn_wc_adm_access_t *anchor,
const char *target,
apr_hash_t *config,
svn_boolean_t descend,
svn_boolean_t get_all,
svn_boolean_t no_ignore,
svn_wc_status_func_t status_func,
void *status_baton,
svn_cancel_func_t cancel_func,
void *cancel_baton,
svn_wc_traversal_info_t *traversal_info,
apr_pool_t *pool)
{
struct edit_baton *eb;
svn_delta_editor_t *tree_editor = svn_delta_default_editor (pool);
/* Construct an edit baton. */
eb = apr_palloc (pool, sizeof (*eb));
eb->descend = descend;
eb->target_revision = edit_revision;
eb->adm_access = anchor;
eb->config = config;
eb->get_all = get_all;
eb->no_ignore = no_ignore;
eb->status_func = status_func;
eb->status_baton = status_baton;
eb->cancel_func = cancel_func;
eb->cancel_baton = cancel_baton;
eb->traversal_info = traversal_info;
eb->externals = traversal_info
? apr_hash_make (traversal_info->pool)
: NULL;
eb->anchor = svn_wc_adm_access_path (anchor);
eb->target = target;
eb->root_opened = FALSE;
/* The edit baton's status structure maps to PATH, and the editor
have to be aware of whether that is the anchor or the target. */
SVN_ERR (svn_wc_status (&(eb->anchor_status), eb->anchor, anchor, pool));
/* Get the set of default ignores. */
SVN_ERR (svn_wc_get_default_ignores (&(eb->ignores), eb->config, pool));
/* Construct an editor. */
tree_editor->set_target_revision = set_target_revision;
tree_editor->open_root = open_root;
tree_editor->delete_entry = delete_entry;
tree_editor->add_directory = add_directory;
tree_editor->open_directory = open_directory;
tree_editor->change_dir_prop = change_dir_prop;
tree_editor->close_directory = close_directory;
tree_editor->add_file = add_file;
tree_editor->open_file = open_file;
tree_editor->apply_textdelta = apply_textdelta;
tree_editor->change_file_prop = change_file_prop;
tree_editor->close_file = close_file;
tree_editor->close_edit = close_edit;
/* Conjoin a cancellation editor with our status editor. */
SVN_ERR (svn_delta_get_cancellation_editor (cancel_func, cancel_baton,
tree_editor, eb, editor,
edit_baton, pool));
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc_get_default_ignores (apr_array_header_t **patterns,
apr_hash_t *config,
apr_pool_t *pool)
{
svn_config_t *cfg = config ? apr_hash_get (config,
SVN_CONFIG_CATEGORY_CONFIG,
APR_HASH_KEY_STRING) : NULL;
const char *val;
/* Check the Subversion run-time configuration for global ignores.
If no configuration value exists, we fall back to our defaults. */
svn_config_get (cfg, &val, SVN_CONFIG_SECTION_MISCELLANY,
SVN_CONFIG_OPTION_GLOBAL_IGNORES,
SVN_CONFIG_DEFAULT_GLOBAL_IGNORES);
*patterns = apr_array_make (pool, 16, sizeof (const char *));
/* Split the patterns on whitespace, and stuff them into *PATTERNS. */
svn_cstring_split_append (*patterns, val, "\n\r\t\v ", FALSE, pool);
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc_status (svn_wc_status_t **status,
const char *path,
svn_wc_adm_access_t *adm_access,
apr_pool_t *pool)
{
const svn_wc_entry_t *entry = NULL;
const svn_wc_entry_t *parent_entry = NULL;
if (adm_access)
SVN_ERR (svn_wc_entry (&entry, path, adm_access, FALSE, pool));
/* If we have an entry, and PATH is not a root, then we need a parent
entry */
if (entry)
{
svn_boolean_t is_root;
SVN_ERR (svn_wc_is_wc_root (&is_root, path, adm_access, pool));
if (! is_root)
{
const char *parent_path = svn_path_dirname (path, pool);
svn_wc_adm_access_t *parent_access;
SVN_ERR (svn_wc_adm_open2 (&parent_access, NULL, parent_path,
FALSE, 0, pool));
SVN_ERR (svn_wc_entry (&parent_entry, parent_path, parent_access,
FALSE, pool));
}
}
SVN_ERR (assemble_status (status, path, adm_access, entry, parent_entry,
svn_node_unknown, TRUE, FALSE, pool));
return SVN_NO_ERROR;
}
svn_wc_status_t *
svn_wc_dup_status (svn_wc_status_t *orig_stat,
apr_pool_t *pool)
{
svn_wc_status_t *new_stat = apr_palloc (pool, sizeof (*new_stat));
/* Shallow copy all members. */
*new_stat = *orig_stat;
/* No go back and dup the deep item. */
if (orig_stat->entry)
new_stat->entry = svn_wc_entry_dup (orig_stat->entry, pool);
/* Return the new hotness. */
return new_stat;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -