Hi, is there a good reason why a local replace has to get rid of the pristine base file? Because, if the file was kept, the problems described below would be resolved.
<tell-mode> I stumbled over an error using 'svn cat <wc_path>' on a locally replaced file. (Not a common use case, but read on.) 'svn cat <wc_path>' appears to want to output the pristine base content (which is not documented). But when a file is locally replaced (not committed), it currently has no pristine base file, apparently; 'svn cat wc/locally_replaced_file' calls svn_wc__get_pristine_contents() which errors with: [[[ $ svn cat file subversion/svn/cat-cmd.c:81: (apr_err=2) subversion/svn/util.c:960: (apr_err=2) subversion/libsvn_client/cat.c:88: (apr_err=2) subversion/libsvn_client/cat.c:88: (apr_err=2) subversion/libsvn_subr/stream.c:774: (apr_err=2) subversion/libsvn_subr/stream.c:774: (apr_err=2) subversion/libsvn_subr/io.c:2711: (apr_err=2) svn: Can't open file '/tmp/wc/.svn/text-base/file.svn-base': No such file or directory ]]] (reproduction script attached) 'svn cat' is just an example of how to hit this. This same function is used in many other places. A quick impact grep study suggests at least export, copy, update, diff, and probably others. (Todo: investigation on whether current callers can hit a locally replaced file and whether they work around it.) </tell-mode> <bug-hunting> I guess svn_wc__get_pristine_contents() wants to return the contents of the file that were committed in revision <BASE>. But the implementation expects a file to exist which isn't there: [[[ svn_error_t * svn_wc__get_pristine_contents(svn_stream_t **contents, svn_wc__db_t *db, const char *local_abspath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { const char *text_base; SVN_ERR(svn_wc__text_base_path(&text_base, db, local_abspath, FALSE, scratch_pool)); if (text_base == NULL) { *contents = NULL; return SVN_NO_ERROR; } return svn_stream_open_readonly(contents, text_base, result_pool, scratch_pool); // ^^^^^ hits error here, file *text_base does not exist. } ]]] I see two ill things: (1) Looking at the function's intention, it should return an empty stream if there is no base file. But svn_wc__text_base_path() returns a path that doesn't exist. (2) When the file is locally replaced, it theoretically *does* have a pristine base, i.e. the file's content committed at revision <BASE>. The function fails to return that content. </bug-hunting> So, back to the question: is there a good reason why a local delete followed by a local add has to get rid of the pristine base file? Thanks, ~Neels
#!/bin/bash ## TO MAKE THIS RUN YOUR CUSTOM COMPILED SVN, two simple options: ## 1. Adjust your PATH to point at your custom installed location: ## export PATH="$HOME/prefix/svn-trunk/bin:$PATH" ## OR ## 2. Uncomment the four lines below to use aliases into your ## built source tree. The next line is the only line you should ## need to adjust. #SVNDIR=/my/svn/trunk #alias svn=${SVNDIR}/subversion/svn/svn #alias svnserve=${SVNDIR}/subversion/svnserve/svnserve #alias svnadmin=${SVNDIR}/subversion/svnadmin/svnadmin svn --version REPOS="`pwd`/repos" URL="file://$REPOS" rm -rf repos wc svnadmin create repos svn co -q ${URL} wc set -x cd wc ## ACTUAL TEST # make a file that is locally replaced... echo content > file svn add file svn ci -mm svn rm file echo "new content" > file svn add file # ...and 'svn cat' that file. svn st svn cat file
signature.asc
Description: OpenPGP digital signature