📄 status.c
字号:
/* * status.c: construct a status structure from an entry structure * * ==================================================================== * Copyright (c) 2000-2006 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/. * ==================================================================== */#include <assert.h>#include <string.h>#include <apr_pools.h>#include <apr_file_io.h>#include <apr_hash.h>#include "svn_pools.h"#include "svn_types.h"#include "svn_delta.h"#include "svn_string.h"#include "svn_error.h"#include "svn_path.h"#include "svn_io.h"#include "svn_wc.h"#include "svn_config.h"#include "svn_time.h"#include "svn_private_config.h"#include "wc.h"#include "lock.h"#include "props.h"#include "translate.h"/*** Editor batons ***/struct edit_baton{ /* For status, the "destination" of the edit and whether to honor any paths that are 'below'. */ const char *anchor; const char *target; svn_wc_adm_access_t *adm_access; svn_boolean_t descend; /* Do we want all statuses (instead of just the interesting ones) ? */ svn_boolean_t get_all; /* Ignore the svn:ignores. */ svn_boolean_t no_ignore; /* The comparison revision in the repository. This is a reference because this editor returns this rev to the driver directly, as well as in each statushash entry. */ svn_revnum_t *target_revision; /* Subversion configuration hash. */ apr_hash_t *config; /* Status function/baton. */ svn_wc_status_func2_t status_func; void *status_baton; /* Cancellation function/baton. */ svn_cancel_func_t cancel_func; void *cancel_baton; /* The configured set of default ignores. */ apr_array_header_t *ignores; /* Externals info harvested during the status run. */ svn_wc_traversal_info_t *traversal_info; apr_hash_t *externals; /* Status item for the path represented by the anchor of the edit. */ svn_wc_status2_t *anchor_status; /* Was open_root() called for this edit drive? */ svn_boolean_t root_opened; /* The repository root URL, if set. */ const char *repos_root; /* Repository locks, if set. */ apr_hash_t *repos_locks;};struct dir_baton{ /* The path to this directory. */ const char *path; /* Basename of this directory. */ const char *name; /* The global edit baton. */ struct edit_baton *edit_baton; /* Baton for this directory's parent, or NULL if this is the root directory. */ struct dir_baton *parent_baton; /* 'svn status' shouldn't print status lines for things that are added; we're only interest in asking if objects that the user *already* has are up-to-date or not. Thus if this flag is set, the next two will be ignored. :-) */ svn_boolean_t added; /* Gets set iff there's a change to this directory's properties, to guide us when syncing adm files later. */ svn_boolean_t prop_changed; /* This means (in terms of 'svn status') that some child was deleted or added to the directory */ svn_boolean_t text_changed; /* Working copy status structures for children of this directory. This hash maps const char * paths (relative to the root of the edit) to svn_wc_status2_t * status items. */ apr_hash_t *statii; /* The pool in which this baton itself is allocated. */ apr_pool_t *pool; /* The URI to this item in the repository. */ const char *url; /* Out of date info corresponding to ood_* fields in svn_wc_status2_t. */ svn_revnum_t ood_last_cmt_rev; apr_time_t ood_last_cmt_date; svn_node_kind_t ood_kind; const char *ood_last_cmt_author;};struct file_baton{ /* The global edit baton. */ struct edit_baton *edit_baton; /* Baton for this file's parent directory. */ struct dir_baton *dir_baton; /* Pool specific to this file_baton. */ apr_pool_t *pool; /* Name of this file (its entry in the directory). */ const char *name; /* Path to this file, either abs or relative to the change-root. */ const char *path; /* 'svn status' shouldn't print status lines for things that are added; we're only interest in asking if objects that the user *already* has are up-to-date or not. Thus if this flag is set, the next two will be ignored. :-) */ svn_boolean_t added; /* This gets set if the file underwent a text change, which guides the code that syncs up the adm dir and working copy. */ svn_boolean_t text_changed; /* This gets set if the file underwent a prop change, which guides the code that syncs up the adm dir and working copy. */ svn_boolean_t prop_changed; /* The URI to this item in the repository. */ const char *url; /* Out of date info corresponding to ood_* fields in svn_wc_status2_t. */ svn_revnum_t ood_last_cmt_rev; apr_time_t ood_last_cmt_date; svn_node_kind_t ood_kind; const char *ood_last_cmt_author;};/** Code **//* Fill in *STATUS for PATH, whose entry data is in ENTRY. Allocate *STATUS in POOL. ENTRY may be null, for non-versioned entities. In this case, we will assemble a special status structure item which implies a non-versioned thing. PARENT_ENTRY is the entry for the parent directory of PATH, it may be NULL if ENTRY is NULL or if PATH is a working copy root. The lifetime of PARENT_ENTRY's pool is not important. PATH_KIND is the node kind of PATH as determined by the caller. NOTE: this may be svn_node_unknown if the caller has made no such determination. If PATH_KIND is not svn_node_unknown, PATH_SPECIAL indicates whether the entry is a special file. If GET_ALL is zero, and ENTRY is not locally modified, then *STATUS will be set to NULL. If GET_ALL is non-zero, then *STATUS will be allocated and returned no matter what. If IS_IGNORED is non-zero and this is a non-versioned entity, set the text_status to svn_wc_status_none. Otherwise set the text_status to svn_wc_status_unversioned. If non-NULL, look up a repository lock in REPOS_LOCKS and set the repos_lock field of the status struct to that lock if it exists. If REPOS_LOCKS is non-NULL, REPOS_ROOT must contain the repository root URL of the entry.*/static svn_error_t *assemble_status(svn_wc_status2_t **status, 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, apr_pool_t *pool){ svn_wc_status2_t *stat; svn_boolean_t has_props; svn_boolean_t text_modified_p = FALSE; svn_boolean_t prop_modified_p = FALSE; svn_boolean_t locked_p = FALSE; svn_boolean_t switched_p = FALSE;#ifdef HAVE_SYMLINK svn_boolean_t wc_special;#endif /* HAVE_SYMLINK */ /* Defaults for two main variables. */ enum svn_wc_status_kind final_text_status = svn_wc_status_normal; enum svn_wc_status_kind final_prop_status = svn_wc_status_none; svn_lock_t *repos_lock = NULL; /* Check for a repository lock. */ if (repos_locks) { const char *abs_path; if (entry && entry->url) abs_path = entry->url + strlen(repos_root); else if (parent_entry && parent_entry->url) abs_path = svn_path_join(parent_entry->url + strlen(repos_root), svn_path_basename(path, pool), pool); else abs_path = NULL; if (abs_path) repos_lock = apr_hash_get(repos_locks, svn_path_uri_decode(abs_path, pool), APR_HASH_KEY_STRING); } /* Check the path kind for PATH. */ if (path_kind == svn_node_unknown) SVN_ERR(svn_io_check_special_path(path, &path_kind, &path_special, pool)); if (! entry) { /* return a blank structure. */ stat = apr_pcalloc(pool, sizeof(*stat)); stat->entry = NULL; stat->text_status = svn_wc_status_none; stat->prop_status = svn_wc_status_none; stat->repos_text_status = svn_wc_status_none; stat->repos_prop_status = svn_wc_status_none; stat->locked = FALSE; stat->copied = FALSE; stat->switched = FALSE; /* If this path has no entry, but IS present on disk, it's unversioned. If this file is being explicitly ignored (due to matching an ignore-pattern), the text_status is set to svn_wc_status_ignored. Otherwise the text_status is set to svn_wc_status_unversioned. */ if (path_kind != svn_node_none) { if (is_ignored) stat->text_status = svn_wc_status_ignored; else stat->text_status = svn_wc_status_unversioned; } stat->repos_lock = repos_lock; stat->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; } /* Someone either deleted the administrative directory in the versioned subdir, or deleted the directory altogether and created a new one. In any case, what is currently there is in the way. */ if (entry->kind == svn_node_dir) { if (path_kind == svn_node_dir) { if (svn_wc__adm_missing(adm_access, path)) final_text_status = svn_wc_status_obstructed; } else if (path_kind != svn_node_none) final_text_status = svn_wc_status_obstructed; } /* Is this item switched? Well, to be switched it must have both an URL and a parent with an URL, at the very least. */ if (entry->url && parent_entry && parent_entry->url) { /* An item is switched if its working copy basename differs from the basename of its URL. */ if (strcmp(svn_path_uri_encode(svn_path_basename(path, pool), pool), svn_path_basename(entry->url, pool))) switched_p = TRUE; /* An item is switched if its URL, without the basename, does not equal its parent's URL. */ if (! switched_p && strcmp(svn_path_dirname(entry->url, pool), parent_entry->url)) switched_p = TRUE; } if (final_text_status != svn_wc_status_obstructed) { /* Implement predecence rules: */ /* 1. Set the two main variables to "discovered" values first (M, C). Together, these two stati are of lowest precedence, and C has precedence over M. */ /* Does the entry have props? */ SVN_ERR(svn_wc__has_props(&has_props, path, adm_access, pool)); if (has_props) final_prop_status = svn_wc_status_normal; /* If the entry has a property file, see if it has local changes. */ SVN_ERR(svn_wc_props_modified_p(&prop_modified_p, path, adm_access, pool));#ifdef HAVE_SYMLINK if (has_props) SVN_ERR(svn_wc__get_special(&wc_special, path, adm_access, pool)); else wc_special = FALSE;#endif /* HAVE_SYMLINK */ /* If the entry is a file, check for textual modifications */ if ((entry->kind == svn_node_file)#ifdef HAVE_SYMLINK && (wc_special == path_special)#endif /* HAVE_SYMLINK */ ) SVN_ERR(svn_wc_text_modified_p(&text_modified_p, path, FALSE,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -