📄 entries.c
字号:
}
break;
case svn_wc_schedule_delete:
switch (*schedule)
{
case svn_wc_schedule_normal:
case svn_wc_schedule_delete:
/* These are no-op cases. */
*modify_flags &= ~SVN_WC__ENTRY_MODIFY_SCHEDULE;
return SVN_NO_ERROR;
case svn_wc_schedule_add:
/* Re-adding an entry marked for deletion? This is really a
replace operation. */
*schedule = svn_wc_schedule_replace;
return SVN_NO_ERROR;
case svn_wc_schedule_replace:
/* Replacing an item marked for deletion breaks down to
(delete + (delete + add)), which might deserve a warning,
but whatever. */
return SVN_NO_ERROR;
}
break;
case svn_wc_schedule_replace:
switch (*schedule)
{
case svn_wc_schedule_normal:
/* These are all no-op cases. */
case svn_wc_schedule_add:
/* Adding a to-be-replaced entry breaks down to ((delete +
add) + add) which might deserve a warning, but we'll just
no-op it. */
case svn_wc_schedule_replace:
/* Replacing a to-be-replaced entry breaks down to ((delete
+ add) + (delete + add)), which is insane! Make up your
friggin' mind, dude! :-) Well, we'll no-op this one,
too. */
*modify_flags &= ~SVN_WC__ENTRY_MODIFY_SCHEDULE;
return SVN_NO_ERROR;
case svn_wc_schedule_delete:
/* Deleting a to-be-replaced entry breaks down to ((delete +
add) + delete) which resolves to a flat deletion. */
*schedule = svn_wc_schedule_delete;
return SVN_NO_ERROR;
}
break;
default:
return
svn_error_createf
(SVN_ERR_WC_SCHEDULE_CONFLICT, NULL,
_("Entry '%s' has illegal schedule"), name);
}
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc__entry_modify (svn_wc_adm_access_t *adm_access,
const char *name,
svn_wc_entry_t *entry,
apr_uint32_t modify_flags,
svn_boolean_t do_sync,
apr_pool_t *pool)
{
apr_hash_t *entries, *entries_nohidden;
svn_boolean_t entry_was_deleted_p = FALSE;
/* ENTRY is rather necessary, and ENTRY->kind is required to be valid! */
assert (entry);
/* Load PATH's whole entries file. */
SVN_ERR (svn_wc_entries_read (&entries, adm_access, TRUE, pool));
SVN_ERR (svn_wc_entries_read (&entries_nohidden, adm_access, FALSE, pool));
/* Ensure that NAME is valid. */
if (name == NULL)
name = SVN_WC_ENTRY_THIS_DIR;
if (modify_flags & SVN_WC__ENTRY_MODIFY_SCHEDULE)
{
svn_wc_entry_t *entry_before, *entry_after;
apr_uint32_t orig_modify_flags = modify_flags;
svn_wc_schedule_t orig_schedule = entry->schedule;
/* Keep a copy of the unmodified entry on hand. */
entry_before = apr_hash_get (entries, name, APR_HASH_KEY_STRING);
/* If scheduling changes were made, we have a special routine to
manage those modifications. */
SVN_ERR (fold_scheduling (entries, name, &modify_flags,
&entry->schedule, pool));
if (entries != entries_nohidden)
{
SVN_ERR (fold_scheduling (entries_nohidden, name, &orig_modify_flags,
&orig_schedule, pool));
/* Make certain that both folding operations had the same
result. */
assert(orig_modify_flags == modify_flags);
assert(orig_schedule == entry->schedule);
}
/* Special case: fold_state_changes() may have actually REMOVED
the entry in question! If so, don't try to fold_entry, as
this will just recreate the entry again. */
entry_after = apr_hash_get (entries, name, APR_HASH_KEY_STRING);
/* Note if this entry was deleted above so we don't accidentally
re-add it in the following steps. */
if (entry_before && (! entry_after))
entry_was_deleted_p = TRUE;
}
/* If the entry wasn't just removed from the entries hash, fold the
changes into the entry. */
if (! entry_was_deleted_p)
{
fold_entry (entries, name, modify_flags, entry,
svn_wc_adm_access_pool (adm_access));
if (entries != entries_nohidden)
fold_entry (entries_nohidden, name, modify_flags, entry,
svn_wc_adm_access_pool (adm_access));
}
/* Sync changes to disk. */
if (do_sync)
SVN_ERR (svn_wc__entries_write (entries, adm_access, pool));
return SVN_NO_ERROR;
}
svn_wc_entry_t *
svn_wc_entry_dup (const svn_wc_entry_t *entry, apr_pool_t *pool)
{
svn_wc_entry_t *dupentry = apr_pcalloc (pool, sizeof(*dupentry));
/* Perform a trivial copy ... */
*dupentry = *entry;
/* ...and then re-copy stuff that needs to be duped into our pool. */
if (entry->name)
dupentry->name = apr_pstrdup (pool, entry->name);
if (entry->url)
dupentry->url = apr_pstrdup (pool, entry->url);
if (entry->repos)
dupentry->repos = apr_pstrdup (pool, entry->repos);
if (entry->uuid)
dupentry->uuid = apr_pstrdup (pool, entry->uuid);
if (entry->copyfrom_url)
dupentry->copyfrom_url = apr_pstrdup (pool, entry->copyfrom_url);
if (entry->conflict_old)
dupentry->conflict_old = apr_pstrdup (pool, entry->conflict_old);
if (entry->conflict_new)
dupentry->conflict_new = apr_pstrdup (pool, entry->conflict_new);
if (entry->conflict_wrk)
dupentry->conflict_wrk = apr_pstrdup (pool, entry->conflict_wrk);
if (entry->prejfile)
dupentry->prejfile = apr_pstrdup (pool, entry->prejfile);
if (entry->checksum)
dupentry->checksum = apr_pstrdup (pool, entry->checksum);
if (entry->cmt_author)
dupentry->cmt_author = apr_pstrdup (pool, entry->cmt_author);
return dupentry;
}
svn_error_t *
svn_wc__tweak_entry (apr_hash_t *entries,
const char *name,
const char *new_url,
svn_revnum_t new_rev,
svn_boolean_t *write_required,
apr_pool_t *pool)
{
svn_wc_entry_t *entry;
entry = apr_hash_get (entries, name, APR_HASH_KEY_STRING);
if (! entry)
return svn_error_createf (SVN_ERR_ENTRY_NOT_FOUND, NULL,
_("No such entry: '%s'"), name);
if (new_url != NULL
&& (! entry->url || strcmp (new_url, entry->url)))
{
*write_required = TRUE;
entry->url = apr_pstrdup (pool, new_url);
}
if ((SVN_IS_VALID_REVNUM (new_rev))
&& (entry->schedule != svn_wc_schedule_add)
&& (entry->schedule != svn_wc_schedule_replace)
&& (entry->revision != new_rev))
{
*write_required = TRUE;
entry->revision = new_rev;
}
/* As long as this function is only called as a helper to
svn_wc__do_update_cleanup, then it's okay to remove any entry
under certain circumstances:
If the entry is still marked 'deleted', then the server did not
re-add it. So it's really gone in this revision, thus we remove
the entry.
If the entry is still marked 'absent' and yet is not the same
revision as new_rev, then the server did not re-add it, nor
re-absent it, so we can remove the entry. */
if ((entry->deleted)
|| (entry->absent && (entry->revision != new_rev)))
{
*write_required = TRUE;
apr_hash_set (entries, name, APR_HASH_KEY_STRING, NULL);
}
return SVN_NO_ERROR;
}
/*** Generic Entry Walker */
/* A recursive entry-walker, helper for svn_wc_walk_entries */
static svn_error_t *
walker_helper (const char *dirpath,
svn_wc_adm_access_t *adm_access,
const svn_wc_entry_callbacks_t *walk_callbacks,
void *walk_baton,
svn_boolean_t show_hidden,
apr_pool_t *pool)
{
apr_pool_t *subpool = svn_pool_create (pool);
apr_hash_t *entries;
apr_hash_index_t *hi;
svn_wc_entry_t *dot_entry;
SVN_ERR (svn_wc_entries_read (&entries, adm_access, show_hidden, pool));
/* As promised, always return the '.' entry first. */
dot_entry = apr_hash_get (entries, SVN_WC_ENTRY_THIS_DIR,
APR_HASH_KEY_STRING);
if (! dot_entry)
return svn_error_createf (SVN_ERR_ENTRY_NOT_FOUND, NULL,
_("Directory '%s' has no THIS_DIR entry"),
dirpath);
SVN_ERR (walk_callbacks->found_entry (dirpath, dot_entry, walk_baton, pool));
/* Loop over each of the other entries. */
for (hi = apr_hash_first (pool, entries); hi; hi = apr_hash_next (hi))
{
const void *key;
apr_ssize_t klen;
void *val;
const svn_wc_entry_t *current_entry;
const char *entrypath;
apr_hash_this (hi, &key, &klen, &val);
current_entry = val;
if (strcmp (current_entry->name, SVN_WC_ENTRY_THIS_DIR) == 0)
continue;
entrypath = svn_path_join (dirpath, key, subpool);
SVN_ERR (walk_callbacks->found_entry (entrypath, current_entry,
walk_baton, subpool));
if (current_entry->kind == svn_node_dir)
{
svn_wc_adm_access_t *entry_access;
SVN_ERR (svn_wc_adm_retrieve (&entry_access, adm_access, entrypath,
subpool));
SVN_ERR (walker_helper (entrypath, entry_access,
walk_callbacks, walk_baton,
show_hidden, subpool));
}
svn_pool_clear (subpool);
}
svn_pool_destroy (subpool);
return SVN_NO_ERROR;
}
/* The public function */
svn_error_t *
svn_wc_walk_entries (const char *path,
svn_wc_adm_access_t *adm_access,
const svn_wc_entry_callbacks_t *walk_callbacks,
void *walk_baton,
svn_boolean_t show_hidden,
apr_pool_t *pool)
{
const svn_wc_entry_t *entry;
SVN_ERR (svn_wc_entry (&entry, path, adm_access, show_hidden, pool));
if (! entry)
return svn_error_createf (SVN_ERR_UNVERSIONED_RESOURCE, NULL,
_("'%s' is not under version control"), path);
if (entry->kind == svn_node_file)
return walk_callbacks->found_entry (path, entry, walk_baton, pool);
else if (entry->kind == svn_node_dir)
return walker_helper (path, adm_access, walk_callbacks, walk_baton,
show_hidden, pool);
else
return svn_error_createf (SVN_ERR_NODE_UNKNOWN_KIND, NULL,
_("'%s' has an unrecognized node kind"), path);
}
svn_error_t *
svn_wc_mark_missing_deleted (const char *path,
svn_wc_adm_access_t *parent,
apr_pool_t *pool)
{
svn_node_kind_t pkind;
SVN_ERR (svn_io_check_path (path, &pkind, pool));
if (pkind == svn_node_none)
{
const char *parent_path, *bname;
svn_wc_adm_access_t *adm_access;
svn_wc_entry_t newent;
newent.deleted = TRUE;
newent.schedule = svn_wc_schedule_normal;
svn_path_split (path, &parent_path, &bname, pool);
SVN_ERR (svn_wc_adm_retrieve (&adm_access, parent, parent_path, pool));
SVN_ERR (svn_wc__entry_modify (adm_access, bname, &newent,
(SVN_WC__ENTRY_MODIFY_DELETED
| SVN_WC__ENTRY_MODIFY_SCHEDULE
| SVN_WC__ENTRY_MODIFY_FORCE),
TRUE, /* sync right away */ pool));
return SVN_NO_ERROR;
}
else
return svn_error_createf (SVN_ERR_WC_PATH_FOUND, NULL,
_("Unexpectedly found '%s': "
"path is marked 'missing'"), path);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -