+1
I think this is a very good idea -- we should take as many steps as
possible to prevent people from accidentally corrupting their base
files. The steps need not be mutually exclusive, and include:
1. making base files read-only, so it's harder to accidentally edit
them, see issue #532,
2. making sure they never show up as a filename in a patch file,
which we can do with --label (not sure if there's an issue # for
that?),
3. storing checksums for bases (issue #549), plus perhaps a
semi-automated mechanism for refetching whenever a checksum
shows that something got corrupted,
4. Kevin's patch below, which makes all base files have a special
extension, thus foiling `find', tags tables, and other common
ways people might accidentally end up in their text base files.
If anyone has reservations about #4, please say something... and we
should wait a couple of days before applying this, so there's time
to discuss if anyone objects.
(By the way, rather than ask people to re-checkout their working
copies for #4, Kevin, could you post a script to convert their working
copies to the new format?)
-K
Kevin Pilch-Bisson <kevin@pilch-bisson.net> writes:
> Subject and below says it all, except that I get no errors, or warnings, and
> all tests pass both over ra_local, and ra_dav.
>
> Log:
>
> Rename all files in .svn/tmp/text-base/, .svn/text-base,
> .svn/tmp/prop-base, and .svn/prop-base to have ".svn-base" as an extension.
> This will make it so that people's scripts which rely on
> "find . -name '*.[ch]'" will continue to work when they switch to
> subversion.
>
> **** NOTE: This will invalidate your working copy if applied. You
> **** _*WILL*_ have to recheckout subversion if you apply it.
>
> * subversion/libsvn_wc/wc.h: Add #define for SVN_WC__BASE_EXT
>
> * subversion/libsvn_wc/props.c
> (svn_wc__do_property_merge): Append SVN_WC__BASE_EXT to real_base_props,
> and tmp_base_props when constructing their paths.
>
> * subversion/libsvn_wc/adm_files.c
> (svn_wc__sync_text_base): Add SVN_WC__BASE_EXT to filename when getting
> constructing text_base name.
>
> (thing_path): Removed, logic placed in svn_wc__text_base_path, since that
> was the only caller.
>
> (svn_wc__text_base_path): Absorbed body of thing_path, and append
> SVN_WC__BASE_EXT to the path.
>
> (prop_path_internal): If getting the prop-base for a file, append
> SVN_WC__BASE_EXT to the propfile path.
>
> (svn_wc__open_text_base): Append SVN_WC__BASE_EXT to the path.
>
> (svn_wc__close_text_base): Append SVN_WC__BASE_EXT to the path.
>
> (svn_wc__open_props): If opening props for a file, and we want the base
> props, append SVN_WC__BASE_EXT to the propfile's path.
>
> (svn_wc__close_props): If closing props for a file, and they were the base
> props, append SVN_WC__BASE_EXT to the propfile's path.
>
> (svn_wc__sync_props): If we are syncing the base props file for a file
> (not dir), then append SVN_WC__BASE_EXT to the path of the file to
> sync.
>
> The rest merely change comments to reflect the latest names for things in
> the adminstrative file.
>
> * subversion/libsvn_wc/props.c:
> * subversion/libsvn_wc/adm_crawler.c:
> * subversion/libsvn_wc/log.c: change SVN/ to .svn/ in comments.
>
> * subversion/libsvn_wc/adm_ops.c:
> * subversion/libsvn_wc/get_editor.c:
> * subversion/libsvn_wc/questions.c: change SVN/ to .svn/ and add ".svn-base"
> to example paths in text-base and prop-base in comments.
>
> Index: ./subversion/libsvn_wc/props.c
> ===================================================================
> --- ./subversion/libsvn_wc/.svn/text-base/props.c Tue Nov 6 09:00:13 2001
> +++ ./subversion/libsvn_wc/props.c Thu Nov 8 12:27:37 2001
> @@ -581,18 +581,18 @@
> if (err) return err;
>
> /* Write the merged pristine prop hash to either
> - path/SVN/tmp/prop-base/name or path/SVN/tmp/dir-prop-base */
> + path/.svn/tmp/prop-base/name or path/.svn/tmp/dir-prop-base */
> err = svn_wc__save_prop_file (base_prop_tmp_path, basehash, pool);
> if (err) return err;
>
> - /* Write the merged local prop hash to path/SVN/tmp/props/name or
> - path/SVN/tmp/dir-props */
> + /* Write the merged local prop hash to path/.svn/tmp/props/name or
> + path/.svn/tmp/dir-props */
> err = svn_wc__save_prop_file (local_prop_tmp_path, localhash, pool);
> if (err) return err;
>
> /* Compute pathnames for the "mv" log entries. Notice that these
> - paths are RELATIVE pathnames (each beginning with "SVN/"), so
> - that each SVN subdir remains separable when executing run_log(). */
> + paths are RELATIVE pathnames (each beginning with ".svn/"), so
> + that each .svn subdir remains separable when executing run_log(). */
> if (is_dir)
> {
> tmp_prop_base = svn_wc__adm_path (svn_stringbuf_create ("", pool),
> @@ -625,12 +625,14 @@
> SVN_WC__ADM_PROP_BASE,
> name->data,
> NULL);
> + svn_stringbuf_appendcstr(tmp_prop_base, SVN_WC__BASE_EXT);
> real_prop_base = svn_wc__adm_path (svn_stringbuf_create ("", pool),
> 0, /* no tmp */
> pool,
> SVN_WC__ADM_PROP_BASE,
> name->data,
> NULL);
> + svn_stringbuf_appendcstr(real_prop_base, SVN_WC__BASE_EXT);
>
> tmp_props = svn_wc__adm_path (svn_stringbuf_create ("", pool),
> 1, /* tmp */
> @@ -671,7 +673,7 @@
>
> if (reject_tmp_fp)
> {
> - /* There's a .prej file sitting in SVN/tmp/ somewhere. Deal
> + /* There's a .prej file sitting in .svn/tmp/ somewhere. Deal
> with the conflicts. */
>
> /* First, _close_ this temporary conflicts file. We've been
> @@ -693,7 +695,7 @@
>
> if (! reject_path)
> {
> - /* Reserve a new .prej file *above* the SVN/ directory by
> + /* Reserve a new .prej file *above* the .svn/ directory by
> opening and closing it. */
> svn_stringbuf_t *reserved_path;
> svn_stringbuf_t *full_reject_path = svn_stringbuf_dup (path, pool);
> @@ -734,7 +736,7 @@
> }
>
> /* We've now guaranteed that some kind of .prej file exists
> - above the SVN/ dir. We write log entries to append our
> + above the .svn/ dir. We write log entries to append our
> conflicts to it. */
> svn_xml_make_open_tag (entry_accum,
> pool,
> Index: ./subversion/libsvn_wc/wc.h
> ===================================================================
> --- ./subversion/libsvn_wc/.svn/text-base/wc.h Tue Nov 6 09:00:11 2001
> +++ ./subversion/libsvn_wc/wc.h Thu Nov 8 10:30:23 2001
> @@ -31,6 +31,7 @@
> #define SVN_WC__TMP_EXT ".tmp"
> #define SVN_WC__TEXT_REJ_EXT ".rej"
> #define SVN_WC__PROP_REJ_EXT ".prej"
> +#define SVN_WC__BASE_EXT ".base-svn"
>
>
>
> Index: ./subversion/libsvn_wc/adm_crawler.c
> ===================================================================
> --- ./subversion/libsvn_wc/.svn/text-base/adm_crawler.c Thu Nov 8 08:23:49 2001
> +++ ./subversion/libsvn_wc/adm_crawler.c Thu Nov 8 09:48:56 2001
> @@ -1616,9 +1616,9 @@
> apr_hash_this (hi, &key, &klen, &val);
> keystring = (const char *) key;
>
> - /* If the dirent isn't in `SVN/entries'... */
> + /* If the dirent isn't in `.svn/entries'... */
> if (! apr_hash_get (entries, key, klen))
> - /* and we're not looking at SVN... */
> + /* and we're not looking at .svn... */
> if (strcmp (keystring, SVN_WC_ADM_DIR_NAME))
> {
> svn_boolean_t print_item = TRUE;
> Index: ./subversion/libsvn_wc/log.c
> ===================================================================
> --- ./subversion/libsvn_wc/.svn/text-base/log.c Tue Nov 6 09:00:11 2001
> +++ ./subversion/libsvn_wc/log.c Thu Nov 8 09:51:18 2001
> @@ -755,7 +755,7 @@
>
> if (is_this_dir)
> /* Drop a 'killme' file into my own adminstrative dir;
> - this signals the svn_wc__run_log() to blow away SVN/
> + this signals the svn_wc__run_log() to blow away .svn/
> after its done with this logfile. */
> SVN_ERR (svn_wc__make_adm_thing (loggy->path,
> SVN_WC__ADM_KILLME,
> Index: ./subversion/libsvn_wc/adm_ops.c
> ===================================================================
> --- ./subversion/libsvn_wc/.svn/text-base/adm_ops.c Thu Nov 8 08:23:50 2001
> +++ ./subversion/libsvn_wc/adm_ops.c Thu Nov 8 09:49:43 2001
> @@ -1156,7 +1156,8 @@
> svn_wc__entry_remove (entries, name);
> SVN_ERR (svn_wc__entries_write (entries, path, pool));
>
> - /* Remove text-base/NAME, prop/NAME, prop-base/NAME, wcprops/NAME */
> + /* Remove text-base/NAME.svn-base, prop/NAME, prop-base/NAME.svn-base,
> + wcprops/NAME */
> {
> svn_stringbuf_t *svn_thang;
>
> @@ -1248,7 +1249,7 @@
> /* At this point, every directory below this one has been
> removed from revision control. */
>
> - /* Remove the entire administrative SVN area, thereby removing
> + /* Remove the entire administrative .svn area, thereby removing
> _this_ dir from revision control too. */
> SVN_ERR (svn_wc__adm_destroy (path, subpool));
>
> @@ -1258,7 +1259,7 @@
> if (destroy_wf && (! left_a_file))
> {
> /* If the dir is *truly* empty (i.e. has no unversioned
> - resources, all versioned files are gone, all SVN dirs are
> + resources, all versioned files are gone, all .svn dirs are
> gone, and contains nothing but empty dirs), then a
> *non*-recursive dir_remove should work. If it doesn't,
> no big deal. Just assume there are unversioned items in
> @@ -1319,7 +1320,7 @@
> svn_stringbuf_t *file = svn_stringbuf_create (filename, pool);
>
> /* Create/overwrite the file in PATH's administrative area.
> - (In reality, this opens a file 'path/SVN/tmp/auth/filename'.) */
> + (In reality, this opens a file 'path/.svn/tmp/auth/filename'.) */
> SVN_ERR (svn_wc__open_auth_file (&fp, path, file,
> (APR_WRITE | APR_CREATE | APR_TRUNCATE),
> pool));
> Index: ./subversion/libsvn_wc/adm_files.c
> ===================================================================
> --- ./subversion/libsvn_wc/.svn/text-base/adm_files.c Tue Nov 6 09:00:10 2001
> +++ ./subversion/libsvn_wc/adm_files.c Thu Nov 8 11:57:08 2001
> @@ -339,6 +339,7 @@
> {
> svn_stringbuf_t *newpath, *basename;
> svn_path_split (path, &newpath, &basename, svn_path_local_style, pool);
> + svn_stringbuf_appendcstr (basename, SVN_WC__BASE_EXT);
> return sync_adm_file (newpath,
> pool,
> SVN_WC__ADM_TEXT_BASE,
> @@ -346,21 +347,19 @@
> NULL);
> }
>
> -
> -static svn_stringbuf_t *
> -thing_path (const svn_stringbuf_t *path,
> - const char *thing,
> - svn_boolean_t tmp,
> - apr_pool_t *pool)
> +svn_stringbuf_t *
> +svn_wc__text_base_path (const svn_stringbuf_t *path,
> + svn_boolean_t tmp,
> + apr_pool_t *pool)
> {
> svn_stringbuf_t *newpath, *basename;
> svn_path_split (path, &newpath, &basename, svn_path_local_style, pool);
> -
> + svn_stringbuf_appendcstr (basename, SVN_WC__BASE_EXT);
> extend_with_adm_name (newpath,
> 0,
> pool,
> tmp ? SVN_WC__ADM_TMP : "",
> - thing,
> + SVN_WC__ADM_TEXT_BASE,
> basename->data,
> NULL);
>
> @@ -368,15 +367,6 @@
> }
>
>
> -svn_stringbuf_t *
> -svn_wc__text_base_path (const svn_stringbuf_t *path,
> - svn_boolean_t tmp,
> - apr_pool_t *pool)
> -{
> - return thing_path (path, SVN_WC__ADM_TEXT_BASE, tmp, pool);
> -}
> -
> -
> static svn_error_t *
> prop_path_internal (svn_stringbuf_t **prop_path,
> const svn_stringbuf_t *path,
> @@ -432,6 +422,9 @@
> "svn_wc__prop_path: %s is not a working copy directory",
> (*prop_path)->data);
>
> + if (base)
> + svn_stringbuf_appendcstr (entry_name, SVN_WC__BASE_EXT);
> +
> extend_with_adm_name (*prop_path,
> 0,
> pool,
> @@ -714,6 +707,7 @@
> {
> svn_stringbuf_t *newpath, *basename;
> svn_path_split (path, &newpath, &basename, svn_path_local_style, pool);
> + svn_stringbuf_appendcstr (basename, SVN_WC__BASE_EXT);
> return open_adm_file (handle, newpath, flags, pool,
> SVN_WC__ADM_TEXT_BASE, basename->data, NULL);
> }
> @@ -727,6 +721,7 @@
> {
> svn_stringbuf_t *newpath, *basename;
> svn_path_split (path, &newpath, &basename, svn_path_local_style, pool);
> + svn_stringbuf_appendcstr (basename, SVN_WC__BASE_EXT);
> return close_adm_file (fp, newpath, write, pool,
> SVN_WC__ADM_TEXT_BASE, basename->data, NULL);
> }
> @@ -790,8 +785,11 @@
> return open_adm_file (handle, parent_dir, flags, pool,
> SVN_WC__ADM_DIR_PROP_BASE, NULL);
> else
> - return open_adm_file (handle, parent_dir, flags, pool,
> - SVN_WC__ADM_PROP_BASE, basename->data, NULL);
> + {
> + svn_stringbuf_appendcstr (basename, SVN_WC__BASE_EXT);
> + return open_adm_file (handle, parent_dir, flags, pool,
> + SVN_WC__ADM_PROP_BASE, basename->data, NULL);
> + }
> }
> else if (wcprops)
> {
> @@ -850,8 +848,11 @@
> return close_adm_file (fp, parent_dir, sync, pool,
> SVN_WC__ADM_DIR_PROP_BASE, NULL);
> else
> - return close_adm_file (fp, parent_dir, sync, pool,
> - SVN_WC__ADM_PROP_BASE, basename->data, NULL);
> + {
> + svn_stringbuf_appendcstr (basename, SVN_WC__BASE_EXT);
> + return close_adm_file (fp, parent_dir, sync, pool,
> + SVN_WC__ADM_PROP_BASE, basename->data, NULL);
> + }
> }
> else if (wcprops)
> {
> @@ -909,8 +910,11 @@
> return sync_adm_file (parent_dir, pool,
> SVN_WC__ADM_DIR_PROP_BASE, NULL);
> else
> - return sync_adm_file (parent_dir, pool,
> - SVN_WC__ADM_PROP_BASE, basename->data, NULL);
> + {
> + svn_stringbuf_appendcstr (basename, SVN_WC__BASE_EXT);
> + return sync_adm_file (parent_dir, pool,
> + SVN_WC__ADM_PROP_BASE, basename->data, NULL);
> + }
> }
> else if (wcprops)
> {
> Index: ./subversion/libsvn_wc/get_editor.c
> ===================================================================
> --- ./subversion/libsvn_wc/.svn/text-base/get_editor.c Tue Nov 6 09:00:09 2001
> +++ ./subversion/libsvn_wc/get_editor.c Thu Nov 8 09:51:02 2001
> @@ -868,7 +868,7 @@
> it's a hash; and we know that we won't lose any local mods. Let
> the existing entry be overwritten. */
>
> - /* If replacing, make sure the SVN entry already exists. */
> + /* If replacing, make sure the .svn entry already exists. */
> if ((! adding) && (! entry))
> return svn_error_createf (SVN_ERR_WC_ENTRY_NOT_FOUND, 0, NULL,
> parent_dir_baton->pool,
> @@ -1065,23 +1065,23 @@
> true:
>
> - The new pristine text of F, if any, is present in
> - SVN/tmp/text-base/F, and the file_baton->text_changed is
> - set if necessary.
> + .svn/tmp/text-base/F.svn-base, and the file_baton->text_changed
> + is set if necessary.
>
> - The new pristine props for F, if any, are present in
> the file_baton->propchanges array, and
> file_baton->prop_changed is set.
>
> - - The SVN/entries file still reflects the old F.
> + - The .svn/entries file still reflects the old F.
>
> - - SVN/text-base/F is the old pristine F.
> + - .svn/text-base/F.svn-base is the old pristine F.
>
> - - SVN/prop-base/F is the old pristine F props.
> + - .svn/prop-base/F.svn-base is the old pristine F props.
>
> The goal is to update the local working copy of F to reflect
> the changes received from the repository, preserving any local
> modifications, in an interrupt-safe way. So we first write our
> - intentions to SVN/log, then run over the log file doing each
> + intentions to .svn/log, then run over the log file doing each
> operation in turn. For a given operation, you can tell by
> inspection whether or not it has already been done; thus, those
> that have already been done are no-ops, and when we reach the
> @@ -1091,10 +1091,12 @@
> operations to update F is this:
>
> 1. receive svndiff data D
> - 2. svnpatch SVN/text-base/F < D > SVN/tmp/text-base/F
> - 3. gdiff -c SVN/text-base/F SVN/tmp/text-base/F > SVN/tmp/F.blah.tmp
> - 4. cp SVN/tmp/text-base/F SVN/text-base/F
> - 5. gpatch F < SVN/tmp/F.tmpfile
> + 2. svnpatch .svn/text-base/F.svn-base < D >
> + .svn/tmp/text-base/F.svn-base
> + 3. gdiff -c .svn/text-base/F.svn-base .svn/tmp/text-base/F.svn-base
> + > .svn/tmp/F.blah.tmp
> + 4. cp .svn/tmp/text-base/F.svn-base .svn/text-base/F.svn-base
> + 5. gpatch F < .svn/tmp/F.tmpfile
> ==> possibly producing F.blah.rej
>
> */
> Index: ./subversion/libsvn_wc/questions.c
> ===================================================================
> --- ./subversion/libsvn_wc/.svn/text-base/questions.c Tue Nov 6 14:43:40 2001
> +++ ./subversion/libsvn_wc/questions.c Thu Nov 8 10:57:02 2001
> @@ -83,11 +83,13 @@
>
> /* svn_wc_text_modified_p answers the question:
>
> - "Are the contents of F different than the contents of SVN/text-base/F?"
> + "Are the contents of F different than the contents of
> + .svn/text-base/F.svn-base?"
>
> or
>
> - "Are the contents of SVN/props/xxx different than SVN/prop-base/xxx?"
> + "Are the contents of .svn/props/xxx different than
> + .svn/prop-base/xxx.svn-base?"
>
> In other words, we're looking to see if a user has made local
> modifications to a file since the last update or commit.
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Oct 21 14:36:48 2006