Incorrect error message on svn copy? Advice?

82 views
Skip to first unread message

Dan Ellis

unread,
May 20, 2014, 6:02:49 PM5/20/14
to Subversion Users
Hi,

I'm wondering if I'm getting an incorrect error message...

I'm attempting to copy a file from a working copy to the server, but using an incorrect case for one of the folders in the path.  The paths all exist and everything works fine using correct case.  In the example below, "FOO" exists on the server as "foo".

(Case 1)
c:\Project_files\sandbox>svn copy bar.c http://svr/repo/some_project/FOO/bar.c -m "text commit"
Adding copy of        bar.c
svn: E155011: Commit failed (details follow):
svn: E155011: File 'C:\Project_files\sandbox\bar.c' is out of date
svn: E160013: File not found: transaction '4249-3lp', path '/some_project/FOO/bar.c'

If I correctly use "foo" instead of "FOO", I get the expected response:

(Case 2)
c:\Project_files\sandbox>svn copy bar.c http://svr/repo/some_project/foo/bar.c -m "test commit"
Adding copy of        bar.c

Committed revision 4249.

If I use --parents to create the path (in case it doesn't exist):

(Case 3)
c:\Project_files\sandbox>svn copy --parents bar.c http://svr/repo/some_project/FOO/bar.c -m "test commit"
Adding copy of        bar.c
svn: E165001: Commit failed (details follow):
svn: E165001: Commit blocked by pre-commit hook (exit code 1) with output:
** ERROR-CASE: This repository is set to be case insensitive.
** ERROR-CASE: Clash: '/some_project/FOO' '/some_project/foo'

It appears we are using a server-side script to prevent name clashes (since we are using windows clients) on our server in Case 3.  Why would Case 3 get caught (--parents) but Case 1 seem to slip by this server side script and return a different error?  I assume we're using the stock case-insensitive.py, but regardless, I don't understand the behavior difference.

As I would expect, I cannot perform an "svn info" on the incorrect-cased path.  I was hoping I could do an "svn info" to test/determine what the case corrected path is, but will have to try an "svn copy --parents" first and if it fails due to a case clash, retry with the returned clash info.  Is there a better way to accomplish this?  I do understand this is more of a corner use case, especially since Subversion is (properly IMO) designed around case sensitivity.  

Thanks,
Dan

Ryan Schmidt

unread,
May 21, 2014, 6:22:46 AM5/21/14
to Dan Ellis, Subversion Users

On May 20, 2014, at 17:02, Dan Ellis wrote:

> I'm wondering if I'm getting an incorrect error message...
>
> I'm attempting to copy a file from a working copy to the server, but using an incorrect case for one of the folders in the path. The paths all exist and everything works fine using correct case. In the example below, "FOO" exists on the server as "foo".
>
> (Case 1)
> c:\Project_files\sandbox>svn copy bar.c http://svr/repo/some_project/FOO/bar.c -m "text commit"
> Adding copy of bar.c
> svn: E155011: Commit failed (details follow):
> svn: E155011: File 'C:\Project_files\sandbox\bar.c' is out of date
> svn: E160013: File not found: transaction '4249-3lp', path '/some_project/FOO/bar.c'

You're trying to create something in the non-existent directory FOO, which is an error. It never gets to the point of calling your hook script. (The message might be clearer if it said "Directory not found: …, path '/some_project/FOO'" instead of "File not found: …, path '/some_project/FOO/bar.c'".)


> If I correctly use "foo" instead of "FOO", I get the expected response:
>
> (Case 2)
> c:\Project_files\sandbox>svn copy bar.c http://svr/repo/some_project/foo/bar.c -m "test commit"
> Adding copy of bar.c
>
> Committed revision 4249.

You've asked Subversion to create a file in an existing folder. No problem.


> If I use --parents to create the path (in case it doesn't exist):
>
> (Case 3)
> c:\Project_files\sandbox>svn copy --parents bar.c http://svr/repo/some_project/FOO/bar.c -m "test commit"
> Adding copy of bar.c
> svn: E165001: Commit failed (details follow):
> svn: E165001: Commit blocked by pre-commit hook (exit code 1) with output:
> ** ERROR-CASE: This repository is set to be case insensitive.
> ** ERROR-CASE: Clash: '/some_project/FOO' '/some_project/foo'

You've asked Subversion to create a directory FOO when a directory foo already exists, which would be fine, except your hook script prevents case collisions.


> It appears we are using a server-side script to prevent name clashes (since we are using windows clients) on our server in Case 3. Why would Case 3 get caught (--parents) but Case 1 seem to slip by this server side script and return a different error? I assume we're using the stock case-insensitive.py, but regardless, I don't understand the behavior difference.
>
> As I would expect, I cannot perform an "svn info" on the incorrect-cased path. I was hoping I could do an "svn info" to test/determine what the case corrected path is, but will have to try an "svn copy --parents" first and if it fails due to a case clash, retry with the returned clash info. Is there a better way to accomplish this? I do understand this is more of a corner use case, especially since Subversion is (properly IMO) designed around case sensitivity.

What exactly are you trying to accomplish? If the problem is that you don't know the names (or cases) of the directories in the repository, then you can use "svn ls" to find out.

Dan Ellis

unread,
May 21, 2014, 10:48:40 AM5/21/14
to Ryan Schmidt, Subversion Users
On Wed, May 21, 2014 at 3:22 AM, Ryan Schmidt <subvers...@ryandesign.com> wrote:

On May 20, 2014, at 17:02, Dan Ellis wrote:

> I'm attempting to copy a file from a working copy to the server, but using an incorrect case for one of the folders in the path.  The paths all exist and everything works fine using correct case.  In the example below, "FOO" exists on the server as "foo".
>
> (Case 1)
> c:\Project_files\sandbox>svn copy bar.c http://svr/repo/some_project/FOO/bar.c -m "text commit"


You're trying to create something in the non-existent directory FOO, which is an error. It never gets to the point of calling your hook script. (The message might be clearer if it said "Directory not found: …, path '/some_project/FOO'" instead of "File not found: …, path '/some_project/FOO/bar.c'".)

> If I use --parents to create the path (in case it doesn't exist):
>
> (Case 3)
> c:\Project_files\sandbox>svn copy --parents bar.c http://svr/repo/some_project/FOO/bar.c -m "test commit"
> ** ERROR-CASE: Clash: '/some_project/FOO' '/some_project/foo'

You've asked Subversion to create a directory FOO when a directory foo already exists, which would be fine, except your hook script prevents case collisions.

My question revolves around why the different behavior/messages when the only difference is when --parents is included. One case bombs out with a cryptic message (svn: E155011: File 'C:\Project_files\sandbox\bar.c' is out of date) and the other triggers a pre-commit check.  Both would seem to have identical implementation accept when a directory is not found (--parents would create it).  Why didn't case 1 trigger the pre-commit check?  Granted, the script in question may be out of scope of this list.

>
> As I would expect, I cannot perform an "svn info" on the incorrect-cased path.  I was hoping I could do an "svn info" to test/determine what the case corrected path is, but will have to try an "svn copy --parents" first and if it fails due to a case clash, retry with the returned clash info.  Is there a better way to accomplish this?  I do understand this is more of a corner use case, especially since Subversion is (properly IMO) designed around case sensitivity.

What exactly are you trying to accomplish? If the problem is that you don't know the names (or cases) of the directories in the repository, then you can use "svn ls" to find out.

Doing an "svn ls" is burden-some when you have a lengthy path that you want to discover the case sensitive version of.  If you had A/b/C/d/E for a path, you'd have to "svn ls" on the repo to find "A" vs "a" then do another for "B" vs "b" etc.  I'd like to know of the easiest method to discover A/b/C/d/E vs doing an svn copy --parents to have the server side report back the case sensitive version of it.  Plus, from a previous email, there's no stock way to do "svn list" and return only the directory listing (you have to wade through all the files as well).

I guess the normal and usual use case is having a working copy checkout so you can locally navigate the repo structure.  In our case, we are doing an archive type of operation where we really do not want a local WC due to size and just operation on the repo directly.  svn copy works great in this case with the exception of users getting case confused.  

I appreciate the feedback.

Thanks
Dan

Ryan Schmidt

unread,
May 21, 2014, 10:00:13 PM5/21/14
to Dan Ellis, Subversion Users
On May 21, 2014, at 09:48, Dan Ellis wrote:

> On Wed, May 21, 2014 at 3:22 AM, Ryan Schmidt wrote:
>
>> On May 20, 2014, at 17:02, Dan Ellis wrote:
>>
>>> I'm attempting to copy a file from a working copy to the server, but using an incorrect case for one of the folders in the path. The paths all exist and everything works fine using correct case. In the example below, "FOO" exists on the server as "foo".
>>>
>>> (Case 1)
>>> c:\Project_files\sandbox>svn copy bar.c http://svr/repo/some_project/FOO/bar.c -m "text commit"
>>
>> You're trying to create something in the non-existent directory FOO, which is an error. It never gets to the point of calling your hook script. (The message might be clearer if it said "Directory not found: …, path '/some_project/FOO'" instead of "File not found: …, path '/some_project/FOO/bar.c'".)
>>
>>> If I use --parents to create the path (in case it doesn't exist):
>>>
>>> (Case 3)
>>> c:\Project_files\sandbox>svn copy --parents bar.c http://svr/repo/some_project/FOO/bar.c -m "test commit"
>>> ** ERROR-CASE: Clash: '/some_project/FOO' '/some_project/foo'
>>
>> You've asked Subversion to create a directory FOO when a directory foo already exists, which would be fine, except your hook script prevents case collisions.
>
> My question revolves around why the different behavior/messages when the only difference is when --parents is included. One case bombs out with a cryptic message (svn: E155011: File 'C:\Project_files\sandbox\bar.c' is out of date) and the other triggers a pre-commit check. Both would seem to have identical implementation accept when a directory is not found (--parents would create it). Why didn't case 1 trigger the pre-commit check? Granted, the script in question may be out of scope of this list.

The pre-commit hook script is only called if Subversion's internal checks already passed; if the internal checks fail, there's no reason to call the pre-commit hook script since the commit will fail regardless of the hook script's outcome.

The internal check that failed in this case was that you asked Subversion to put a file into a nonexistent directory.

I agree the error message could be improved, as I said above. I can reproduce it with a simple script:

$ cd /private/tmp
$ svnadmin create repo
$ REPO=file://$(pwd)/repo
$ svn co $REPO wc
Checked out revision 0.
$ cd wc
$ touch file
$ svn add file
A file
$ svn ci file -m ""
Adding file
Transmitting file data .
Committed revision 1.
$ svn up
Updating '.':
At revision 1.
$ svn cp file $REPO/nonexistent/path/to/file -m ""
Adding copy of file
svn: E155011: Commit failed (details follow):
svn: E155011: File '/private/tmp/wc/file' is out of date
svn: E160013: File not found: transaction '1-1', path '/nonexistent/path/to/file'

I think it would be clearer if the message said:

Adding copy of file
svn: E155011: Commit failed (details follow):
svn: E160013: Directory not found: transaction '1-1', path '/nonexistent'


>>> As I would expect, I cannot perform an "svn info" on the incorrect-cased path. I was hoping I could do an "svn info" to test/determine what the case corrected path is, but will have to try an "svn copy --parents" first and if it fails due to a case clash, retry with the returned clash info. Is there a better way to accomplish this? I do understand this is more of a corner use case, especially since Subversion is (properly IMO) designed around case sensitivity.
>>
>> What exactly are you trying to accomplish? If the problem is that you don't know the names (or cases) of the directories in the repository, then you can use "svn ls" to find out.
>
> Doing an "svn ls" is burden-some when you have a lengthy path that you want to discover the case sensitive version of. If you had A/b/C/d/E for a path, you'd have to "svn ls" on the repo to find "A" vs "a" then do another for "B" vs "b" etc. I'd like to know of the easiest method to discover A/b/C/d/E vs doing an svn copy --parents to have the server side report back the case sensitive version of it. Plus, from a previous email, there's no stock way to do "svn list" and return only the directory listing (you have to wade through all the files as well).
>
> I guess the normal and usual use case is having a working copy checkout so you can locally navigate the repo structure. In our case, we are doing an archive type of operation where we really do not want a local WC due to size and just operation on the repo directly. svn copy works great in this case with the exception of users getting case confused.

I don't understand how you get into the situation of knowing the letters in the names of directories in the repository but don't know their case.


Dan Ellis

unread,
May 22, 2014, 11:16:32 AM5/22/14
to Ryan Schmidt, Subversion Users
The pre-commit hook script is only called if Subversion's internal checks already passed; if the internal checks fail, there's no reason to call the pre-commit hook script since the commit will fail regardless of the hook script's outcome.

The internal check that failed in this case was that you asked Subversion to put a file into a nonexistent directory.

I don't quite follow what the different checks would be as in this case the only difference is --parents vs no --parents.  Both I imagine do a path existence check and in both cases the path doesn't exist.  In the end, it really doesn't matter - its a general curiosity on my part.

I agree the error message could be improved, as I said above. I can reproduce it with a simple script:
I agree, it lead me astray for a little bit.

I don't understand how you get into the situation of knowing the letters in the names of directories in the repository but don't know their case.
Time.  Developers know the project names and subsystems very well, but do not always remember case, especially when we move from project to project.  This is not a normal use case as most users will have a local WC checkout, but we use this for some archival purposes where we don't really want every developer with a checkout (one way trip stuff).

It would be nice if the SVN client, for case insensitive operating systems, could automatically resolve these case issues.  I really don't expect that to happen as working on operating system-specific stuff isn't always the best use of time (smaller audience, limited impact, etc.).  In lieu  of this, I'm working on changing all our directory entries to lower-case.

Thanks for the help,
Dan

Ryan Schmidt

unread,
May 22, 2014, 11:31:01 AM5/22/14
to Dan Ellis, Subversion Users
On May 22, 2014, at 10:16, Dan Ellis wrote:

>> The pre-commit hook script is only called if Subversion's internal checks already passed; if the internal checks fail, there's no reason to call the pre-commit hook script since the commit will fail regardless of the hook script's outcome.
>>
>> The internal check that failed in this case was that you asked Subversion to put a file into a nonexistent directory.
>
> I don't quite follow what the different checks would be as in this case the only difference is --parents vs no --parents. Both I imagine do a path existence check and in both cases the path doesn't exist.

You're telling Subversion to copy a file into a nonexistent directory.

When you don't use --parents, that's an error, which Subversion reports to you, albeit cryptically.

When you do use --parents, it's not an error, because Subversion will try to create the directory for you, but that fails because your hook script forbids it.


> It would be nice if the SVN client, for case insensitive operating systems, could automatically resolve these case issues. I really don't expect that to happen as working on operating system-specific stuff isn't always the best use of time (smaller audience, limited impact, etc.).

At present, Subversion repositories are case-sensitive filesystems. It might be nice if it could be specified at repository creation time that a repository should be case-insensitive, but that capability does not exist today.


> In lieu of this, I'm working on changing all our directory entries to lower-case.

Yeah, that's probably a good idea, or at least some predictable naming scheme.


Philip Martin

unread,
May 22, 2014, 12:17:45 PM5/22/14
to Dan Ellis, Ryan Schmidt, Subversion Users
Dan Ellis <danel...@gmail.com> writes:

> I don't quite follow what the different checks would be as in this case the
> only difference is --parents vs no --parents. Both I imagine do a path
> existence check and in both cases the path doesn't exist. In the end, it
> really doesn't matter - its a general curiosity on my part.

--parents is implemented by the client. The client first builds up a
transaction on the server and then tells the server to attempt to commit
the transaction. Without --parents the copy fails while building the
transaction so no attempt is made to commit the transaction. With
--parents the client detects the missing directory and sends an explicit
mkdir before sending the copy, this allows the copy to succeed and in
turn allows the client to proceed to tell the server to attempt the
commit.

--
Philip Martin | Subversion Committer
WANdisco // *Non-Stop Data*

Dan Ellis

unread,
May 22, 2014, 12:20:48 PM5/22/14
to Philip Martin, Ryan Schmidt, Subversion Users

--parents is implemented by the client.  The client first builds up a
transaction on the server and then tells the server to attempt to commit
the transaction.  Without --parents the copy fails while building the
transaction so no attempt is made to commit the transaction.  With
--parents the client detects the missing directory and sends an explicit
mkdir before sending the copy, this allows the copy to succeed and in
turn allows the client to proceed to tell the server to attempt the
commit.

That makes perfect sense now.  Thank you.

Dan
Reply all
Reply to author
Forward
0 new messages