📄 status.c
字号:
be in the prop_status field at this point.*/
if (entry->schedule == svn_wc_schedule_add)
{
final_text_status = svn_wc_status_added;
final_prop_status = svn_wc_status_none;
}
else if (entry->schedule == svn_wc_schedule_replace)
{
final_text_status = svn_wc_status_replaced;
final_prop_status = svn_wc_status_none;
}
else if (entry->schedule == svn_wc_schedule_delete)
{
final_text_status = svn_wc_status_deleted;
final_prop_status = svn_wc_status_none;
}
/* 3. Highest precedence:
a. check to see if file or dir is just missing, or
incomplete. This overrides every possible state
*except* deletion. (If something is deleted or
scheduled for it, we don't care if the working file
exists.)
b. check to see if the file or dir is present in the
file system as the same kind it was versioned as.
4. Check for locked directory (only for directories). */
if (entry->incomplete
&& (final_text_status != svn_wc_status_deleted)
&& (final_text_status != svn_wc_status_added))
{
final_text_status = svn_wc_status_incomplete;
}
else if (path_kind == svn_node_none)
{
if (final_text_status != svn_wc_status_deleted)
final_text_status = svn_wc_status_missing;
}
else if (path_kind != entry->kind)
final_text_status = svn_wc_status_obstructed;
else if (((! wc_special) && (node_special))
#ifdef HAVE_SYMLINK
|| (wc_special && (! node_special))
#endif /* HAVE_SYMLINK */
)
final_text_status = svn_wc_status_obstructed;
if (path_kind == svn_node_dir && entry->kind == svn_node_dir)
SVN_ERR (svn_wc_locked (&locked_p, path, pool));
}
/* 5. Easy out: unless we're fetching -every- entry, don't bother
to allocate a struct for an uninteresting entry. */
if (! get_all)
if (((final_text_status == svn_wc_status_none)
|| (final_text_status == svn_wc_status_normal))
&& ((final_prop_status == svn_wc_status_none)
|| (final_prop_status == svn_wc_status_normal))
&& (! locked_p) && (! switched_p))
{
*status = NULL;
return SVN_NO_ERROR;
}
/* 6. Build and return a status structure. */
stat = apr_pcalloc (pool, sizeof(**status));
stat->entry = svn_wc_entry_dup (entry, pool);
stat->text_status = final_text_status;
stat->prop_status = final_prop_status;
stat->repos_text_status = svn_wc_status_none; /* default */
stat->repos_prop_status = svn_wc_status_none; /* default */
stat->locked = locked_p;
stat->switched = switched_p;
stat->copied = entry->copied;
*status = stat;
return SVN_NO_ERROR;
}
/* Given an ENTRY object representing PATH, build a status structure
and pass it off to the STATUS_FUNC/STATUS_BATON. All other
arguments are the same as those passed to assemble_status(). */
static svn_error_t *
send_status_structure (const char *path,
svn_wc_adm_access_t *adm_access,
const svn_wc_entry_t *entry,
const svn_wc_entry_t *parent_entry,
svn_node_kind_t path_kind,
svn_boolean_t get_all,
svn_boolean_t is_ignored,
svn_wc_status_func_t status_func,
void *status_baton,
apr_pool_t *pool)
{
svn_wc_status_t *statstruct;
SVN_ERR (assemble_status (&statstruct, path, adm_access, entry, parent_entry,
path_kind, get_all, is_ignored, pool));
if (statstruct && (status_func))
(*status_func) (status_baton, path, statstruct);
return SVN_NO_ERROR;
}
/* Store in PATTERNS a list of all svn:ignore properties from
the working copy directory, including the default ignores
passed in as IGNORES.
Upon return, *PATTERNS will contain zero or more (const char *)
patterns from the value of the SVN_PROP_IGNORE property set on
the working directory path.
IGNORES is a list of patterns to include; typically this will
be the default ignores as, for example, specified in a config file.
ADM_ACCESS is an access baton for the working copy path.
Allocate everything in POOL.
None of the arguments may be NULL.
*/
static svn_error_t *
collect_ignore_patterns (apr_array_header_t *patterns,
apr_array_header_t *ignores,
svn_wc_adm_access_t *adm_access,
apr_pool_t *pool)
{
int i;
const svn_string_t *value;
/* Copy default ignores into the local PATTERNS array. */
for (i = 0; i < ignores->nelts; i++)
{
const char *ignore = APR_ARRAY_IDX (ignores, i, const char *);
APR_ARRAY_PUSH (patterns, const char *) = ignore;
}
/* Then add any svn:ignore globs to the PATTERNS array. */
SVN_ERR (svn_wc_prop_get (&value, SVN_PROP_IGNORE,
svn_wc_adm_access_path (adm_access), adm_access,
pool));
if (value != NULL)
svn_cstring_split_append (patterns, value->data, "\n\r", FALSE, pool);
return SVN_NO_ERROR;
}
/* Compare PATH with items in the EXTERNALS hash to see if PATH is the
drop location for, or an intermediate directory of the drop
location for, an externals definition. Use POOL for
scratchwork. */
static svn_boolean_t
is_external_path (apr_hash_t *externals,
const char *path,
apr_pool_t *pool)
{
apr_hash_index_t *hi;
/* First try: does the path exist as a key in the hash? */
if (apr_hash_get (externals, path, APR_HASH_KEY_STRING))
return TRUE;
/* Failing that, we need to check if any external is a child of
PATH. */
for (hi = apr_hash_first (pool, externals); hi; hi = apr_hash_next (hi))
{
const void *key;
apr_hash_this (hi, &key, NULL, NULL);
if (svn_path_is_child (path, key, pool))
return TRUE;
}
return FALSE;
}
/* Assuming that NAME is unversioned, send a status structure
for it through STATUS_FUNC/STATUS_BATON unless this path is being
ignored. This function should never be called on a versioned entry.
NAME is the basename of the unversioned file whose status is being
requested. PATH_KIND is the node kind of NAME as determined by the
caller. ADM_ACCESS is an access baton for the working copy path.
PATTERNS points to a list of filename patterns which are marked as
ignored. None of these parameter may be NULL. EXTERNALS is a hash
of known externals definitions for this status run.
If NO_IGNORE is non-zero, the item will be added regardless of
whether it is ignored; otherwise we will only add the item if it
does not match any of the patterns in PATTERNS.
Allocate everything in POOL.
*/
static svn_error_t *
send_unversioned_item (const char *name,
svn_node_kind_t path_kind,
svn_wc_adm_access_t *adm_access,
apr_array_header_t *patterns,
apr_hash_t *externals,
svn_boolean_t no_ignore,
svn_wc_status_func_t status_func,
void *status_baton,
apr_pool_t *pool)
{
int ignore_me = svn_cstring_match_glob_list (name, patterns);
const char *path = svn_path_join (svn_wc_adm_access_path (adm_access),
name, pool);
int is_external = is_external_path (externals, path, pool);
svn_wc_status_t *status;
/* If we aren't ignoring it, or if it's an externals path, create a
status structure for this dirent. */
if (no_ignore || (! ignore_me) || is_external)
{
SVN_ERR (assemble_status (&status, path, adm_access, NULL, NULL,
path_kind, FALSE, ignore_me, pool));
if (is_external)
status->text_status = svn_wc_status_external;
(status_func) (status_baton, path, status);
}
return SVN_NO_ERROR;
}
/* Prototype for untangling a tango-ing two-some. */
static svn_error_t *get_dir_status (struct edit_baton *eb,
const svn_wc_entry_t *parent_entry,
svn_wc_adm_access_t *adm_access,
const char *entry,
apr_array_header_t *ignores,
svn_boolean_t descend,
svn_boolean_t get_all,
svn_boolean_t no_ignore,
svn_boolean_t skip_this_dir,
svn_wc_status_func_t status_func,
void *status_baton,
svn_cancel_func_t cancel_func,
void *cancel_baton,
apr_pool_t *pool);
/* Handle NAME (whose entry is ENTRY) as a directory entry of the
directory represented by ADM_ACCESS (and whose entry is
DIR_ENTRY). All other arguments are the same as those passed to
get_dir_status(), the function for which this one is a helper. */
static svn_error_t *
handle_dir_entry (struct edit_baton *eb,
svn_wc_adm_access_t *adm_access,
const char *name,
const svn_wc_entry_t *dir_entry,
const svn_wc_entry_t *entry,
apr_array_header_t *ignores,
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,
apr_pool_t *pool)
{
const char *dirname = svn_wc_adm_access_path (adm_access);
const char *path = svn_path_join (dirname, name, pool);
svn_node_kind_t kind;
/* Get the entry's kind on disk. */
SVN_ERR (svn_io_check_path (path, &kind, pool));
if (kind == svn_node_dir)
{
/* Directory entries are incomplete. We must get their full
entry from their own THIS_DIR entry. svn_wc_entry does this
for us if it can.
Of course, if there has been a kind-changing replacement (for
example, there is an entry for a file 'foo', but 'foo' exists
as a *directory* on disk), we don't want to reach down into
that subdir to try to flesh out a "complete entry". */
const svn_wc_entry_t *full_entry = entry;
if (entry->kind == kind)
SVN_ERR (svn_wc_entry (&full_entry, path, adm_access, FALSE, pool));
/* Descend only if the subdirectory is a working copy directory
(and DESCEND is non-zero ofcourse) */
if (descend && (full_entry != entry))
{
svn_wc_adm_access_t *dir_access;
SVN_ERR (svn_wc_adm_retrieve (&dir_access, adm_access, path, pool));
SVN_ERR (get_dir_status (eb, dir_entry, dir_access, NULL, ignores,
descend, get_all, no_ignore, FALSE,
status_func, status_baton, cancel_func,
cancel_baton, pool));
}
else
{
SVN_ERR (send_status_structure (path, adm_access, full_entry,
dir_entry, kind, get_all, FALSE,
status_func, status_baton, pool));
}
}
else
{
/* File entries are ... just fine! */
SVN_ERR (send_status_structure (path, adm_access, entry, dir_entry,
kind, get_all, FALSE,
status_func, status_baton, pool));
}
return SVN_NO_ERROR;
}
/* Send svn_wc_status_t * structures for the directory ADM_ACCESS and
for all its entries through STATUS_FUNC/STATUS_BATON, or, if ENTRY
is non-NULL, only for that directory entry.
PARENT_ENTRY is the entry for the parent of the directory or NULL
if that directory is a working copy root.
If SKIP_THIS_DIR is TRUE (and ENTRY is NULL), the directory's own
status will not be reported. However, upon recursing, all subdirs
*will* be reported, regardless of this parameter's value.
Other arguments are the same as those passed to
svn_wc_get_status_editor(). */
static svn_error_t *
get_dir_status (struct edit_baton *eb,
const svn_wc_entry_t *parent_entry,
svn_wc_adm_access_t *adm_access,
const char *entry,
apr_array_header_t *ignores,
svn_boolean_t descend,
svn_boolean_t get_all,
svn_boolean_t no_ignore,
svn_boolean_t skip_this_dir,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -