📄 main.c
字号:
SVN_ERR(generate_delta_tree(&tree, c->repos, root, base_rev_id, TRUE, pool)); if (tree) { const char *tmpdir; SVN_ERR(svn_fs_revision_root(&base_root, c->fs, base_rev_id, pool)); SVN_ERR(svn_io_temp_dir(&tmpdir, pool)); SVN_ERR(print_diff_tree(root, base_root, tree, "", "", c, tmpdir, pool)); } return SVN_NO_ERROR;}/* Callback baton for print_history() (and do_history()). */struct print_history_baton{ svn_fs_t *fs; svn_boolean_t show_ids;};/* Implements svn_repos_history_func_t interface. Print the history that's reported through this callback, possibly finding and displaying node-rev-ids. */static svn_error_t *print_history(void *baton, const char *path, svn_revnum_t revision, apr_pool_t *pool){ struct print_history_baton *phb = baton; SVN_ERR(check_cancel(NULL)); if (phb->show_ids) { const svn_fs_id_t *node_id; svn_fs_root_t *rev_root; svn_string_t *id_string; SVN_ERR(svn_fs_revision_root(&rev_root, phb->fs, revision, pool)); SVN_ERR(svn_fs_node_id(&node_id, rev_root, path, pool)); id_string = svn_fs_unparse_id(node_id, pool); SVN_ERR(svn_cmdline_printf(pool, "%8ld %s <%s>\n", revision, path, id_string->data)); } else { SVN_ERR(svn_cmdline_printf(pool, "%8ld %s\n", revision, path)); } return SVN_NO_ERROR;}/* Print a tabular display of history location points for PATH in revision C->rev_id. Optionally, SHOW_IDS. Use POOL for allocations. */static svn_error_t *do_history(svnlook_ctxt_t *c, const char *path, svn_boolean_t show_ids, apr_pool_t *pool){ struct print_history_baton args; if (show_ids) { SVN_ERR(svn_cmdline_printf(pool, _("REVISION PATH <ID>\n" "-------- ---------\n"))); } else { SVN_ERR(svn_cmdline_printf(pool, _("REVISION PATH\n" "-------- ----\n"))); } /* Call our history crawler. We want the whole lifetime of the path (prior to the user-supplied revision, of course), across all copies. */ args.fs = c->fs; args.show_ids = show_ids; SVN_ERR(svn_repos_history2(c->fs, path, print_history, &args, NULL, NULL, 0, c->rev_id, 1, pool)); return SVN_NO_ERROR;}/* Print the value of property PROPNAME on PATH in the repository. Error with SVN_ERR_FS_NOT_FOUND if PATH does not exist, or with SVN_ERR_PROPERTY_NOT_FOUND if no such property on PATH. If PATH is NULL, operate on a revision property. */static svn_error_t *do_pget(svnlook_ctxt_t *c, const char *propname, const char *path, apr_pool_t *pool){ svn_fs_root_t *root; svn_string_t *prop; svn_node_kind_t kind; svn_stream_t *stdout_stream; apr_size_t len; SVN_ERR(get_root(&root, c, pool)); if (path != NULL) { SVN_ERR(verify_path(&kind, root, path, pool)); SVN_ERR(svn_fs_node_prop(&prop, root, path, propname, pool)); } else SVN_ERR(get_property(&prop, c, propname, pool)); if (prop == NULL) { if (path == NULL) return svn_error_createf (SVN_ERR_PROPERTY_NOT_FOUND, NULL, _("Property '%s' not found on revision %ld"), propname, c->rev_id); else return svn_error_createf (SVN_ERR_PROPERTY_NOT_FOUND, NULL, _("Property '%s' not found on path '%s' in revision %ld"), propname, path, c->rev_id); } /* Else. */ SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool)); /* Unlike the command line client, we don't translate the property value or print a trailing newline here. We just output the raw bytes of whatever's in the repository, as svnlook is more likely to be used for automated inspections. */ len = prop->len; SVN_ERR(svn_stream_write(stdout_stream, prop->data, &len)); return SVN_NO_ERROR;}/* Print the property names of all properties on PATH in the repository. If VERBOSE, print their values too. Error with SVN_ERR_FS_NOT_FOUND if PATH does not exist, or with SVN_ERR_PROPERTY_NOT_FOUND if no such property on PATH. If PATH is NULL, operate on a revision properties. */static svn_error_t *do_plist(svnlook_ctxt_t *c, const char *path, svn_boolean_t verbose, apr_pool_t *pool){ svn_stream_t *stdout_stream; svn_fs_root_t *root; apr_hash_t *props; apr_hash_index_t *hi; svn_node_kind_t kind; SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool)); if (path != NULL) { SVN_ERR(get_root(&root, c, pool)); SVN_ERR(verify_path(&kind, root, path, pool)); SVN_ERR(svn_fs_node_proplist(&props, root, path, pool)); } else SVN_ERR(svn_fs_revision_proplist(&props, c->fs, c->rev_id, pool)); for (hi = apr_hash_first(pool, props); hi; hi = apr_hash_next(hi)) { const void *key; void *val; const char *pname; svn_string_t *propval; SVN_ERR(check_cancel(NULL)); apr_hash_this(hi, &key, NULL, &val); pname = key; propval = val; /* Since we're already adding a trailing newline (and possible a colon and some spaces) anyway, just mimic the output of the command line client proplist. Compare to 'svnlook propget', which sends the raw bytes to stdout, untranslated. */ /* We leave printf calls here, since we don't always know the encoding of the prop value. */ if (svn_prop_needs_translation(pname)) SVN_ERR(svn_subst_detranslate_string(&propval, propval, TRUE, pool)); if (verbose) { const char *pname_stdout; SVN_ERR(svn_cmdline_cstring_from_utf8(&pname_stdout, pname, pool)); printf(" %s : %s\n", pname_stdout, propval->data); } else printf(" %s\n", pname); } return SVN_NO_ERROR;}/* Print the diff between revision 0 and our root. */static svn_error_t *do_tree(svnlook_ctxt_t *c, const char *path, svn_boolean_t show_ids, svn_boolean_t full_paths, apr_pool_t *pool){ svn_fs_root_t *root; const svn_fs_id_t *id; svn_boolean_t is_dir; SVN_ERR(get_root(&root, c, pool)); SVN_ERR(svn_fs_node_id(&id, root, path, pool)); SVN_ERR(svn_fs_is_dir(&is_dir, root, path, pool)); SVN_ERR(print_tree(root, path, id, is_dir, 0, show_ids, full_paths, pool)); return SVN_NO_ERROR;}/* Custom filesystem warning function. */static voidwarning_func(void *baton, svn_error_t *err){ if (! err) return; svn_handle_error2(err, stderr, FALSE, "svnlook: ");}/* Factory function for the context baton. */static svn_error_t *get_ctxt_baton(svnlook_ctxt_t **baton_p, struct svnlook_opt_state *opt_state, apr_pool_t *pool){ svnlook_ctxt_t *baton = apr_pcalloc(pool, sizeof(*baton)); SVN_ERR(svn_repos_open(&(baton->repos), opt_state->repos_path, pool)); baton->fs = svn_repos_fs(baton->repos); svn_fs_set_warning_func(baton->fs, warning_func, NULL); baton->show_ids = opt_state->show_ids; baton->no_diff_deleted = opt_state->no_diff_deleted; baton->no_diff_added = opt_state->no_diff_added; baton->diff_copy_from = opt_state->diff_copy_from; baton->full_paths = opt_state->full_paths; baton->copy_info = opt_state->copy_info; baton->is_revision = opt_state->txn ? FALSE : TRUE; baton->rev_id = opt_state->rev; baton->txn_name = apr_pstrdup(pool, opt_state->txn); if (baton->txn_name) SVN_ERR(svn_fs_open_txn(&(baton->txn), baton->fs, baton->txn_name, pool)); else if (baton->rev_id == SVN_INVALID_REVNUM) SVN_ERR(svn_fs_youngest_rev(&(baton->rev_id), baton->fs, pool)); *baton_p = baton; return SVN_NO_ERROR;}/*** Subcommands. ***//* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_author(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnlook_opt_state *opt_state = baton; svnlook_ctxt_t *c; SVN_ERR(get_ctxt_baton(&c, opt_state, pool)); SVN_ERR(do_author(c, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_cat(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnlook_opt_state *opt_state = baton; svnlook_ctxt_t *c; if (opt_state->arg1 == NULL) return svn_error_createf (SVN_ERR_CL_INSUFFICIENT_ARGS, NULL, _("Missing repository path argument")); SVN_ERR(get_ctxt_baton(&c, opt_state, pool)); SVN_ERR(do_cat(c, opt_state->arg1, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_changed(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnlook_opt_state *opt_state = baton; svnlook_ctxt_t *c; SVN_ERR(get_ctxt_baton(&c, opt_state, pool)); SVN_ERR(do_changed(c, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_date(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnlook_opt_state *opt_state = baton; svnlook_ctxt_t *c; SVN_ERR(get_ctxt_baton(&c, opt_state, pool)); SVN_ERR(do_date(c, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_diff(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnlook_opt_state *opt_state = baton; svnlook_ctxt_t *c; SVN_ERR(get_ctxt_baton(&c, opt_state, pool)); SVN_ERR(do_diff(c, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_dirschanged(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnlook_opt_state *opt_state = baton; svnlook_ctxt_t *c; SVN_ERR(get_ctxt_baton(&c, opt_state, pool)); SVN_ERR(do_dirs_changed(c, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_help(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnlook_opt_state *opt_state = baton; const char *header = _("general usage: svnlook SUBCOMMAND REPOS_PATH [ARGS & OPTIONS ...]\n" "Note: any subcommand which takes the '--revision' and '--transaction'\n" " options will, if invoked without one of those options, act on\n" " the repository's youngest revision.\n" "Type 'svnlook help <subcommand>' for help on a specific subcommand.\n" "Type 'svnlook --version' to see the program version and FS modules.\n" "\n" "Available subcommands:\n"); const char *fs_desc_start = _("The following repository back-end (FS) modules are available:\n\n"); svn_stringbuf_t *version_footer; version_footer = svn_stringbuf_create(fs_desc_start, pool); SVN_ERR(svn_fs_print_modules(version_footer, pool)); SVN_ERR(svn_opt_print_help(os, "svnlook", opt_state ? opt_state->version : FALSE, FALSE, version_footer->data, header, cmd_table, options_table, NULL, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_history(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnlook_opt_state *opt_state = baton; svnlook_ctxt_t *c; const char *path = "/"; if (opt_state->arg1) path = opt_state->arg1; SVN_ERR(get_ctxt_baton(&c, opt_state, pool)); SVN_ERR(do_history(c, path, opt_state->show_ids, pool)); return SVN_NO_ERROR;}/* This implements `svn_opt_subcommand_t'. */static svn_error_t *subcommand_lock(apr_getopt_t *os, void *baton, apr_pool_t *pool){ struct svnlook_opt_state *opt_state = baton; svnlook_ctxt_t *c; const char *path; svn_lock_t *lock; if (opt_state->arg1) path = opt_state->arg1; else return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, NULL, _("Missing path argument")); SVN_ERR(get_ctxt_baton(&c, opt_state, pool)); SVN_ERR(svn_fs_get_lock(&lock, c->fs, path, pool)); if (lock) { const char *cr_date, *exp_date = ""; int comment_lines = 0; cr_date = svn_time_to_human_cstring(lock->creation_date, pool); if (lock->expiration_date) exp_date = svn_time_to_human_cstring(lock->expiration_date, pool); if (lock->comment) comment_lines = svn_cstring_count_newlines(lock->comment) + 1; SVN_ERR(svn_cmdline_printf(pool, _("UUID Token: %s\n"), lock->token));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -