📄 ra_plugin.c
字号:
svn_pool_clear(iterpool); apr_hash_this(hi, &rel_path, NULL, &val); token = val; abs_path = svn_path_join(db->fs_path, rel_path, iterpool); /* We may get errors here if the lock was broken or stolen after the commit succeeded. This is fine and should be ignored. */ svn_error_clear(svn_repos_fs_unlock(db->repos, abs_path, token, FALSE, iterpool)); } svn_pool_destroy(iterpool); } /* But, deltification shouldn't be stopped just because someone's random callback failed, so proceed unconditionally on to deltification. */ err2 = svn_fs_deltify_revision(db->fs, commit_info->revision, db->pool); /* It's more interesting if the original callback failed, so let that one dominate. */ if (err1) { svn_error_clear(err2); return err1; } return err2;}static svn_error_t *svn_ra_local__get_commit_editor(svn_ra_session_t *session, const svn_delta_editor_t **editor, void **edit_baton, const char *log_msg, svn_commit_callback2_t callback, void *callback_baton, apr_hash_t *lock_tokens, svn_boolean_t keep_locks, apr_pool_t *pool){ svn_ra_local__session_baton_t *sess_baton = session->priv; struct deltify_etc_baton *db = apr_palloc(pool, sizeof(*db)); apr_hash_index_t *hi; svn_fs_access_t *fs_access; db->fs = sess_baton->fs; db->repos = sess_baton->repos; db->fs_path = sess_baton->fs_path->data; if (! keep_locks) db->lock_tokens = lock_tokens; else db->lock_tokens = NULL; db->pool = pool; db->callback = callback; db->callback_baton = callback_baton; SVN_ERR(get_username(session, pool)); /* If there are lock tokens to add, do so. */ if (lock_tokens) { SVN_ERR(svn_fs_get_access(&fs_access, sess_baton->fs)); /* If there is no access context, the filesystem will scream if a lock is needed. */ if (fs_access) { for (hi = apr_hash_first(pool, lock_tokens); hi; hi = apr_hash_next(hi)) { void *val; const char *token; apr_hash_this(hi, NULL, NULL, &val); token = val; SVN_ERR(svn_fs_access_add_lock_token(fs_access, token)); } } } /* Get the repos commit-editor */ SVN_ERR(svn_repos_get_commit_editor4 (editor, edit_baton, sess_baton->repos, NULL, svn_path_uri_decode(sess_baton->repos_url, pool), sess_baton->fs_path->data, sess_baton->username, log_msg, deltify_etc, db, NULL, NULL, pool)); return SVN_NO_ERROR;}static svn_error_t *make_reporter(svn_ra_session_t *session, const svn_ra_reporter2_t **reporter, void **report_baton, svn_revnum_t revision, const char *target, const char *other_url, svn_boolean_t text_deltas, svn_boolean_t recurse, svn_boolean_t ignore_ancestry, const svn_delta_editor_t *editor, void *edit_baton, apr_pool_t *pool){ svn_ra_local__session_baton_t *sbaton = session->priv; void *rbaton; int repos_url_len; const char *other_fs_path = NULL; const char *repos_url_decoded; /* Get the HEAD revision if one is not supplied. */ if (! SVN_IS_VALID_REVNUM(revision)) SVN_ERR(svn_ra_local__get_latest_revnum(session, &revision, pool)); /* If OTHER_URL was provided, validate it and convert it into a regular filesystem path. */ if (other_url) { other_url = svn_path_uri_decode(other_url, pool); repos_url_decoded = svn_path_uri_decode(sbaton->repos_url, pool); repos_url_len = strlen(repos_url_decoded); /* Sanity check: the other_url better be in the same repository as the original session url! */ if (strncmp(other_url, repos_url_decoded, repos_url_len) != 0) return svn_error_createf (SVN_ERR_RA_ILLEGAL_URL, NULL, _("'%s'\n" "is not the same repository as\n" "'%s'"), other_url, sbaton->repos_url); other_fs_path = other_url + repos_url_len; } /* Pass back our reporter */ *reporter = &ra_local_reporter; SVN_ERR(get_username(session, pool)); /* Build a reporter baton. */ SVN_ERR(svn_repos_begin_report(&rbaton, revision, sbaton->username, sbaton->repos, sbaton->fs_path->data, target, other_fs_path, text_deltas, recurse, ignore_ancestry, editor, edit_baton, NULL, NULL, pool)); /* Wrap the report baton given us by the repos layer with our own reporter baton. */ *report_baton = make_reporter_baton(sbaton, rbaton, pool); return SVN_NO_ERROR;}static svn_error_t *svn_ra_local__do_update(svn_ra_session_t *session, const svn_ra_reporter2_t **reporter, void **report_baton, svn_revnum_t update_revision, const char *update_target, svn_boolean_t recurse, const svn_delta_editor_t *update_editor, void *update_baton, apr_pool_t *pool){ return make_reporter(session, reporter, report_baton, update_revision, update_target, NULL, TRUE, recurse, FALSE, update_editor, update_baton, pool);}static svn_error_t *svn_ra_local__do_switch(svn_ra_session_t *session, const svn_ra_reporter2_t **reporter, void **report_baton, svn_revnum_t update_revision, const char *update_target, svn_boolean_t recurse, const char *switch_url, const svn_delta_editor_t *update_editor, void *update_baton, apr_pool_t *pool){ return make_reporter(session, reporter, report_baton, update_revision, update_target, switch_url, TRUE, recurse, TRUE, update_editor, update_baton, pool);}static svn_error_t *svn_ra_local__do_status(svn_ra_session_t *session, const svn_ra_reporter2_t **reporter, void **report_baton, const char *status_target, svn_revnum_t revision, svn_boolean_t recurse, const svn_delta_editor_t *status_editor, void *status_baton, apr_pool_t *pool){ return make_reporter(session, reporter, report_baton, revision, status_target, NULL, FALSE, recurse, FALSE, status_editor, status_baton, pool);}static svn_error_t *svn_ra_local__do_diff(svn_ra_session_t *session, const svn_ra_reporter2_t **reporter, void **report_baton, svn_revnum_t update_revision, const char *update_target, svn_boolean_t recurse, svn_boolean_t ignore_ancestry, svn_boolean_t text_deltas, const char *switch_url, const svn_delta_editor_t *update_editor, void *update_baton, apr_pool_t *pool){ return make_reporter(session, reporter, report_baton, update_revision, update_target, switch_url, text_deltas, recurse, ignore_ancestry, update_editor, update_baton, pool);}static svn_error_t *svn_ra_local__get_log(svn_ra_session_t *session, const apr_array_header_t *paths, svn_revnum_t start, svn_revnum_t end, int limit, svn_boolean_t discover_changed_paths, svn_boolean_t strict_node_history, svn_log_message_receiver_t receiver, void *receiver_baton, apr_pool_t *pool){ svn_ra_local__session_baton_t *sbaton = session->priv; int i; apr_array_header_t *abs_paths = apr_array_make(pool, 0, sizeof(const char *)); if (paths) { for (i = 0; i < paths->nelts; i++) { const char *abs_path = ""; const char *relative_path = (((const char **)(paths)->elts)[i]); /* Append the relative paths to the base FS path to get an absolute repository path. */ abs_path = svn_path_join(sbaton->fs_path->data, relative_path, pool); (*((const char **)(apr_array_push(abs_paths)))) = abs_path; } } return svn_repos_get_logs3(sbaton->repos, abs_paths, start, end, limit, discover_changed_paths, strict_node_history, NULL, NULL, receiver, receiver_baton, pool);}static svn_error_t *svn_ra_local__do_check_path(svn_ra_session_t *session, const char *path, svn_revnum_t revision, svn_node_kind_t *kind, apr_pool_t *pool){ svn_ra_local__session_baton_t *sbaton = session->priv; svn_fs_root_t *root; const char *abs_path = sbaton->fs_path->data; /* ### Not sure if this counts as a workaround or not. The session baton uses the empty string to mean root, and not sure that should change. However, it would be better to use a path library function to add this separator -- hardcoding it is totally bogus. See issue #559, though it may be only tangentially related. */ if (abs_path[0] == '\0') abs_path = "/"; /* If we were given a relative path to append, append it. */ if (path) abs_path = svn_path_join(abs_path, path, pool); if (! SVN_IS_VALID_REVNUM(revision)) SVN_ERR(svn_fs_youngest_rev(&revision, sbaton->fs, pool)); SVN_ERR(svn_fs_revision_root(&root, sbaton->fs, revision, pool)); SVN_ERR(svn_fs_check_path(kind, root, abs_path, pool)); return SVN_NO_ERROR;}static svn_error_t *svn_ra_local__stat(svn_ra_session_t *session, const char *path, svn_revnum_t revision, svn_dirent_t **dirent, apr_pool_t *pool){ svn_ra_local__session_baton_t *sbaton = session->priv; svn_fs_root_t *root; const char *abs_path = sbaton->fs_path->data; /* ### see note above in __do_check_path() */ if (abs_path[0] == '\0') abs_path = "/"; if (path) abs_path = svn_path_join(abs_path, path, pool); if (! SVN_IS_VALID_REVNUM(revision)) SVN_ERR(svn_fs_youngest_rev(&revision, sbaton->fs, pool)); SVN_ERR(svn_fs_revision_root(&root, sbaton->fs, revision, pool)); SVN_ERR(svn_repos_stat(dirent, root, abs_path, pool)); return SVN_NO_ERROR;}static svn_error_t *get_node_props(apr_hash_t **props, svn_ra_local__session_baton_t *sbaton, svn_fs_root_t *root, const char *path, apr_pool_t *pool){ svn_revnum_t cmt_rev; const char *cmt_date, *cmt_author; /* Create a hash with props attached to the fs node. */ SVN_ERR(svn_fs_node_proplist(props, root, path, pool)); /* Now add some non-tweakable metadata to the hash as well... */ /* The so-called 'entryprops' with info about CR & friends. */ SVN_ERR(svn_repos_get_committed_info(&cmt_rev, &cmt_date, &cmt_author, root, path, pool)); apr_hash_set(*props, SVN_PROP_ENTRY_COMMITTED_REV, APR_HASH_KEY_STRING, svn_string_createf(pool, "%ld", cmt_rev)); apr_hash_set(*props, SVN_PROP_ENTRY_COMMITTED_DATE, APR_HASH_KEY_STRING, cmt_date ? svn_string_create(cmt_date, pool) : NULL); apr_hash_set(*props, SVN_PROP_ENTRY_LAST_AUTHOR, APR_HASH_KEY_STRING, cmt_author ? svn_string_create(cmt_author, pool) : NULL); apr_hash_set(*props, SVN_PROP_ENTRY_UUID, APR_HASH_KEY_STRING, svn_string_create(sbaton->uuid, pool)); /* We have no 'wcprops' in ra_local, but might someday. */ return SVN_NO_ERROR;}/* Getting just one file. */static svn_error_t *svn_ra_local__get_file(svn_ra_session_t *session, const char *path, svn_revnum_t revision, svn_stream_t *stream, svn_revnum_t *fetched_rev, apr_hash_t **props, apr_pool_t *pool){ svn_fs_root_t *root; svn_stream_t *contents; svn_revnum_t youngest_rev; svn_ra_local__session_baton_t *sbaton = session->priv; const char *abs_path = sbaton->fs_path->data; /* ### Not sure if this counts as a workaround or not. The session baton uses the empty string to mean root, and not sure that should change. However, it would be better to use a path library function to add this separator -- hardcoding it is totally bogus. See issue #559, though it may be only tangentially related. */ if (abs_path[0] == '\0') abs_path = "/"; /* If we were given a relative path to append, append it. */ if (path) abs_path = svn_path_join(abs_path, path, pool);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -