📄 repos_diff.c
字号:
svn_wc_adm_access_t *adm_access; /* Open the file to be used as the base for second revision */ SVN_ERR(svn_io_file_open(&(b->file_start_revision), b->path_start_revision, APR_READ, APR_OS_DEFAULT, b->pool)); /* Open the file that will become the second revision after applying the text delta, it starts empty */ if (b->edit_baton->adm_access) { svn_error_t *err; err = svn_wc_adm_probe_retrieve(&adm_access, b->edit_baton->adm_access, b->wcpath, pool); if (err) { svn_error_clear(err); adm_access = NULL; } } else adm_access = NULL; SVN_ERR(create_empty_file(&(b->file_end_revision), &(b->path_end_revision), adm_access, svn_io_file_del_on_pool_cleanup, b->pool)); svn_txdelta_apply(svn_stream_from_aprfile(b->file_start_revision, b->pool), svn_stream_from_aprfile(b->file_end_revision, b->pool), NULL, b->path, b->pool, &(b->apply_handler), &(b->apply_baton)); *handler = window_handler; *handler_baton = file_baton; return SVN_NO_ERROR;}/* An editor function. When the file is closed we have a temporary * file containing a pristine version of the repository file. This can * be compared against the working copy. * * ### Ignore TEXT_CHECKSUM for now. Someday we can use it to verify * ### the integrity of the file being diffed. Done efficiently, this * ### would probably involve calculating the checksum as the data is * ### received, storing the final checksum in the file_baton, and * ### comparing against it here. */static svn_error_t *close_file(void *file_baton, const char *text_checksum, apr_pool_t *pool){ struct file_baton *b = file_baton; struct edit_baton *eb = b->edit_baton; svn_wc_adm_access_t *adm_access; svn_error_t *err; svn_wc_notify_action_t action; svn_wc_notify_state_t content_state = svn_wc_notify_state_unknown, prop_state = svn_wc_notify_state_unknown; err = get_parent_access(&adm_access, eb->adm_access, b->wcpath, eb->dry_run, b->pool); if (err && err->apr_err == SVN_ERR_WC_NOT_LOCKED) { /* ### maybe try to stat the local b->wcpath? */ /* If the file path doesn't exist, then send a 'skipped' notification. */ if (eb->notify_func) { svn_wc_notify_t *notify = svn_wc_create_notify(b->wcpath, svn_wc_notify_skip, pool); notify->kind = svn_node_file; notify->content_state = svn_wc_notify_state_missing; notify->prop_state = prop_state; (*eb->notify_func)(eb->notify_baton, notify, pool); } svn_error_clear(err); return SVN_NO_ERROR; } else if (err) return err; if (b->path_end_revision || b->propchanges->nelts > 0) { const char *mimetype1, *mimetype2; get_file_mime_types(&mimetype1, &mimetype2, b); if (b->added) SVN_ERR(eb->diff_callbacks->file_added (adm_access, &content_state, &prop_state, b->wcpath, b->path_end_revision ? b->path_start_revision : NULL, b->path_end_revision, 0, b->edit_baton->target_revision, mimetype1, mimetype2, b->propchanges, b->pristine_props, b->edit_baton->diff_cmd_baton)); else SVN_ERR(eb->diff_callbacks->file_changed (adm_access, &content_state, &prop_state, b->wcpath, b->path_end_revision ? b->path_start_revision : NULL, b->path_end_revision, b->edit_baton->revision, b->edit_baton->target_revision, mimetype1, mimetype2, b->propchanges, b->pristine_props, b->edit_baton->diff_cmd_baton)); } if ((content_state == svn_wc_notify_state_missing) || (content_state == svn_wc_notify_state_obstructed)) action = svn_wc_notify_skip; else if (b->added) action = svn_wc_notify_update_add; else action = svn_wc_notify_update_update; if (eb->notify_func) { svn_wc_notify_t *notify = svn_wc_create_notify(b->wcpath, action, pool); notify->kind = svn_node_file; notify->content_state = content_state; notify->prop_state = prop_state; (*eb->notify_func)(eb->notify_baton, notify, pool); } return SVN_NO_ERROR;}/* An editor function. */static svn_error_t *close_directory(void *dir_baton, apr_pool_t *pool){ struct dir_baton *b = dir_baton; struct edit_baton *eb = b->edit_baton; svn_wc_notify_state_t prop_state = svn_wc_notify_state_unknown; svn_error_t *err; if (eb->dry_run) { apr_hash_index_t *hi; apr_hash_t *wc_paths = svn_client__dry_run_deletions(eb->diff_cmd_baton); /* FUTURE: Someday, we'll have apr_hash_clear() instead. */ for (hi = apr_hash_first(NULL, wc_paths); hi; hi = apr_hash_next(hi)) { const void *path; apr_hash_this(hi, &path, NULL, NULL); apr_hash_set(wc_paths, path, APR_HASH_KEY_STRING, NULL); } } if (b->propchanges->nelts > 0) { svn_wc_adm_access_t *adm_access; err = get_path_access(&adm_access, eb->adm_access, b->wcpath, eb->dry_run, b->pool); if (err && err->apr_err == SVN_ERR_WC_NOT_LOCKED) { /* ### maybe try to stat the local b->wcpath? */ /* If the path doesn't exist, then send a 'skipped' notification. */ if (eb->notify_func) { svn_wc_notify_t *notify = svn_wc_create_notify(b->wcpath, svn_wc_notify_skip, pool); notify->kind = svn_node_dir; notify->content_state = notify->prop_state = svn_wc_notify_state_missing; (*eb->notify_func)(eb->notify_baton, notify, pool); } svn_error_clear(err); return SVN_NO_ERROR; } else if (err) return err; /* Don't do the props_changed stuff if this is a dry_run and we don't have an access baton, since in that case the directory will already have been recognised as added, in which case they cannot conflict. */ if (! eb->dry_run || adm_access) SVN_ERR(eb->diff_callbacks->dir_props_changed (adm_access, &prop_state, b->wcpath, b->propchanges, b->pristine_props, b->edit_baton->diff_cmd_baton)); } /* ### Don't notify added directories as they triggered notification in add_directory. Does this mean that directory notification isn't getting all the information? */ if (!b->added && eb->notify_func) { svn_wc_notify_t *notify = svn_wc_create_notify(b->wcpath, svn_wc_notify_update_update, pool); notify->kind = svn_node_dir; notify->content_state = svn_wc_notify_state_inapplicable; notify->prop_state = prop_state; notify->lock_state = svn_wc_notify_lock_state_inapplicable; (*eb->notify_func)(eb->notify_baton, notify, pool); } return SVN_NO_ERROR;}/* An editor function. */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 *b = file_baton; svn_prop_t *propchange; propchange = apr_array_push(b->propchanges); propchange->name = apr_pstrdup(b->pool, name); propchange->value = value ? svn_string_dup(value, b->pool) : NULL; return SVN_NO_ERROR;}/* An editor function. */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; svn_prop_t *propchange; propchange = apr_array_push(db->propchanges); propchange->name = apr_pstrdup(db->pool, name); propchange->value = value ? svn_string_dup(value, db->pool) : NULL; return SVN_NO_ERROR;}/* An editor function. */static svn_error_t *close_edit(void *edit_baton, apr_pool_t *pool){ struct edit_baton *eb = edit_baton; svn_pool_destroy(eb->pool); return SVN_NO_ERROR;}/* Create a repository diff editor and baton. */svn_error_t *svn_client__get_diff_editor(const char *target, svn_wc_adm_access_t *adm_access, const svn_wc_diff_callbacks2_t *diff_callbacks, void *diff_cmd_baton, svn_boolean_t recurse, svn_boolean_t dry_run, svn_ra_session_t *ra_session, svn_revnum_t revision, svn_wc_notify_func2_t notify_func, void *notify_baton, svn_cancel_func_t cancel_func, void *cancel_baton, const svn_delta_editor_t **editor, void **edit_baton, apr_pool_t *pool){ apr_pool_t *subpool = svn_pool_create(pool); svn_delta_editor_t *tree_editor = svn_delta_default_editor(subpool); struct edit_baton *eb = apr_palloc(subpool, sizeof(*eb)); eb->target = target; eb->adm_access = adm_access; eb->diff_callbacks = diff_callbacks; eb->diff_cmd_baton = diff_cmd_baton; eb->recurse = recurse; eb->dry_run = dry_run; eb->ra_session = ra_session; eb->revision = revision; eb->empty_file = NULL; eb->empty_hash = apr_hash_make(subpool); eb->pool = subpool; eb->notify_func = notify_func; eb->notify_baton = notify_baton; tree_editor->set_target_revision = set_target_revision; tree_editor->open_root = open_root; tree_editor->delete_entry = delete_entry; tree_editor->add_directory = add_directory; tree_editor->open_directory = open_directory; tree_editor->add_file = add_file; tree_editor->open_file = open_file; tree_editor->apply_textdelta = apply_textdelta; tree_editor->close_file = close_file; tree_editor->close_directory = close_directory; tree_editor->change_file_prop = change_file_prop; tree_editor->change_dir_prop = change_dir_prop; tree_editor->close_edit = close_edit; SVN_ERR(svn_delta_get_cancellation_editor(cancel_func, cancel_baton, tree_editor, eb, editor, edit_baton, pool)); return SVN_NO_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -