📄 entries.c
字号:
if (entry->conflict_new) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_CONFLICT_NEW, APR_HASH_KEY_STRING, entry->conflict_new); if (entry->conflict_wrk) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_CONFLICT_WRK, APR_HASH_KEY_STRING, entry->conflict_wrk); if (entry->prejfile) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_PREJFILE, APR_HASH_KEY_STRING, entry->prejfile); /* Copy-related Stuff */ apr_hash_set(atts, SVN_WC__ENTRY_ATTR_COPIED, APR_HASH_KEY_STRING, (entry->copied ? "true" : NULL)); if (SVN_IS_VALID_REVNUM(entry->copyfrom_rev)) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_COPYFROM_REV, APR_HASH_KEY_STRING, apr_psprintf(pool, "%ld", entry->copyfrom_rev)); if (entry->copyfrom_url) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_COPYFROM_URL, APR_HASH_KEY_STRING, entry->copyfrom_url); /* Deleted state */ apr_hash_set(atts, SVN_WC__ENTRY_ATTR_DELETED, APR_HASH_KEY_STRING, (entry->deleted ? "true" : NULL)); /* Absent state */ apr_hash_set(atts, SVN_WC__ENTRY_ATTR_ABSENT, APR_HASH_KEY_STRING, (entry->absent ? "true" : NULL)); /* Incomplete state */ apr_hash_set(atts, SVN_WC__ENTRY_ATTR_INCOMPLETE, APR_HASH_KEY_STRING, (entry->incomplete ? "true" : NULL)); /* Timestamps */ if (entry->text_time) { apr_hash_set(atts, SVN_WC__ENTRY_ATTR_TEXT_TIME, APR_HASH_KEY_STRING, svn_time_to_cstring(entry->text_time, pool)); } if (entry->prop_time) { apr_hash_set(atts, SVN_WC__ENTRY_ATTR_PROP_TIME, APR_HASH_KEY_STRING, svn_time_to_cstring(entry->prop_time, pool)); } /* Checksum */ if (entry->checksum) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_CHECKSUM, APR_HASH_KEY_STRING, entry->checksum); /* Last-commit stuff */ if (SVN_IS_VALID_REVNUM(entry->cmt_rev)) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_CMT_REV, APR_HASH_KEY_STRING, apr_psprintf(pool, "%ld", entry->cmt_rev)); if (entry->cmt_author) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_CMT_AUTHOR, APR_HASH_KEY_STRING, entry->cmt_author); if (entry->uuid) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_UUID, APR_HASH_KEY_STRING, entry->uuid); if (entry->cmt_date) { apr_hash_set(atts, SVN_WC__ENTRY_ATTR_CMT_DATE, APR_HASH_KEY_STRING, svn_time_to_cstring(entry->cmt_date, pool)); } /* Lock token */ if (entry->lock_token) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_LOCK_TOKEN, APR_HASH_KEY_STRING, entry->lock_token); /* Lock owner */ if (entry->lock_owner) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_LOCK_OWNER, APR_HASH_KEY_STRING, entry->lock_owner); /* Lock comment */ if (entry->lock_comment) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_LOCK_COMMENT, APR_HASH_KEY_STRING, entry->lock_comment); /* Lock creation date */ if (entry->lock_creation_date) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_LOCK_CREATION_DATE, APR_HASH_KEY_STRING, svn_time_to_cstring(entry->lock_creation_date, pool)); /* Has-props flag. */ apr_hash_set(atts, SVN_WC__ENTRY_ATTR_HAS_PROPS, APR_HASH_KEY_STRING, (entry->has_props ? "true" : NULL)); /* Prop-mods. */ if (entry->has_prop_mods) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_HAS_PROP_MODS, APR_HASH_KEY_STRING, "true"); /* Cachable props. */ if (entry->cachable_props && *entry->cachable_props) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_CACHABLE_PROPS, APR_HASH_KEY_STRING, entry->cachable_props); /* Present props. */ if (entry->present_props && *entry->present_props) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_PRESENT_PROPS, APR_HASH_KEY_STRING, entry->present_props); /*** Now, remove stuff that can be derived through inheritance rules. ***/ /* We only want to write out 'revision' and 'url' for the following things: 1. the current directory's "this dir" entry. 2. non-directory entries: a. which are marked for addition (and consequently should have an invalid revnum) b. whose revision or url is valid and different than that of the "this dir" entry. */ if (strcmp(name, SVN_WC_ENTRY_THIS_DIR)) { /* This is NOT the "this dir" entry */ if (! strcmp(name, ".")) { /* By golly, if this isn't recognized as the "this dir" entry, and it looks like '.', we're just asking for an infinite recursion to happen. Abort! */ abort(); } if (entry->kind == svn_node_dir) { /* We don't write url, revision, repository root or uuid for subdir entries. */ apr_hash_set(atts, SVN_WC__ENTRY_ATTR_REVISION, APR_HASH_KEY_STRING, NULL); apr_hash_set(atts, SVN_WC__ENTRY_ATTR_URL, APR_HASH_KEY_STRING, NULL); apr_hash_set(atts, SVN_WC__ENTRY_ATTR_REPOS, APR_HASH_KEY_STRING, NULL); apr_hash_set(atts, SVN_WC__ENTRY_ATTR_UUID, APR_HASH_KEY_STRING, NULL); } else { /* If this is not the "this dir" entry, and the revision is the same as that of the "this dir" entry, don't write out the revision. */ if (entry->revision == this_dir->revision) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_REVISION, APR_HASH_KEY_STRING, NULL); /* If this is not the "this dir" entry, and the uuid is the same as that of the "this dir" entry, don't write out the uuid. */ if (entry->uuid && this_dir->uuid) { if (strcmp(entry->uuid, this_dir->uuid) == 0) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_UUID, APR_HASH_KEY_STRING, NULL); } /* If this is not the "this dir" entry, and the url is trivially calculable from that of the "this dir" entry, don't write out the url */ if (entry->url) { if (strcmp(entry->url, svn_path_url_add_component(this_dir->url, name, pool)) == 0) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_URL, APR_HASH_KEY_STRING, NULL); } /* Avoid writing repository root if that's the same as this_dir. */ if (entry->repos && this_dir->repos && strcmp(entry->repos, this_dir->repos) == 0) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_REPOS, APR_HASH_KEY_STRING, NULL); /* Cachable props are also inherited. */ if (entry->cachable_props && this_dir->cachable_props && strcmp(entry->cachable_props, this_dir->cachable_props) == 0) apr_hash_set(atts, SVN_WC__ENTRY_ATTR_CACHABLE_PROPS, APR_HASH_KEY_STRING, NULL); } } /* Append the entry onto the accumulating string. */ svn_xml_make_open_tag_hash(output, pool, svn_xml_self_closing, SVN_WC__ENTRIES_ENTRY, atts);}/* Construct an entries file from the ENTRIES hash in XML format in a newly allocated stringbuf and return it in *OUTPUT. Allocate the result in POOL. THIS_DIR is the this_dir entry in ENTRIES. */static voidwrite_entries_xml(svn_stringbuf_t **output, apr_hash_t *entries, svn_wc_entry_t *this_dir, apr_pool_t *pool){ apr_hash_index_t *hi; apr_pool_t *subpool = svn_pool_create(pool); svn_xml_make_header(output, pool); svn_xml_make_open_tag(output, pool, svn_xml_normal, SVN_WC__ENTRIES_TOPLEVEL, "xmlns", SVN_XML_NAMESPACE, NULL); /* Write out "this dir" */ write_entry_xml(output, this_dir, SVN_WC_ENTRY_THIS_DIR, this_dir, pool); for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi)) { const void *key; void *val; svn_wc_entry_t *this_entry; svn_pool_clear(subpool); /* Get the entry and make sure its attributes are up-to-date. */ apr_hash_this(hi, &key, NULL, &val); this_entry = val; /* Don't rewrite the "this dir" entry! */ if (! strcmp(key, SVN_WC_ENTRY_THIS_DIR )) continue; /* Append the entry to output */ write_entry_xml(output, this_entry, key, this_dir, subpool); } svn_xml_make_close_tag(output, pool, SVN_WC__ENTRIES_TOPLEVEL); svn_pool_destroy(subpool);} svn_error_t *svn_wc__entries_write(apr_hash_t *entries, svn_wc_adm_access_t *adm_access, apr_pool_t *pool){ svn_error_t *err = SVN_NO_ERROR; svn_stringbuf_t *bigstr = NULL; apr_file_t *outfile = NULL; apr_hash_index_t *hi; svn_wc_entry_t *this_dir; SVN_ERR(svn_wc__adm_write_check(adm_access)); /* Get a copy of the "this dir" entry for comparison purposes. */ this_dir = apr_hash_get(entries, SVN_WC_ENTRY_THIS_DIR, APR_HASH_KEY_STRING); /* If there is no "this dir" entry, something is wrong. */ if (! this_dir) return svn_error_createf(SVN_ERR_ENTRY_NOT_FOUND, NULL, _("No default entry in directory '%s'"), svn_path_local_style (svn_wc_adm_access_path(adm_access), pool)); /* Open entries file for writing. It's important we don't use APR_EXCL * here. Consider what happens if a log file is interrupted, it may * leave a .svn/tmp/entries file behind. Then when cleanup reruns the * log file, and it attempts to modify the entries file, APR_EXCL would * cause an error that prevents cleanup running. We don't use log file * tags such as SVN_WC__LOG_MV to move entries files so any existing file * is not "valuable". */ SVN_ERR(svn_wc__open_adm_file(&outfile, svn_wc_adm_access_path(adm_access), SVN_WC__ADM_ENTRIES, (APR_WRITE | APR_CREATE), pool)); if (svn_wc__adm_wc_format(adm_access) > SVN_WC__XML_ENTRIES_VERSION) { apr_pool_t *subpool = svn_pool_create(pool); bigstr = svn_stringbuf_createf(pool, "%d\n", svn_wc__adm_wc_format(adm_access)); /* Write out "this dir" */ write_entry(bigstr, this_dir, SVN_WC_ENTRY_THIS_DIR, this_dir, pool); for (hi = apr_hash_first(pool, entries); hi; hi = apr_hash_next(hi)) { const void *key; void *val; svn_wc_entry_t *this_entry; svn_pool_clear(subpool); /* Get the entry and make sure its attributes are up-to-date. */ apr_hash_this(hi, &key, NULL, &val); this_entry = val; /* Don't rewrite the "this dir" entry! */ if (! strcmp(key, SVN_WC_ENTRY_THIS_DIR )) continue; /* Append the entry to BIGSTR */ write_entry(bigstr, this_entry, key, this_dir, subpool); } svn_pool_destroy(subpool); } else /* This is needed during cleanup of a not yet upgraded WC. */ write_entries_xml(&bigstr, entries, this_dir, pool); SVN_ERR_W(svn_io_file_write_full(outfile, bigstr->data, bigstr->len, NULL, pool), apr_psprintf(pool, _("Error writing to '%s'"), svn_path_local_style (svn_wc_adm_access_path(adm_access), pool))); err = svn_wc__close_adm_file(outfile, svn_wc_adm_access_path(adm_access), SVN_WC__ADM_ENTRIES, 1, pool); svn_wc__adm_access_set_entries(adm_access, TRUE, entries); svn_wc__adm_access_set_entries(adm_access, FALSE, NULL); return err;}/* Update an entry NAME in ENTRIES, according to the combination of entry data found in ENTRY and masked by MODIFY_FLAGS. If the entry already exists, the requested changes will be folded (merged) into the entry's existing state. If the entry doesn't exist, the entry will be created with exactly those properties described by the set of changes. Also cleanups meaningless fields combinations. POOL may be used to allocate memory referenced by ENTRIES. */static voidfold_entry(apr_hash_t *entries, const char *name, apr_uint32_t modify_flags, svn_wc_entry_t *entry, apr_pool_t *pool){ svn_wc_entry_t *cur_entry = apr_hash_get(entries, name, APR_HASH_KEY_STRING); assert(name != NULL); if (! cur_entry) cur_entry = alloc_entry(pool); /* Name (just a safeguard here, really) */ if (! cur_entry->name) cur_entry->name = apr_pstrdup(pool, name); /* Revision */ if (modify_flags & SVN_WC__ENTRY_MODIFY_REVISION) cur_entry->revision = entry->revision; /* Ancestral URL in repository */ if (modify_flags & SVN_WC__ENTRY_MODIFY_URL) cur_entry->url = entry->url ? apr_pstrdup(pool, entry->url) : NULL; /* Repository root */ if (modify_flags & SVN_WC__ENTRY_MODIFY_REPOS) cur_entry->repos = entry->repos ? apr_pstrdup(pool, entry->repos) : NULL; /* Kind */ if (modify_flags & SVN_WC__ENTRY_MODIFY_KIND) cur_entry->kind = entry->kind; /* Schedule */ if (modify_flags & SVN_WC__ENTRY_MODIFY_SCHEDULE) cur_entry->schedule = entry->schedule; /* Checksum */ if (modify_flags & SVN_WC__ENTRY_MODIFY_CHECKSUM) cur_entry->checksum = entry->checksum ? apr_pstrdup(pool, entry->checksum) : NULL; /* Copy-related stuff */ if (modify_flags & SVN_WC__ENTRY_MODIFY_COPIED) cur_entry->copied = entry->copied; if (modify_flags & SVN_WC__ENTRY_MODIFY_COPYFROM_URL) cur_entry->copyfrom_url = entry->copyfrom_url ? apr_pstrdup(pool, entry->copyfrom_url)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -