Author: stsp
Date: Sat Dec 19 14:13:18 2009
New Revision: 892471
URL: http://svn.apache.org/viewvc?rev=892471&view=rev
Log:
Allow keyword expansion to be disabled during 'svn export' using
a new --ignore-keywords option.
In some scenarios expanded keywords create unnecessary noise.
E.g. if files exported from Subversion need to be compared with files
from other sources, such as after a migration from another version
control system to Subversion.
Or, if two Subversion URLs need to be compared reliably using 'svn export'
(currently a 2-URL diff from 'svn diff' doesn't show deleted files properly,
see issue #2333).
* subversion/include/svn_client.h
(svn_client_export5): Declare, document new ignore_keywords parameter.
(svn_client_export4): Deprecate.
* subversion/libsvn_client/deprecated.c
(svn_client_export4): Moved here from ...
* subversion/libsvn_client/export.c
(svn_client_export4): ... here.
(copy_one_versioned_file, copy_versioned_files): Add and handle new
ignore_keywords parameter.
(edit_baton): Add ignore_keywords field.
(change_file_prop): Heed new ignore_keywords in edit_baton.
(svn_client_export5): Add ignore_keywords parameter, pass it on to
the edit_baton and copy_versioned_files().
* subversion/svn/cl.h
(svn_cl__opt_state_t): Add ignore_keywords field.
* subversion/svn/export-cmd.c
(svn_cl__export): Upgrade to svn_client_export5().
* subversion/svn/main.c
(svn_cl__longopt_t): Add opt_ignore_keywords field.
(svn_cl__options): Add entry for --ignore-keywords, alias --ik.
(svn_cl__cmd_table): Add opt_ignore_keywords to the list of options
supported by 'svn export'.
(main): Handle new --ignore-keywords option.
* subversion/tests/cmdline/export_tests.py
(export_ignoring_keyword_translation,
export_working_copy_ignoring_keyword_translation): New tests.
(test_list): Add new tests.
Modified:
subversion/trunk/subversion/include/svn_client.h
subversion/trunk/subversion/libsvn_client/deprecated.c
subversion/trunk/subversion/libsvn_client/export.c
subversion/trunk/subversion/svn/cl.h
subversion/trunk/subversion/svn/export-cmd.c
subversion/trunk/subversion/svn/main.c
subversion/trunk/subversion/tests/cmdline/export_tests.py
Modified: subversion/trunk/subversion/include/svn_client.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_client.h?rev=892471&r1=892470&r2=892471&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_client.h (original)
+++ subversion/trunk/subversion/include/svn_client.h Sat Dec 19 14:13:18 2009
@@ -4033,6 +4033,9 @@
* If @a ignore_externals is set, don't process externals definitions
* as part of this operation.
*
+ * If @a ignore_keywords is set, don't expand keywords as part of this
+ * operation.
+ *
* @a native_eol allows you to override the standard eol marker on the platform
* you are running on. Can be either "LF", "CR" or "CRLF" or NULL. If NULL
* will use the standard eol marker. Any other value will cause the
@@ -4047,6 +4050,28 @@
*
* All allocations are done in @a pool.
*
+ * @since New in 1.7.
+ */
+svn_error_t *
+svn_client_export5(svn_revnum_t *result_rev,
+ const char *from,
+ const char *to,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_boolean_t overwrite,
+ svn_boolean_t ignore_externals,
+ svn_boolean_t ignore_keywords,
+ svn_depth_t depth,
+ const char *native_eol,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool);
+
+/**
+ * Similar to svn_client_export5(), but with @a ignore_keywords set
+ * to FALSE.
+ *
+ * @deprecated Provided for backward compatibility with the 1.5 API.
+ *
* @since New in 1.5.
*/
svn_error_t *
Modified: subversion/trunk/subversion/libsvn_client/deprecated.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/deprecated.c?rev=892471&r1=892470&r2=892471&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/deprecated.c (original)
+++ subversion/trunk/subversion/libsvn_client/deprecated.c Sat Dec 19 14:13:18
2009
@@ -860,6 +860,24 @@
/*** From export.c ***/
svn_error_t *
+svn_client_export4(svn_revnum_t *result_rev,
+ const char *from,
+ const char *to,
+ const svn_opt_revision_t *peg_revision,
+ const svn_opt_revision_t *revision,
+ svn_boolean_t overwrite,
+ svn_boolean_t ignore_externals,
+ svn_depth_t depth,
+ const char *native_eol,
+ svn_client_ctx_t *ctx,
+ apr_pool_t *pool)
+{
+ return svn_client_export5(result_rev, from, to, peg_revision, revision,
+ overwrite, ignore_externals, FALSE, depth,
+ native_eol, ctx, pool);
+}
+
+svn_error_t *
svn_client_export3(svn_revnum_t *result_rev,
const char *from,
const char *to,
Modified: subversion/trunk/subversion/libsvn_client/export.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/export.c?rev=892471&r1=892470&r2=892471&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/export.c (original)
+++ subversion/trunk/subversion/libsvn_client/export.c Sat Dec 19 14:13:18 2009
@@ -101,6 +101,7 @@
svn_wc_context_t *wc_ctx,
const svn_opt_revision_t *revision,
const char *native_eol,
+ svn_boolean_t ignore_keywords,
apr_pool_t *scratch_pool)
{
const svn_wc_entry_t *entry;
@@ -245,7 +246,7 @@
eol,
FALSE /* repair */,
kw,
- TRUE /* expand */,
+ ! ignore_keywords /* expand */,
scratch_pool);
/* ###: use cancel func/baton in place of NULL/NULL below. */
@@ -271,6 +272,7 @@
const svn_opt_revision_t *revision,
svn_boolean_t force,
svn_boolean_t ignore_externals,
+ svn_boolean_t ignore_keywords,
svn_depth_t depth,
const char *native_eol,
svn_client_ctx_t *ctx,
@@ -369,7 +371,8 @@
SVN_ERR(copy_versioned_files(new_from, new_to,
revision, force,
- ignore_externals, depth,
+ ignore_externals,
+ ignore_keywords, depth,
native_eol, ctx, iterpool));
}
}
@@ -391,7 +394,8 @@
SVN_ERR(copy_one_versioned_file(new_from_abspath, new_to_abspath,
ctx->wc_ctx, revision,
- native_eol, iterpool));
+ native_eol, ignore_keywords,
+ iterpool));
}
}
@@ -435,6 +439,7 @@
SVN_ERR(copy_versioned_files(new_from, new_to,
revision, force, FALSE,
+ ignore_keywords,
svn_depth_infinity, native_eol,
ctx, iterpool));
}
@@ -446,7 +451,8 @@
else if (from_kind == svn_node_file)
{
SVN_ERR(copy_one_versioned_file(from_abspath, to_abspath, ctx->wc_ctx,
- revision, native_eol, pool));
+ revision, native_eol, ignore_keywords,
+ pool));
}
return SVN_NO_ERROR;
@@ -511,6 +517,7 @@
svn_revnum_t *target_revision;
apr_hash_t *externals;
const char *native_eol;
+ svn_boolean_t ignore_keywords;
svn_wc_notify_func2_t notify_func;
void *notify_baton;
@@ -739,7 +746,8 @@
if (strcmp(name, SVN_PROP_EOL_STYLE) == 0)
fb->eol_style_val = svn_string_dup(value, fb->pool);
- else if (strcmp(name, SVN_PROP_KEYWORDS) == 0)
+ else if (! fb->edit_baton->ignore_keywords &&
+ strcmp(name, SVN_PROP_KEYWORDS) == 0)
fb->keywords_val = svn_string_dup(value, fb->pool);
else if (strcmp(name, SVN_PROP_EXECUTABLE) == 0)
@@ -868,13 +876,14 @@
/*** Public Interfaces ***/
svn_error_t *
-svn_client_export4(svn_revnum_t *result_rev,
+svn_client_export5(svn_revnum_t *result_rev,
const char *from,
const char *to,
const svn_opt_revision_t *peg_revision,
const svn_opt_revision_t *revision,
svn_boolean_t overwrite,
svn_boolean_t ignore_externals,
+ svn_boolean_t ignore_keywords,
svn_depth_t depth,
const char *native_eol,
svn_client_ctx_t *ctx,
@@ -915,6 +924,7 @@
eb->notify_baton = ctx->notify_baton2;
eb->externals = apr_hash_make(pool);
eb->native_eol = native_eol;
+ eb->ignore_keywords = ignore_keywords;
SVN_ERR(svn_ra_check_path(ra_session, "", revnum, &kind, pool));
@@ -1038,8 +1048,8 @@
/* This is a working copy export. */
/* just copy the contents of the working copy into the target path. */
SVN_ERR(copy_versioned_files(from, to, revision, overwrite,
- ignore_externals, depth, native_eol,
- ctx, pool));
+ ignore_externals, ignore_keywords,
+ depth, native_eol, ctx, pool));
}
Modified: subversion/trunk/subversion/svn/cl.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=892471&r1=892470&r2=892471&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Sat Dec 19 14:13:18 2009
@@ -222,6 +222,7 @@
svn_boolean_t trust_server_cert; /* trust server SSL certs that would
otherwise be rejected as "untrusted" */
int strip_count; /* number of leading path components to strip */
+ svn_boolean_t ignore_keywords; /* do not expand keywords */
} svn_cl__opt_state_t;
Modified: subversion/trunk/subversion/svn/export-cmd.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/export-cmd.c?rev=892471&r1=892470&r2=892471&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/export-cmd.c (original)
+++ subversion/trunk/subversion/svn/export-cmd.c Sat Dec 19 14:13:18 2009
@@ -91,12 +91,11 @@
opt_state->depth = svn_depth_infinity;
/* Do the export. */
- err = svn_client_export4(NULL, truefrom, to, &peg_revision,
+ err = svn_client_export5(NULL, truefrom, to, &peg_revision,
&(opt_state->start_revision),
opt_state->force, opt_state->ignore_externals,
- opt_state->depth,
- opt_state->native_eol, ctx,
- pool);
+ opt_state->ignore_keywords, opt_state->depth,
+ opt_state->native_eol, ctx, pool);
if (err && err->apr_err == SVN_ERR_WC_OBSTRUCTED_UPDATE && !opt_state->force)
SVN_ERR_W(err,
_("Destination directory exists; please remove "
Modified: subversion/trunk/subversion/svn/main.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/main.c?rev=892471&r1=892470&r2=892471&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/main.c (original)
+++ subversion/trunk/subversion/svn/main.c Sat Dec 19 14:13:18 2009
@@ -114,7 +114,8 @@
opt_show_revs,
opt_reintegrate,
opt_trust_server_cert,
- opt_show_copies_as_adds
+ opt_show_copies_as_adds,
+ opt_ignore_keywords
} svn_cl__longopt_t;
/* Option codes and descriptions for the command line client.
@@ -309,6 +310,10 @@
"while -p2 would give just crunchy.html")},
{"show-copies-as-adds", opt_show_copies_as_adds, 0,
N_("don't diff copied or moved files with their source")},
+ {"ignore-keywords", opt_ignore_keywords, 0,
+ N_("don't expand keywords\n"
+ " "
+ "[aliases: --ik]")},
/* Long-opt Aliases
*
@@ -318,6 +323,7 @@
{"cl", opt_changelist, 1, NULL},
{"ie", opt_ignore_externals, 0, NULL},
+ {"ik", opt_ignore_keywords, 0, NULL},
{0, 0, 0, 0},
};
@@ -514,7 +520,8 @@
"\n"
" If specified, PEGREV determines in which revision the target is
first\n"
" looked up.\n"),
- {'r', 'q', 'N', opt_depth, opt_force, opt_native_eol,
opt_ignore_externals} },
+ {'r', 'q', 'N', opt_depth, opt_force, opt_native_eol, opt_ignore_externals,
+ opt_ignore_keywords} },
{ "help", svn_cl__help, {"?", "h"}, N_
("Describe the usage of this program or its subcommands.\n"
@@ -1660,6 +1667,9 @@
}
}
break;
+ case opt_ignore_keywords:
+ opt_state.ignore_keywords = TRUE;
+ break;
default:
/* Hmmm. Perhaps this would be a good place to squirrel away
opts that commands like svn diff might need. Hmmm indeed. */
Modified: subversion/trunk/subversion/tests/cmdline/export_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/export_tests.py?rev=892471&r1=892470&r2=892471&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/export_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/export_tests.py Sat Dec 19
14:13:18 2009
@@ -422,6 +422,67 @@
'.', expected_output,
expected_disk)
+def export_ignoring_keyword_translation(sbox):
+ "export ignoring keyword translation"
+ sbox.build()
+
+ wc_dir = sbox.wc_dir
+
+ # Add a keyword to A/mu and set the svn:keywords property
+ # appropriately to make sure it's not translated during
+ # the export operation
+ mu_path = os.path.join(wc_dir, 'A', 'mu')
+ svntest.main.file_append(mu_path, '$LastChangedRevision$')
+ svntest.main.run_svn(None, 'ps', 'svn:keywords',
+ 'LastChangedRevision', mu_path)
+ svntest.main.run_svn(None, 'ci',
+ '-m', 'Added keyword to mu', mu_path)
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu',
+ contents=expected_disk.desc['A/mu'].contents +
+ '$LastChangedRevision$')
+
+ export_target = sbox.add_wc_path('export')
+
+ expected_output = svntest.main.greek_state.copy()
+ expected_output.wc_dir = export_target
+ expected_output.desc[''] = Item()
+ expected_output.tweak(contents=None, status='A ')
+
+ svntest.actions.run_and_verify_export(sbox.repo_url,
+ export_target,
+ expected_output,
+ expected_disk,
+ "--ignore-keywords")
+
+def export_working_copy_ignoring_keyword_translation(sbox):
+ "export working copy ignoring keyword translation"
+ sbox.build(read_only = True)
+
+ wc_dir = sbox.wc_dir
+
+ # Add a keyword to A/mu and set the svn:keywords property
+ # appropriately to make sure it's not translated during
+ # the export operation
+ mu_path = os.path.join(wc_dir, 'A', 'mu')
+ svntest.main.file_append(mu_path, '$LastChangedRevision$')
+ svntest.main.run_svn(None, 'ps', 'svn:keywords',
+ 'LastChangedRevision', mu_path)
+
+ expected_disk = svntest.main.greek_state.copy()
+ expected_disk.tweak('A/mu',
+ contents=expected_disk.desc['A/mu'].contents +
+ '$LastChangedRevision$')
+
+ export_target = sbox.add_wc_path('export')
+
+ svntest.actions.run_and_verify_export(wc_dir,
+ export_target,
+ svntest.wc.State(sbox.wc_dir, {}),
+ expected_disk,
+ "--ignore-keywords")
+
########################################################################
# Run the tests
@@ -446,6 +507,8 @@
export_creates_intermediate_folders,
export_HEADplus1_fails,
export_to_explicit_cwd,
+ export_ignoring_keyword_translation,
+ export_working_copy_ignoring_keyword_translation,
]
if __name__ == '__main__':