Hello,
I am re-posting this question about a possible bug in Svn because I got
no response on the users' mailing list (for the original e-mail, see
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=1065&dsMessageId=2300569).
I cannot 'svn add' or 'svn commit' a file if the file's name starts with
an at sign (@) and the specified file path contains at least one
directory element.
For example, I would expect the following behavior:
$ svn add 'dir/@File.txt'
A dir/@File.txt
but I get
$ svn add 'dir/@File.txt'
svn: warning: 'dir_at_File.txt' not found
(Note the missing slash in the Svn output.)
Appending an extra at sign to the end of the path does not help:
$ svn add 'dir/@File.txt@'
svn: warning: 'dir/@File.txt@' not found
Now the slash was maintained but the trailing at sign was maintained,
too, which makes the path invalid.
This issue can be quite easily worked around by first changing to the
directory containing the file, invoking "svn add @File.txt" (i.e.
without any directory element in the file's path) and changing back to
the original directory:
$ cd dir
$ svn add '@File.txt'
A @File.txt
$ cd ..
The more serious problem is that 'svn commit' fails the same way:
$ svn commit -m 'added file' 'dir/@File.txt'
svn: Commit failed (details follow):
svn: '/home/mp/wc/dir_at_File.txt' is not under version control
$ svn commit -m 'added file' 'dir/@File.txt@'
svn: Commit failed (details follow):
svn: '/home/mp/wc/dir/@File.txt@' is not under version control
In some cases, this issue can be worked around by committing the whole
directory. But it is not an option if a subset of files in the given
directory is to be committed.
I attached a test script (for Unix-like systems). It creates two
subdirectories in the current directory ("working-copy", "test-repo")
and runs a test on them, displaying the executed commands on the console
as if invoked by the user.
Environment:
Operating system:
Linux - Debian Lenny running on x86-64
Subversion info:
Svn version 1.6.2 (r37639), compiled with:
gcc (Debian 4.3.2-1.1) 4.3.2
Configuration options:
--with-berkeley-db=db.h:/usr/include:/usr/lib:db-4.6
--with-gnome-keyring
--enable-javahl
--with-jdk=/usr/local/java/jdk1.5.0_18
--with-junit=/usr/local/java/junit3.8.1/junit.jar
uname -m = x86_64
uname -r = 2.6.26-1-amd64
uname -s = Linux
uname -v = #1 SMP Fri Mar 13 17:46:45 UTC 2009
No private modifications.
Berkeley DB: 4.6
The problem is only with the command-line client. When JavaHL is used to
invoke the equivalent commands, everything works. This was discovered
during evaluation of a bug reported to the NetBeans project
(http://www.netbeans.org/issues/show_bug.cgi?id=165329). The Subversion
module of the NetBeans IDE prefers JavaHL but if it does not find one,
it falls back to using the command-line client.
I have also reproduced this behavior on the following systems:
Linux (Debian Lenny, x86-64)
Subversion version 1.5.1 (r32289)
Linux (openSUSE, x86-64)
Subversion version 1.6.0 (r36650)
Windows XP 32-bit
Subversion version 1.6.1 (r37116)
Marián Petráš
developer of the NetBeans IDE
------------------------------------------------------
http://subversion.tigris.org/ds/viewMessage.do?dsForumId=462&dsMessageId=2353599
#!/bin/sh
check_arg() {
#
# Checks whether the second argument contains an apostrophe character.
# If so, displays an error message on the error output and interrupts the script.
#
if echo "$2" | fgrep -q \'; then
echo "Argument to \"$1\" must not contain character \"'\" (apostrophe)." >&2
exit 1
fi
}
runcmd() {
#
# Runs the given command and and also displays what is being executed as if it was typed in the console.
#
local RUNCMD_PROMPT='$'
local display_args_count=all
case "$1" in
-d[1-9])
# Only display the first given number of arguments, hide the rest of the command-line
display_args_count=`echo $1 | cut -c 3-`
shift
;;
esac
check_arg "$0" "$1"
if echo "$1" | fgrep -q ' '; then
if ! test $display_args_count = 0; then
display_line="$RUNCMD_PROMPT '$1'"
else
display_line=
fi
cmd_line="'$1'"
else
if ! test $display_args_count = 0; then
display_line="$RUNCMD_PROMPT $1"
else
display_line=
fi
cmd_line="$1"
fi
shift
if ! test '(' $display_args_count = all ')' -o '(' $display_args_count = 0 ')'; then
display_args_count=`expr $display_args_count - 1`
fi
while ! test $# = 0; do
check_arg "$0" "$1"
if echo "$1" | fgrep -q ' '; then
if ! test $display_args_count = 0; then
display_line="$display_line '$1'"
fi
cmd_line="$cmd_line '$1'"
else
if ! test $display_args_count = 0; then
display_line="$display_line $1"
fi
cmd_line="$cmd_line $1"
fi
shift
if ! test '(' $display_args_count = all ')' -o '(' $display_args_count = 0 ')'; then
display_args_count=`expr $display_args_count - 1`
fi
done
echo $display_line
eval $cmd_line
}
trycmd() {
#
# Runs the given command trough 'runcmd' and checks whether execution of the command was successful.
# The test for success is not done the common way, i.e. by checking the return code.
# Instead, a command execution is considered successful if and only if the command has written
# something on the standard output.
#
tmpfile="svn-cmd-output.txt"
runcmd -d$# "$@" \| tee "$tmpfile"
outputsize=`wc -c "$tmpfile" | awk '{ print $1 }'`
rm "$tmpfile"
echo "x$outputsize" | grep -q '^x[1-9][0-9]*$'
return $?
}
echo
runcmd svnadmin create test-repo
runcmd mkdir working-copy
runcmd svn checkout file://`pwd | sed -e 's/ /%20/g'`/test-repo "`pwd`/working-copy"
runcmd cd working-copy
runcmd mkdir newdir
runcmd svn add newdir
runcmd svn commit -m "added dir \"newdir\""
runcmd echo 'Hello, world!' \> "newdir/\@NewFile.txt"
trycmd svn add "newdir/@NewFile.txt"
if ! test $? = 0; then
trycmd svn add "newdir/@NewFile.txt@"
fi
if ! test $? = 0; then
runcmd cd newdir
runcmd svn add "@NewFile.txt"
runcmd cd ..
fi
trycmd svn commit -m "added file \"newdir/@NewFile.txt\"" "newdir/@NewFile.txt"
if ! test $? = 0; then
trycmd svn commit -m "added file \"newdir/@NewFile.txt\"" "newdir/@NewFile.txt@"
fi
runcmd cd ..
echo
Received on 2009-05-26 07:28:47 CEST