You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by st...@apache.org on 2012/02/07 11:33:20 UTC
svn commit: r1241415 [2/2] - in /subversion/branches/moves-scan-log: ./
build/ subversion/bindings/javahl/native/
subversion/bindings/javahl/src/org/apache/subversion/javahl/
subversion/include/ subversion/libsvn_client/ subversion/libsvn_delta/
subver...
Modified: subversion/branches/moves-scan-log/subversion/mod_dav_svn/liveprops.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/mod_dav_svn/liveprops.c?rev=1241415&r1=1241414&r2=1241415&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/mod_dav_svn/liveprops.c (original)
+++ subversion/branches/moves-scan-log/subversion/mod_dav_svn/liveprops.c Tue Feb 7 10:33:18 2012
@@ -679,7 +679,7 @@ insert_prop_internal(const dav_resource
{
ap_log_rerror(APLOG_MARK, APLOG_ERR, serr->apr_err,
resource->info->r,
- "Can't get fetch or compute md5 checksum of '%s': "
+ "Can't fetch or compute MD5 checksum of '%s': "
"%s",
resource->info->repos_path,
serr->message);
Modified: subversion/branches/moves-scan-log/subversion/mod_dav_svn/mod_dav_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/mod_dav_svn/mod_dav_svn.c?rev=1241415&r1=1241414&r2=1241415&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/mod_dav_svn/mod_dav_svn.c (original)
+++ subversion/branches/moves-scan-log/subversion/mod_dav_svn/mod_dav_svn.c Tue Feb 7 10:33:18 2012
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <apr_strings.h>
+#include <apr_hash.h>
#include <httpd.h>
#include <http_config.h>
@@ -94,6 +95,7 @@ typedef struct dir_conf_t {
const char *activities_db; /* path to activities database(s) */
enum conf_flag txdelta_cache; /* whether to enable txdelta caching */
enum conf_flag fulltext_cache; /* whether to enable fulltext caching */
+ apr_hash_t *hooks_env; /* environment for hook scripts */
} dir_conf_t;
@@ -193,6 +195,7 @@ create_dir_config(apr_pool_t *p, char *d
conf->root_dir = svn_urlpath__canonicalize(dir, p);
conf->bulk_updates = CONF_FLAG_ON;
conf->v2_protocol = CONF_FLAG_ON;
+ conf->hooks_env = apr_hash_make(p);
return conf;
}
@@ -222,6 +225,7 @@ merge_dir_config(apr_pool_t *p, void *ba
newconf->txdelta_cache = INHERIT_VALUE(parent, child, txdelta_cache);
newconf->fulltext_cache = INHERIT_VALUE(parent, child, fulltext_cache);
newconf->root_dir = INHERIT_VALUE(parent, child, root_dir);
+ newconf->hooks_env = INHERIT_VALUE(parent, child, hooks_env);
if (parent->fs_path)
ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL,
@@ -528,6 +532,47 @@ SVNUseUTF8_cmd(cmd_parms *cmd, void *con
return NULL;
}
+static const char *
+SVNHooksEnv_cmd(cmd_parms *cmd, void *config, const char *arg1)
+{
+ apr_array_header_t *var;
+
+ var = svn_cstring_split(arg1, "=", TRUE, cmd->pool);
+ if (var && var->nelts >= 2)
+ {
+ dir_conf_t *conf = config;
+ const char *name;
+ const char *val;
+
+ name = apr_pstrdup(apr_hash_pool_get(conf->hooks_env),
+ APR_ARRAY_IDX(var, 0, const char *));
+
+ /* Special case for values which contain '='. */
+ if (var->nelts > 2)
+ {
+ svn_stringbuf_t *buf;
+ int i;
+
+ buf = svn_stringbuf_create(APR_ARRAY_IDX(var, 1, const char *),
+ cmd->pool);
+ for (i = 2; i < var->nelts; i++)
+ {
+ svn_stringbuf_appendbyte(buf, '=');
+ svn_stringbuf_appendcstr(buf, APR_ARRAY_IDX(var, i, const char *));
+ }
+
+ val = apr_pstrdup(apr_hash_pool_get(conf->hooks_env), buf->data);
+ }
+ else
+ val = apr_pstrdup(apr_hash_pool_get(conf->hooks_env),
+ APR_ARRAY_IDX(var, 1, const char *));
+
+ apr_hash_set(conf->hooks_env, name, APR_HASH_KEY_STRING, val);
+ }
+
+ return NULL;
+}
+
/** Accessor functions for the module's configuration state **/
@@ -805,6 +850,15 @@ dav_svn__get_compression_level(void)
return svn__compression_level;
}
+apr_hash_t *
+dav_svn__get_hooks_env(request_rec *r)
+{
+ dir_conf_t *conf;
+
+ conf = ap_get_module_config(r->per_dir_config, &dav_svn_module);
+ return conf->hooks_env;
+}
+
static void
merge_xml_filter_insert(request_rec *r)
{
@@ -1044,6 +1098,12 @@ static const command_rec cmds[] =
SVNUseUTF8_cmd, NULL,
RSRC_CONF,
"use UTF-8 as native character encoding (default is ASCII)."),
+
+ /* per directory/location */
+ AP_INIT_ITERATE("SVNHooksEnv", SVNHooksEnv_cmd, NULL,
+ ACCESS_CONF|RSRC_CONF,
+ "Set the environment of hook scripts via any number of "
+ "VAR=VAL arguments (the default hook environment is empty)."),
{ NULL }
};
Modified: subversion/branches/moves-scan-log/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/mod_dav_svn/repos.c?rev=1241415&r1=1241414&r2=1241415&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/moves-scan-log/subversion/mod_dav_svn/repos.c Tue Feb 7 10:33:18 2012
@@ -1917,8 +1917,6 @@ parse_querystring(request_rec *r, const
return NULL;
}
-
-
static dav_error *
get_resource(request_rec *r,
const char *root_path,
@@ -2188,6 +2186,9 @@ get_resource(request_rec *r,
"in repos object",
HTTP_INTERNAL_SERVER_ERROR, r);
}
+
+ /* Configure the hooks environment, if not empty. */
+ svn_repos_hooks_setenv(repos->repos, dav_svn__get_hooks_env(r));
}
/* cache the filesystem object */
Modified: subversion/branches/moves-scan-log/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/cl.h?rev=1241415&r1=1241414&r2=1241415&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svn/cl.h (original)
+++ subversion/branches/moves-scan-log/subversion/svn/cl.h Tue Feb 7 10:33:18 2012
@@ -184,7 +184,7 @@ typedef struct svn_cl__opt_state_t
svn_boolean_t no_ignore; /* disregard default ignores & svn:ignore's */
svn_boolean_t no_auth_cache; /* do not cache authentication information */
svn_boolean_t no_diff_deleted; /* do not show diffs for deleted files */
- svn_boolean_t no_diff_props; /* do not show diffs for properties */
+ svn_boolean_t ignore_props; /* ignore properties */
svn_boolean_t show_copies_as_adds; /* do not diff copies with their source */
svn_boolean_t notice_ancestry; /* notice ancestry for diff-y operations */
svn_boolean_t ignore_ancestry; /* ignore ancestry for merge-y operations */
Modified: subversion/branches/moves-scan-log/subversion/svn/diff-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/diff-cmd.c?rev=1241415&r1=1241414&r2=1241415&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svn/diff-cmd.c (original)
+++ subversion/branches/moves-scan-log/subversion/svn/diff-cmd.c Tue Feb 7 10:33:18 2012
@@ -174,7 +174,7 @@ svn_cl__diff(apr_getopt_t *os,
svn_boolean_t show_copies_as_adds =
opt_state->use_patch_diff_format ? TRUE : opt_state->show_copies_as_adds;
svn_boolean_t ignore_prop_diff =
- opt_state->use_patch_diff_format ? TRUE : opt_state->no_diff_props;
+ opt_state->use_patch_diff_format ? TRUE : opt_state->ignore_props;
int i;
const svn_client_diff_summarize_func_t summarize_func =
(opt_state->xml ? summarize_xml : summarize_regular);
Modified: subversion/branches/moves-scan-log/subversion/svn/main.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svn/main.c?rev=1241415&r1=1241414&r2=1241415&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svn/main.c (original)
+++ subversion/branches/moves-scan-log/subversion/svn/main.c Tue Feb 7 10:33:18 2012
@@ -89,7 +89,7 @@ typedef enum svn_cl__longopt_t {
opt_no_auth_cache,
opt_no_autoprops,
opt_no_diff_deleted,
- opt_no_diff_props,
+ opt_ignore_props,
opt_no_ignore,
opt_no_unlock,
opt_non_interactive,
@@ -241,8 +241,8 @@ const apr_getopt_option_t svn_cl__option
N_("try operation but make no changes")},
{"no-diff-deleted", opt_no_diff_deleted, 0,
N_("do not print differences for deleted files")},
- {"no-diff-properties", opt_no_diff_props, 0,
- N_("do not print differences for properties")},
+ {"ignore-properties", opt_ignore_props, 0,
+ N_("ignore properties during the operation")},
{"notice-ancestry", opt_notice_ancestry, 0,
N_("notice ancestry when calculating differences")},
{"ignore-ancestry", opt_ignore_ancestry, 0,
@@ -352,7 +352,7 @@ const apr_getopt_option_t svn_cl__option
" "
"patch tools; currently the same as\n"
" "
- "--show-copies-as-adds --no-diff-properties\n"
+ "--show-copies-as-adds --ignore-properties\n"
)},
{"allow-mixed-revisions", opt_allow_mixed_revisions, 0,
N_("Allow merge into mixed-revision working copy.\n"
@@ -549,7 +549,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
"\n"
" Use just 'svn diff' to display local modifications in a working copy.\n"),
{'r', 'c', opt_old_cmd, opt_new_cmd, 'N', opt_depth, opt_diff_cmd,
- opt_internal_diff, 'x', opt_no_diff_deleted, opt_no_diff_props,
+ opt_internal_diff, 'x', opt_no_diff_deleted, opt_ignore_props,
opt_show_copies_as_adds, opt_notice_ancestry, opt_summarize, opt_changelist,
opt_force, opt_xml, opt_use_git_diff_format, opt_use_patch_diff_format} },
{ "export", svn_cl__export, {0}, N_
@@ -1247,7 +1247,7 @@ const svn_opt_subcommand_desc2_t svn_cl_
" complete old and new URLs if you wish.) Use 'svn info' to determine\n"
" the current working copy URL.\n"
"\n"
- " 2. TO-URL is the (complete) new repository URL to use for for PATH.\n"
+ " 2. TO-URL is the (complete) new repository URL to use for PATH.\n"
"\n"
" Examples:\n"
" svn relocate http:// svn:// project1 project2\n"
@@ -1919,8 +1919,8 @@ main(int argc, const char *argv[])
case opt_no_diff_deleted:
opt_state.no_diff_deleted = TRUE;
break;
- case opt_no_diff_props:
- opt_state.no_diff_props = TRUE;
+ case opt_ignore_props:
+ opt_state.ignore_props = TRUE;
break;
case opt_show_copies_as_adds:
opt_state.show_copies_as_adds = TRUE;
Modified: subversion/branches/moves-scan-log/subversion/svnserve/serve.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/svnserve/serve.c?rev=1241415&r1=1241414&r2=1241415&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/svnserve/serve.c (original)
+++ subversion/branches/moves-scan-log/subversion/svnserve/serve.c Tue Feb 7 10:33:18 2012
@@ -2949,6 +2949,24 @@ repos_path_valid(const char *path)
return TRUE;
}
+/* Callback which receives hook environment variables from the hook
+ * environment configuration section,
+ * An implementation of svn_config_enumerator2_t. */
+static svn_boolean_t
+hooks_env_conf_cb(const char *name,
+ const char *value,
+ void *baton,
+ apr_pool_t *pool)
+{
+ apr_hash_t *hooks_env = baton;
+ apr_pool_t *hash_pool = apr_hash_pool_get(hooks_env);
+
+ apr_hash_set(hooks_env, apr_pstrdup(hash_pool, name),
+ APR_HASH_KEY_STRING, apr_pstrdup(hash_pool, value));
+
+ return TRUE;
+}
+
/* Look for the repository given by URL, using ROOT as the virtual
* repository root. If we find one, fill in the repos, fs, cfg,
* repos_url, and fs_path fields of B. Set B->repos's client
@@ -3039,6 +3057,17 @@ static svn_error_t *find_repos(const cha
"No access allowed to this repository",
b, conn, pool);
+ /* If a hook environment has been configured, set it up. */
+ if (svn_config_has_section(b->cfg, SVN_CONFIG_SECTION_HOOKS_ENV))
+ {
+ apr_hash_t *hooks_env = apr_hash_make(pool);
+
+ svn_config_enumerate2(b->cfg, SVN_CONFIG_SECTION_HOOKS_ENV,
+ hooks_env_conf_cb, hooks_env, pool);
+
+ svn_repos_hooks_setenv(b->repos, hooks_env);
+ }
+
return SVN_NO_ERROR;
}
Modified: subversion/branches/moves-scan-log/subversion/tests/cmdline/update_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/cmdline/update_tests.py?rev=1241415&r1=1241414&r2=1241415&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/cmdline/update_tests.py (original)
+++ subversion/branches/moves-scan-log/subversion/tests/cmdline/update_tests.py Tue Feb 7 10:33:18 2012
@@ -3142,19 +3142,17 @@ def mergeinfo_update_elision(sbox):
lambda_path = os.path.join(wc_dir, "A", "B", "lambda")
# Make a branch A/B_COPY
- svntest.actions.run_and_verify_svn(
- None,
- ["A " + os.path.join(wc_dir, "A", "B_COPY", "lambda") + "\n",
+ expected_stdout = verify.UnorderedOutput([
+ "A " + os.path.join(wc_dir, "A", "B_COPY", "lambda") + "\n",
"A " + os.path.join(wc_dir, "A", "B_COPY", "E") + "\n",
"A " + os.path.join(wc_dir, "A", "B_COPY", "E", "alpha") + "\n",
"A " + os.path.join(wc_dir, "A", "B_COPY", "E", "beta") + "\n",
"A " + os.path.join(wc_dir, "A", "B_COPY", "F") + "\n",
"Checked out revision 1.\n",
- "A " + B_COPY_path + "\n"],
- [],
- 'copy',
- sbox.repo_url + "/A/B",
- B_COPY_path)
+ "A " + B_COPY_path + "\n",
+ ])
+ svntest.actions.run_and_verify_svn(None, expected_stdout, [], 'copy',
+ sbox.repo_url + "/A/B", B_COPY_path)
expected_output = wc.State(wc_dir, {'A/B_COPY' : Item(verb='Adding')})
Modified: subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/checksum-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/checksum-test.c?rev=1241415&r1=1241414&r2=1241415&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/checksum-test.c (original)
+++ subversion/branches/moves-scan-log/subversion/tests/libsvn_subr/checksum-test.c Tue Feb 7 10:33:18 2012
@@ -59,11 +59,34 @@ test_checksum_parse(apr_pool_t *pool)
return SVN_NO_ERROR;
}
+static svn_error_t *
+test_checksum_empty(apr_pool_t *pool)
+{
+ svn_checksum_t *checksum;
+ char data = '\0';
+
+ checksum = svn_checksum_empty_checksum(svn_checksum_md5, pool);
+ SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum));
+
+ checksum = svn_checksum_empty_checksum(svn_checksum_sha1, pool);
+ SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum));
+
+ SVN_ERR(svn_checksum(&checksum, svn_checksum_md5, &data, 0, pool));
+ SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum));
+
+ SVN_ERR(svn_checksum(&checksum, svn_checksum_sha1, &data, 0, pool));
+ SVN_TEST_ASSERT(svn_checksum_is_empty_checksum(checksum));
+
+ return SVN_NO_ERROR;
+}
+
/* An array of all test functions */
struct svn_test_descriptor_t test_funcs[] =
{
SVN_TEST_NULL,
SVN_TEST_PASS2(test_checksum_parse,
"checksum parse"),
+ SVN_TEST_PASS2(test_checksum_empty,
+ "checksum emptiness"),
SVN_TEST_NULL
};
Modified: subversion/branches/moves-scan-log/tools/dev/merge-graph.py
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/tools/dev/merge-graph.py?rev=1241415&r1=1241414&r2=1241415&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/tools/dev/merge-graph.py (original)
+++ subversion/branches/moves-scan-log/tools/dev/merge-graph.py Tue Feb 7 10:33:18 2012
@@ -22,237 +22,9 @@
args_message = 'GRAPH_CONFIG_FILE...'
help_message = """Produce pretty graphs representing branches and merging.
For each config file specified, construct a graph and write it as a PNG file."""
-example = """
- [graph]
- filename = merge-sync-1.png
- title = Sync Merge: CC vs SVN
- # Branches: (branch name, branched from node, first rev, last rev).
- branches = [
- ('A', 'O0', 1, 4),
- ('O', None, 0, 0),
- ('B', 'O0', 1, 5)
- ]
- # Changes: nodes in which a change was committed; merge targets need not
- # be listed here.
- changes = [
- 'A1', 'A2', 'A3', 'A4',
- 'B1', 'B2', 'B3', 'B4', 'B5'
- ]
- # Merges: (base node, source-right node, target node, label).
- # Base is also known as source-left.
- merges = [
- ('O0', 'A:1', 'B3', 'sync'),
- ('A2', 'A:3', 'B5', 'sync'),
- ]
- # Annotations for nodes: (node, annotation text).
- annotations = [
- ('A2', 'cc:YCA')
- ]
-"""
-
-# Notes about different kinds of merge.
-#
-# A basic 3-way merge is ...
-#
-# The ClearCase style of merge is a 3-way merge.
-#
-# The Subversion style of merge (that is, one phase of a Subversion merge)
-# is a three-way merge with its base (typically the YCA) on the source branch.
-
import sys
-import pydot
-from pydot import Node, Edge
-
-
-def mergeinfo_to_node_list(mi):
- """Convert a mergeinfo string such as '/foo:1,3-5*' into a list of
- node names such as ['foo1', 'foo3', 'foo4', 'foo5']."""
- ### Doesn't yet strip the leading slash.
- l = []
- if mi:
- for mi_str in mi.split(' '):
- path, ranges = mi_str.split(':')
- for r in ranges.split(','):
- if r.endswith('*'):
- # TODO: store & use this 'non-inheritable' flag
- # Remove the flag
- r = r[:-1]
- rlist = r.split('-')
- r1 = int(rlist[0])
- if len(rlist) == 2:
- r2 = int(rlist[1])
- else:
- r2 = r1
- for rev in range(r1, r2 + 1):
- l.append(path + str(rev))
- return l
-
-
-class MergeGraph(pydot.Graph):
- """Base class, not intended for direct use. Use MergeDot for the main
- graph and MergeSubgraph for a subgraph."""
-
- def mk_origin_node(graph, name):
- """Add a node to the graph"""
- graph.add_node(Node(name + '0', label=name, shape='plaintext'))
-
- def mk_invis_node(graph, name):
- """Add a node to the graph"""
- graph.add_node(Node(name, style='invis'))
-
- def mk_node(graph, name):
- """Add a node to the graph, if not already present"""
- if not graph.get_node(name):
- if name in graph.changes:
- graph.add_node(Node(name))
- else:
- graph.add_node(Node(name, color='grey', label=''))
-
- def mk_merge_target(graph, target_node, important):
- """Add a merge target node to the graph."""
- if important:
- color = 'red'
- else:
- color = 'black'
- graph.add_node(Node(target_node, color=color, fontcolor=color, style='bold'))
-
- def mk_edge(graph, name1, name2, **attrs):
- """Add an ordinary edge to the graph"""
- graph.add_edge(Edge(name1, name2, dir='none', style='dotted', color='grey', **attrs))
-
- def mk_br_edge(graph, name1, name2):
- """Add a branch-creation edge to the graph"""
- # Constraint=false to avoid the Y-shape skewing the nice parallel branch lines
- graph.mk_edge(name1, name2, constraint='false')
-
- def mk_merge_edge(graph, src_node, tgt_node, kind, label, important):
- """Add a merge edge to the graph"""
- if important:
- color = 'red'
- else:
- color = 'grey'
- e = Edge(src_node, tgt_node, constraint='false',
- label='"' + label + '"',
- color=color, fontcolor=color,
- style='bold')
- if kind == 'cherry':
- e.set_style('dashed')
- e.set_dir('both')
- e.set_arrowtail('tee')
- graph.add_edge(e)
-
- def mk_mergeinfo_edge(graph, base_node, src_node, important):
- """"""
- if important:
- color = 'red'
- else:
- color = 'grey'
- graph.add_edge(Edge(base_node, src_node,
- dir='both', arrowtail='odot', arrowhead='tee',
- color=color, constraint='false'))
-
- def mk_invis_edge(graph, name1, name2):
- """Add an invisible edge to the graph"""
- graph.add_edge(Edge(name1, name2, style='invis'))
-
- def add_merge(graph, merge, important):
- """Add a merge"""
- base_node, src_node, tgt_node, kind = merge
-
- if base_node and src_node and kind != 'cherry':
- graph.mk_mergeinfo_edge(base_node, src_node, important)
-
- # Merge target node
- graph.mk_merge_target(tgt_node, important)
-
- # Merge edge
- graph.mk_merge_edge(src_node, tgt_node, kind, kind, important)
-
- def add_annotation(graph, node, label, color='red'):
- """"""
- ann_node = node + '_annotation'
- g = pydot.Subgraph(rank='same')
- g.add_node(Node(ann_node, shape='box', color=color, label='"' + label + '"'))
- g.add_edge(Edge(ann_node, node, style='dotted', color=color, dir='none', constraint='false'))
- graph.add_subgraph(g)
-
-class MergeSubgraph(MergeGraph, pydot.Subgraph):
- """"""
- def __init__(graph, **attrs):
- """"""
- MergeGraph.__init__(graph)
- pydot.Subgraph.__init__(graph, **attrs)
-
-class MergeDot(MergeGraph, pydot.Dot):
- """
- # TODO: In the 'merges' input, find the predecessor automatically.
- """
- def __init__(graph, config_filename, **attrs):
- """Return a new MergeDot graph generated from the specified config file."""
- MergeGraph.__init__(graph)
- pydot.Dot.__init__(graph, **attrs)
-
- graph.read_config(config_filename)
-
- graph.construct()
-
- def read_config(graph, config_filename):
- """"""
- import ConfigParser
- config = ConfigParser.SafeConfigParser()
- files_read = config.read(config_filename)
- if len(files_read) == 0:
- print >> sys.stderr, 'graph: unable to read graph config from "' + config_filename + '"'
- sys.exit(1)
- graph.title = config.get('graph', 'title')
- graph.filename = config.get('graph', 'filename')
- graph.branches = eval(config.get('graph', 'branches'))
- graph.changes = eval(config.get('graph', 'changes'))
- graph.merges = eval(config.get('graph', 'merges'))
- graph.annotations = eval(config.get('graph', 'annotations'))
-
- def construct(graph):
- """"""
- # Origin nodes (done first, in an attempt to set the order)
- for br, orig, r1, head in graph.branches:
- graph.mk_origin_node(br)
-
- # Edges and target nodes for merges
- for merge in graph.merges:
- # Emphasize the last merge, as it's the important one
- important = (merge == graph.merges[-1])
- graph.add_merge(merge, important)
-
- # Edges for basic lines of descent
- for br, orig, r1, head in graph.branches:
- sub_g = MergeSubgraph(ordering='out')
- for i in range(1, head + 1):
- prev_n = br + str(i - 1)
- this_n = br + str(i)
-
- # Normal edges and nodes
- if i < r1:
- graph.mk_invis_node(this_n)
- else:
- graph.mk_node(this_n)
- if i <= r1:
- graph.mk_invis_edge(prev_n, this_n)
- else:
- graph.mk_edge(prev_n, this_n)
-
- # Branch creation edges
- if orig:
- sub_g.mk_br_edge(orig, br + str(r1))
-
- graph.add_subgraph(sub_g)
-
- # Annotations
- for node, label in graph.annotations:
- graph.add_annotation(node, label)
-
- # A title for the graph (added last so it goes at the top)
- #graph.add_node(Node('title', shape='plaintext', label='"' + graph.title + '"'))
+from mergegraph import MergeDot
# If run as a program, process each input filename as a graph config file.
Propchange: subversion/branches/moves-scan-log/tools/dev/merge-graph.py
------------------------------------------------------------------------------
svn:eol-style = native
Modified: subversion/branches/moves-scan-log/tools/dist/backport.pl
URL: http://svn.apache.org/viewvc/subversion/branches/moves-scan-log/tools/dist/backport.pl?rev=1241415&r1=1241414&r2=1241415&view=diff
==============================================================================
--- subversion/branches/moves-scan-log/tools/dist/backport.pl (original)
+++ subversion/branches/moves-scan-log/tools/dist/backport.pl Tue Feb 7 10:33:18 2012
@@ -1,6 +1,7 @@
#!/usr/bin/perl -l
use warnings;
use strict;
+use feature qw/switch say/;
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -21,6 +22,7 @@ use strict;
use Term::ReadKey qw/ReadMode ReadKey/;
use File::Temp qw/tempfile/;
+use POSIX qw/ctermid/;
$/ = ""; # paragraph mode
@@ -28,7 +30,17 @@ my $SVN = $ENV{SVN} || 'svn'; # passed u
my $VIM = 'vim';
my $STATUS = './STATUS';
my $BRANCHES = '^/subversion/branches';
+
+my $YES = $ENV{YES}; # batch mode: assume 'yes' without asking
my $WET_RUN = qw[false true][1]; # don't commit
+my $DEBUG = qw[false true][0]; # 'set -x', etc
+
+# derived values
+my $SVNq;
+
+$SVN .= " --non-interactive" unless defined ctermid;
+$SVNq = "$SVN -q ";
+$SVNq =~ s/-q// if $DEBUG eq 'true';
sub usage {
my $basename = $0;
@@ -91,13 +103,20 @@ sub merge {
my $script = <<"EOF";
#!/bin/sh
set -e
+if $DEBUG; then
+ set -x
+fi
$SVN diff > $backupfile
-$SVN revert -R .
-$SVN up
-$SVN merge $mergeargs
+$SVNq revert -R .
+$SVNq up
+$SVNq merge $mergeargs
$VIM -e -s -n -N -i NONE -u NONE -c '/$pattern/normal! dap' -c wq $STATUS
if $WET_RUN; then
- $SVN commit -F $logmsg_filename
+ if [ -n "\$PRINT_SOMETHING_BETWEEN_PROMPTS" ]; then
+ # hack for pw-driver.pl to see some output between prompts
+ head -n1 $logmsg_filename
+ fi
+ $SVNq commit -F $logmsg_filename
else
echo "Committing:"
$SVN status -q
@@ -108,13 +127,13 @@ EOF
$script .= <<"EOF" if $entry{branch};
reinteg_rev=\`$SVN info $STATUS | sed -ne 's/Last Changed Rev: //p'\`
if $WET_RUN; then
- $SVN rm $BRANCHES/$entry{branch} -m "Remove the '$entry{branch}' branch, reintegrated in r\$reinteg_rev."
+ $SVNq rm $BRANCHES/$entry{branch} -m "Remove the '$entry{branch}' branch, reintegrated in r\$reinteg_rev."
else
echo "Removing reintegrated '$entry{branch}' branch"
fi
EOF
- open SHELL, '|-', qw#/bin/sh#, ($WET_RUN ? () : '-x') or die $!;
+ open SHELL, '|-', qw#/bin/sh# or die $!;
print SHELL $script;
close SHELL or warn "$0: sh($?): $!";
@@ -182,20 +201,25 @@ sub handle_entry {
my %entry = parse_entry @_;
my @vetoes = grep { /^ -1:/ } @{$entry{votes}};
- print "";
- print "\n>>> The $entry{header}:";
- print join ", ", map { "r$_" } @{$entry{revisions}};
- print "$BRANCHES/$entry{branch}" if $entry{branch};
- print "";
- print for @{$entry{logsummary}};
- print "";
- print for @{$entry{votes}};
- print "";
- print "Vetoes found!" if @vetoes;
+ if ($YES) {
+ merge %entry unless @vetoes;
+ } else {
+ print "";
+ print "\n>>> The $entry{header}:";
+ print join ", ", map { "r$_" } @{$entry{revisions}};
+ print "$BRANCHES/$entry{branch}" if $entry{branch};
+ print "";
+ print for @{$entry{logsummary}};
+ print "";
+ print for @{$entry{votes}};
+ print "";
+ print "Vetoes found!" if @vetoes;
- # TODO: this changes ./STATUS, which we're reading below, but
+ merge %entry if prompt;
+ }
+
+ # TODO: merge() changes ./STATUS, which we're reading below, but
# on my system the loop in main() doesn't seem to care.
- merge %entry if $ENV{YES} ? !@vetoes : prompt;
1;
}
@@ -209,14 +233,22 @@ sub main {
while (<>) {
my @lines = split /\n/;
- # Section header?
+ # Skip most of the file
next unless $sawapproved ||= /^Approved changes/;
- print "\n\n=== $lines[0]" and next if $lines[0] =~ /^[A-Z].*:$/i;
- # Backport entry?
- handle_entry @lines and next if $lines[0] =~ /^ \*/ and $sawapproved;
-
- warn "Unknown entry '$lines[0]' at $ARGV:$.\n";
+ given ($lines[0]) {
+ # Section header
+ when (/^[A-Z].*:$/i) {
+ print "\n\n=== $lines[0]" unless $YES;
+ }
+ # Backport entry?
+ when (/^ \*/) {
+ handle_entry @lines if $sawapproved;
+ }
+ default {
+ warn "Unknown entry '$lines[0]' at $ARGV:$.\n";
+ }
+ }
}
}