Hello!
I have run across a bug with "svn merge" on files with
keyword-translation enabled. The problem arises because
svn_io_run_diff3() require LEFT, RIGHT and TARGET to be all in one
directory. Without translation all works as expected. But with
enabled translations svn_wc_translated_file() will use
svn_wc__adm_path() to create the temporary file. And svn_wc__adm_path()
forces the temp-file to be within the administrative .svn-area. BOOM.
Look below for script to trigger the bug and for a patch to fix it.
PS: I first tried to give diff3 files with paths, but that caused the
regression tests to fail. Why does diff3 require all the files in
one directory?
PS1: Sorry for not including a regression test for this patch. I
tried, but could not figure out how to do it. :-(
PS2: This patch is based on revision 2016 which is current at the
time of this writing.
-------- Snip here for script to trigger the bug. --------
#!/bin/sh
TESTDIR=/tmp/subvers.test
cd $TESTDIR || exit
set -x
# Ough! svnadmin wants a filesystem path while svn want file:///foo/bar =:)
#
arep=rep
rep=file://`pwd`/$arep
# create test repos
#
rm -fr $arep test test.wc test.wc1
svnadmin create $arep || exit
# create 1st version
#
mkdir -p test/trunk test/branches test/tags
echo '$HeadURL$' >>test/trunk/x
svn import -m "first revision" $rep test
# allow keyword substitution
#
svn co -d test.wc $rep/trunk
svn propset svn:keywords "HeadURL" test.wc/x
(cd test.wc ; svn ci -m "keyword substitution activated")
# tag 1st version
#
svn cp -m "tag it" $rep/trunk $rep/tags/V1.0
# branch from tag
#
svn cp -m "create branch" $rep/tags/V1.0 $rep/branches/V1.0
# development on trunk
#
echo 2nd vers >>test.wc/x
(cd test.wc ; svn ci -m "development")
# check out branch
#
svn co $rep/branches/V1.0 -d test.wc1
# bugfix (will create conflict later on)
#
echo bugfix >>test.wc1/x
(cd test.wc1 ; svn ci -m bugfix)
# merge bugfix into main development
#
(cd test.wc ; svn update ; svn merge $rep/tags/V1.0 $rep/branches/V1.0 )
##
## Snip here for patch
##
Log:
Fix bug with "svn merge" on files with enabled keyword translation.
svn_io_run_diff3() require the merged files to be in one directory.
* subversion/libsvn_wc/translate.c
(svn_wc_translated_file): add boolean argument ADM to request the
creation of the translated file in the administrative area
(i.e. withhin .svn directory). Otherwise the translated file will
be created in the directory where the original file resided.
* subversion/libsvn_wc/merge.c
(svn_wc_merge): Adjust accordingly. Translated file is created where
original file was.
* subversion/libsvn_wc/diff.c
(file_diff, close_file): Adjust accordingly. Translated file is
created in administrative area.
* subversion/libsvn_wc/adm_crawler.c
(svn_wc_transmit_text_deltas): Adjust accordingly. Translated file
is created where original file was.
* subversion/libsvn_wc/questions.c
(svn_wc__versioned_file_modcheck): Adjust accordingly. Translated
file is created where original file was.
* subversion/include/svn_wc.h
(svn_wc_translated_file): Adjust accordingly.
Index: ./subversion/include/svn_wc.h
===================================================================
--- ./subversion/include/svn_wc.h
+++ ./subversion/include/svn_wc.h Thu May 23 20:54:58 2002
@@ -1191,6 +1191,9 @@
* manner is indicated by VFILE's properties; otherwise, set *XLATED_P
* to VFILE.
*
+ * If ADM is zero, the returned path will be in the directory the original
+ * file was. Otherwise it will be in the adminstrative area.
+ *
* Caller is responsible for detecting if they are different (pointer
* comparison is sufficient), and for removing *XLATED_P if
* necessary.
@@ -1206,6 +1209,7 @@
*/
svn_error_t *svn_wc_translated_file (svn_stringbuf_t **xlated_p,
svn_stringbuf_t *vfile,
+ svn_boolean_t adm,
apr_pool_t *pool);
Index: ./subversion/libsvn_wc/merge.c
===================================================================
--- ./subversion/libsvn_wc/merge.c
+++ ./subversion/libsvn_wc/merge.c Fri May 24 21:58:35 2002
@@ -70,7 +70,7 @@
/* Make sure a temporary copy of 'target' is available with keywords
contracted and line endings in repository-normal (LF) form.
This is the file that diff3 will read as the 'mine' file. */
- SVN_ERR (svn_wc_translated_file (&tmp_target, full_tgt_path, pool));
+ SVN_ERR (svn_wc_translated_file (&tmp_target, full_tgt_path, 0, pool));
if (tmp_target == full_tgt_path) /* contraction didn't happen */
{
/* The target is already in repository form, so we just need to
Index: ./subversion/libsvn_wc/diff.c
===================================================================
--- ./subversion/libsvn_wc/diff.c
+++ ./subversion/libsvn_wc/diff.c Thu May 23 20:02:26 2002
@@ -414,7 +414,7 @@
tmp translated copy too. But what the heck, diff is
already expensive, translating twice for the sake of code
modularity is liveable. */
- SVN_ERR (svn_wc_translated_file (&translated, path,
+ SVN_ERR (svn_wc_translated_file (&translated, path, 1,
dir_baton->pool));
err = dir_baton->edit_baton->diff_callbacks->file_changed
@@ -904,7 +904,7 @@
svn_error_t *err1, *err2 = SVN_NO_ERROR;
svn_stringbuf_t *translated;
- SVN_ERR (svn_wc_translated_file (&translated, b->path, b->pool));
+ SVN_ERR (svn_wc_translated_file (&translated, b->path, 1, b->pool));
err1 = b->edit_baton->diff_callbacks->file_changed
(b->path->data,
Index: ./subversion/libsvn_wc/adm_crawler.c
===================================================================
--- ./subversion/libsvn_wc/adm_crawler.c
+++ ./subversion/libsvn_wc/adm_crawler.c Thu May 23 20:02:27 2002
@@ -463,7 +463,7 @@
Note that since the translation routine doesn't let you choose
the filename, we have to do one extra copy. But what the heck,
we're about to generate an svndiff anyway. */
- SVN_ERR (svn_wc_translated_file (&tmpf, path, pool));
+ SVN_ERR (svn_wc_translated_file (&tmpf, path, 1, pool));
tmp_base = svn_wc__text_base_path (path, TRUE, pool);
SVN_ERR (svn_io_copy_file (tmpf->data, tmp_base->data, FALSE, pool));
Index: ./subversion/libsvn_wc/questions.c
===================================================================
--- ./subversion/libsvn_wc/questions.c
+++ ./subversion/libsvn_wc/questions.c Thu May 23 20:02:23 2002
@@ -306,7 +306,7 @@
svn_stringbuf_t *tmp_vfile;
svn_error_t *err = SVN_NO_ERROR;
- SVN_ERR (svn_wc_translated_file (&tmp_vfile, versioned_file, pool));
+ SVN_ERR (svn_wc_translated_file (&tmp_vfile, versioned_file, 1, pool));
err = svn_wc__files_contents_same_p (&same, tmp_vfile, base_file, pool);
*modified_p = (! same);
Index: ./subversion/libsvn_wc/translate.c
===================================================================
--- ./subversion/libsvn_wc/translate.c
+++ ./subversion/libsvn_wc/translate.c Thu May 23 20:54:06 2002
@@ -705,6 +705,7 @@
svn_error_t *
svn_wc_translated_file (svn_stringbuf_t **xlated_p,
svn_stringbuf_t *vfile,
+ svn_boolean_t adm,
apr_pool_t *pool)
{
enum svn_wc__eol_style style;
@@ -730,9 +731,12 @@
svn_path_split (vfile, &tmp_dir, &tmp_vfile, pool);
- tmp_vfile = svn_wc__adm_path (tmp_dir, 1, pool,
- tmp_vfile->data, NULL);
-
+ if (adm)
+ {
+ tmp_vfile = svn_wc__adm_path (tmp_dir, 1, pool,
+ tmp_vfile->data, NULL);
+ }
+
SVN_ERR (svn_io_open_unique_file (&ignored,
&tmp_vfile,
tmp_vfile->data,
--
-- Josef Wolf -- jw@raven.inka.de --
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat May 25 00:08:15 2002