📄 status.c
字号:
/* Mark the parent as changed; it gained an entry. */ pb->text_changed = TRUE; return SVN_NO_ERROR;}static svn_error_t *open_directory(const char *path, void *parent_baton, svn_revnum_t base_revision, apr_pool_t *pool, void **child_baton){ struct dir_baton *pb = parent_baton; return make_dir_baton(child_baton, path, pb->edit_baton, pb, pool);}static svn_error_t *change_dir_prop(void *dir_baton, const char *name, const svn_string_t *value, apr_pool_t *pool){ struct dir_baton *db = dir_baton; if (svn_wc_is_normal_prop(name)) db->prop_changed = TRUE; /* Note any changes to the repository. */ if (value != NULL) { if (strcmp(name, SVN_PROP_ENTRY_COMMITTED_REV) == 0) db->ood_last_cmt_rev = SVN_STR_TO_REV(value->data); else if (strcmp(name, SVN_PROP_ENTRY_LAST_AUTHOR) == 0) db->ood_last_cmt_author = apr_pstrdup(db->pool, value->data); else if (strcmp(name, SVN_PROP_ENTRY_COMMITTED_DATE) == 0) { apr_time_t tm; SVN_ERR(svn_time_from_cstring(&tm, value->data, db->pool)); db->ood_last_cmt_date = tm; } } return SVN_NO_ERROR;}static svn_error_t *close_directory(void *dir_baton, apr_pool_t *pool){ struct dir_baton *db = dir_baton; struct dir_baton *pb = db->parent_baton; struct edit_baton *eb = db->edit_baton; svn_wc_status2_t *dir_status = NULL; /* If nothing has changed, return. */ if (db->added || db->prop_changed || db->text_changed) { enum svn_wc_status_kind repos_text_status; enum svn_wc_status_kind repos_prop_status; /* If this is a new directory, add it to the statushash. */ if (db->added) { repos_text_status = svn_wc_status_added; repos_prop_status = db->prop_changed ? svn_wc_status_added : svn_wc_status_none; } else { repos_text_status = db->text_changed ? svn_wc_status_modified : svn_wc_status_none; repos_prop_status = db->prop_changed ? svn_wc_status_modified : svn_wc_status_none; } /* Maybe add this directory to its parent's status hash. Note that tweak_statushash won't do anything if repos_text_status is not svn_wc_status_added. */ if (pb) { /* ### When we add directory locking, we need to find a ### directory lock here. */ SVN_ERR(tweak_statushash(pb, TRUE, eb->adm_access, db->path, TRUE, repos_text_status, repos_prop_status, NULL)); } else { /* We're editing the root dir of the WC. As its repos status info isn't otherwise set, set it directly to trigger invocation of the status callback below. */ eb->anchor_status->repos_prop_status = repos_prop_status; eb->anchor_status->repos_text_status = repos_text_status; } } /* Handle this directory's statuses, and then note in the parent that this has been done. */ if (pb && eb->descend) { svn_boolean_t was_deleted = FALSE; /* See if the directory was deleted or replaced. */ dir_status = apr_hash_get(pb->statii, db->path, APR_HASH_KEY_STRING); if (dir_status && ((dir_status->repos_text_status == svn_wc_status_deleted) || (dir_status->repos_text_status == svn_wc_status_replaced))) was_deleted = TRUE; /* Now do the status reporting. */ SVN_ERR(handle_statii(eb, dir_status ? dir_status->entry : NULL, db->path, db->statii, was_deleted, TRUE, pool)); if (dir_status && is_sendable_status(dir_status, eb)) (eb->status_func)(eb->status_baton, db->path, dir_status); apr_hash_set(pb->statii, db->path, APR_HASH_KEY_STRING, NULL); } else if (! pb) { /* If this is the top-most directory, and the operation had a target, we should only report the target. */ if (*eb->target) { svn_wc_status2_t *tgt_status; const char *path = svn_path_join(eb->anchor, eb->target, pool); dir_status = eb->anchor_status; tgt_status = apr_hash_get(db->statii, path, APR_HASH_KEY_STRING); if (tgt_status) { if ((eb->descend) && (tgt_status->entry) && (tgt_status->entry->kind == svn_node_dir)) { svn_wc_adm_access_t *dir_access; SVN_ERR(svn_wc_adm_retrieve(&dir_access, eb->adm_access, path, pool)); SVN_ERR(get_dir_status (eb, tgt_status->entry, dir_access, NULL, eb->ignores, TRUE, eb->get_all, eb->no_ignore, TRUE, eb->status_func, eb->status_baton, eb->cancel_func, eb->cancel_baton, pool)); } if (is_sendable_status(tgt_status, eb)) (eb->status_func)(eb->status_baton, path, tgt_status); } } else { /* Otherwise, we report on all our children and ourself. Note that our directory couldn't have been deleted, because it is the root of the edit drive. */ SVN_ERR(handle_statii(eb, eb->anchor_status->entry, db->path, db->statii, FALSE, eb->descend, pool)); if (is_sendable_status(eb->anchor_status, eb)) (eb->status_func)(eb->status_baton, db->path, eb->anchor_status); eb->anchor_status = NULL; } } return SVN_NO_ERROR;}static svn_error_t *add_file(const char *path, void *parent_baton, const char *copyfrom_path, svn_revnum_t copyfrom_revision, apr_pool_t *pool, void **file_baton){ struct dir_baton *pb = parent_baton; struct file_baton *new_fb = make_file_baton(pb, path, pool); /* Mark parent dir as changed */ pb->text_changed = TRUE; /* Make this file as added. */ new_fb->added = TRUE; *file_baton = new_fb; return SVN_NO_ERROR;}static svn_error_t *open_file(const char *path, void *parent_baton, svn_revnum_t base_revision, apr_pool_t *pool, void **file_baton){ struct dir_baton *pb = parent_baton; struct file_baton *new_fb = make_file_baton(pb, path, pool); *file_baton = new_fb; return SVN_NO_ERROR;}static svn_error_t *apply_textdelta(void *file_baton, const char *base_checksum, apr_pool_t *pool, svn_txdelta_window_handler_t *handler, void **handler_baton){ struct file_baton *fb = file_baton; /* Mark file as having textual mods. */ fb->text_changed = TRUE; /* Send back a NULL window handler -- we don't need the actual diffs. */ *handler_baton = NULL; *handler = svn_delta_noop_window_handler; return SVN_NO_ERROR;}static svn_error_t *change_file_prop(void *file_baton, const char *name, const svn_string_t *value, apr_pool_t *pool){ struct file_baton *fb = file_baton; if (svn_wc_is_normal_prop(name)) fb->prop_changed = TRUE; /* Note any changes to the repository. */ if (value != NULL) { if (strcmp(name, SVN_PROP_ENTRY_COMMITTED_REV) == 0) fb->ood_last_cmt_rev = SVN_STR_TO_REV(value->data); else if (strcmp(name, SVN_PROP_ENTRY_LAST_AUTHOR) == 0) fb->ood_last_cmt_author = apr_pstrdup(fb->dir_baton->pool, value->data); else if (strcmp(name, SVN_PROP_ENTRY_COMMITTED_DATE) == 0) { apr_time_t tm; SVN_ERR(svn_time_from_cstring(&tm, value->data, fb->dir_baton->pool)); fb->ood_last_cmt_date = tm; } } return SVN_NO_ERROR;}static svn_error_t *close_file(void *file_baton, const char *text_checksum, /* ignored, as we receive no data */ apr_pool_t *pool){ struct file_baton *fb = file_baton; enum svn_wc_status_kind repos_text_status; enum svn_wc_status_kind repos_prop_status; svn_lock_t *repos_lock = NULL; /* If nothing has changed, return. */ if (! (fb->added || fb->prop_changed || fb->text_changed)) return SVN_NO_ERROR; /* If this is a new file, add it to the statushash. */ if (fb->added) { const char *url; repos_text_status = svn_wc_status_added; repos_prop_status = fb->prop_changed ? svn_wc_status_added : 0; if (fb->edit_baton->repos_locks) { url = find_dir_url(fb->dir_baton, pool); if (url) { url = svn_path_url_add_component(url, fb->name, pool); repos_lock = apr_hash_get (fb->edit_baton->repos_locks, svn_path_uri_decode(url + strlen(fb->edit_baton->repos_root), pool), APR_HASH_KEY_STRING); } } } else { repos_text_status = fb->text_changed ? svn_wc_status_modified : 0; repos_prop_status = fb->prop_changed ? svn_wc_status_modified : 0; } SVN_ERR(tweak_statushash(fb, FALSE, fb->edit_baton->adm_access, fb->path, FALSE, repos_text_status, repos_prop_status, repos_lock)); return SVN_NO_ERROR;}static svn_error_t *close_edit(void *edit_baton, apr_pool_t *pool){ struct edit_baton *eb = edit_baton; apr_array_header_t *ignores = eb->ignores; svn_error_t *err = NULL; /* If we get here and the root was not opened as part of the edit, we need to transmit statuses for everything. Otherwise, we should be done. */ if (eb->root_opened) goto cleanup; /* If we have a target, that's the thing we're sending, otherwise we're sending the anchor. */ if (*eb->target) { svn_node_kind_t kind; const char *full_path = svn_path_join(eb->anchor, eb->target, pool); err = svn_io_check_path(full_path, &kind, pool); if (err) goto cleanup; if (kind == svn_node_dir) { svn_wc_adm_access_t *tgt_access; const svn_wc_entry_t *tgt_entry; err = svn_wc_entry(&tgt_entry, full_path, eb->adm_access, FALSE, pool); if (err) goto cleanup; if (! tgt_entry) { err = get_dir_status(eb, NULL, eb->adm_access, eb->target, ignores, FALSE, eb->get_all, TRUE, TRUE, eb->status_func, eb->status_baton, eb->cancel_func, eb->cancel_baton, pool); if (err) goto cleanup; } else { err = svn_wc_adm_retrieve(&tgt_access, eb->adm_access, full_path, pool); if (err) goto cleanup; err = get_dir_status(eb, NULL, tgt_access, NULL, ignores, eb->descend, eb->get_all, eb->no_ignore, FALSE, eb->status_func, eb->status_baton, eb->cancel_func, eb->cancel_baton, pool); if (err) goto cleanup; } } else { err = get_dir_status(eb, NULL, eb->adm_access, eb->target, ignores, FALSE, eb->get_all, TRUE, TRUE, eb->status_func, eb->status_baton, eb->cancel_func, eb->cancel_baton, pool); if (err) goto cl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -