📄 status.c
字号:
adm_access, pool)); if (text_modified_p) final_text_status = svn_wc_status_modified; if (prop_modified_p) final_prop_status = svn_wc_status_modified; if (entry->prejfile || entry->conflict_old || entry->conflict_new || entry->conflict_wrk) { svn_boolean_t text_conflict_p, prop_conflict_p; const char *parent_dir; if (entry->kind == svn_node_dir) parent_dir = path; else /* non-directory, that's all we need to know */ parent_dir = svn_path_dirname(path, pool); SVN_ERR(svn_wc_conflicted_p(&text_conflict_p, &prop_conflict_p, parent_dir, entry, pool)); if (text_conflict_p) final_text_status = svn_wc_status_conflicted; if (prop_conflict_p) final_prop_status = svn_wc_status_conflicted; } /* 2. Possibly overwrite the text_status variable with "scheduled" states from the entry (A, D, R). As a group, these states are of medium precedence. They also override any C or M that may be in the prop_status field at this point, although they do not override a C text status.*/ if (entry->schedule == svn_wc_schedule_add && final_text_status != svn_wc_status_conflicted) { 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_conflicted) { 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_conflicted) { 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;#ifdef HAVE_SYMLINK else if (((! wc_special) && (path_special)) || (wc_special && (! path_special)) ) final_text_status = svn_wc_status_obstructed;#endif /* HAVE_SYMLINK */ 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) && (! entry->lock_token) && (! repos_lock)) { *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; stat->repos_lock = repos_lock; stat->url = (entry->url ? entry->url : NULL); stat->ood_last_cmt_rev = SVN_INVALID_REVNUM; stat->ood_last_cmt_date = 0; stat->ood_kind = svn_node_none; stat->ood_last_cmt_author = NULL; *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 path_special, svn_boolean_t get_all, svn_boolean_t is_ignored, apr_hash_t *repos_locks, const char *repos_root, svn_wc_status_func2_t status_func, void *status_baton, apr_pool_t *pool){ svn_wc_status2_t *statstruct; SVN_ERR(assemble_status(&statstruct, path, adm_access, entry, parent_entry, path_kind, path_special, get_all, is_ignored, repos_locks, repos_root, 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; *patterns = apr_array_make(pool, 1, sizeof(const char *)); /* 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_tis_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. PATH_SPECIAL is the special status of the path, also 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_boolean_t path_special, svn_wc_adm_access_t *adm_access, apr_array_header_t *patterns, apr_hash_t *externals, svn_boolean_t no_ignore, apr_hash_t *repos_locks, const char *repos_root, svn_wc_status_func2_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_status2_t *status; SVN_ERR(assemble_status(&status, path, adm_access, NULL, NULL, path_kind, path_special, FALSE, ignore_me, repos_locks, repos_root, pool)); if (is_external) status->text_status = svn_wc_status_external; /* If we aren't ignoring it, or if it's an externals path, or it has a lock in the repository, pass this entry to the status func. */ if (no_ignore || (! ignore_me) || is_external || status->repos_lock) (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_func2_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, svn_node_kind_t kind, svn_boolean_t special, apr_array_header_t *ignores, svn_boolean_t descend, svn_boolean_t get_all, svn_boolean_t no_ignore, svn_wc_status_func2_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); 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)); if (! full_entry) return svn_error_createf(SVN_ERR_UNVERSIONED_RESOURCE, NULL, _("'%s' is not under version control"), svn_path_local_style(path, 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, special, get_all, FALSE, eb->repos_locks, eb->repos_root, status_func, status_baton, pool)); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -