Cannot use TortoiseSVN with Phabricator SVN repository


#1

Observed Behavior:

When trying to browse a Phabricator SVN repository using TortoiseSVN, the message "Connection closed unexpectedly is seen.

When trying to browse a Phabricator SVN repository manually using TortoisePlink on the command line and using the commands sniffed using Wireshark for a non-SSH repository, Phabricator reports an exception.

See Has anyone had any luck getting TortoiseSVN working with a Phabricator hosted SVN server? and https://stackoverflow.com/questions/50924254/cant-get-tortoise-svn-to-use-ssh-correctly for more details.

Expected Behavior:

Tortoise SVN should connect successfully and allow the user to browse the repository, checkout, commit, etc. etc.

Phabricator Version:

phabricator
b8b2d1672dc3d43f8af2b73cff0cf836db773063 (Jun 6 2018)
phutil
20eff1c8d14f08f05ef72828fa379e871d29662c (Apr 13 2018)
svn
1.9.7 at /usr/bin/svn

Reproduction Steps:

  1. Setup a SVN repository in a Docker container. That I am running in a Docker container may not be relevant to reproducing the issue.

  2. Import from an existing repository using svnsync on the Phabricator server with a file:// URL for the destination. This may not be necessary, but it is what I am doing.

  3. Add a user. Add an SSH key to access the SVN repository.

  4. Configure TortoiseSVN using any of the standard methods, i.e. putting TortoisePlink options in the URL, in a Putty session, or in the TortoiseSVN settings.
    5a) Try to browse the repository.

    Message “Connection closed unexpectedly” is seen.

5b) Run TortoisePlink manually on the command line specifying the user, key, and URL. Manually enter the input below once the connection forms:

( success ( ( ANONYMOUS EXTERNAL ) 36:4a5ca636-0b49-4f9e-8811-fcb4d745bd92 ) ) ( get-latest-rev ( ) )

I got the following response:

[2018-07-13 14:44:23] ERROR 2: Illegal string offset ‘value’ at [/var/lib/phabricator/phabricator/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php:334]
arcanist(head=master, ref.master=b199ca808660), phabricator(head=master, ref.master=b8b2d1672dc3), phutil(head=master, ref.master=20eff1c8d14f)
#0 DiffusionSubversionServeSSHWorkflow::willReadMessageCallback(PhabricatorSSHPassthruCommand, array) called at [/src/infrastructure/ssh/PhabricatorSSHPassthruCommand.php:223]
#1 PhabricatorSSHPassthruCommand::willReadData(string) called at [/src/infrastructure/ssh/PhabricatorSSHPassthruCommand.php:167]
#2 PhabricatorSSHPassthruCommand::execute() called at [/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php:186]
#3 DiffusionSubversionServeSSHWorkflow::executeRepositoryOperations() called at [/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php:188]
#4 DiffusionSSHWorkflow::execute(PhutilArgumentParser) called at [/scripts/ssh/ssh-exec.php:284]
[2018-07-13 14:44:23] ERROR 2: Illegal string offset ‘value’ at [/var/lib/phabricator/phabricator/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php:335]
arcanist(head=master, ref.master=b199ca808660), phabricator(head=master, ref.master=b8b2d1672dc3), phutil(head=master, ref.master=20eff1c8d14f)
#0 DiffusionSubversionServeSSHWorkflow::willReadMessageCallback(PhabricatorSSHPassthruCommand, array) called at [/src/infrastructure/ssh/PhabricatorSSHPassthruCommand.php:223]
#1 PhabricatorSSHPassthruCommand::willReadData(string) called at [/src/infrastructure/ssh/PhabricatorSSHPassthruCommand.php:167]
#2 PhabricatorSSHPassthruCommand::execute() called at [/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php:186]
#3 DiffusionSubversionServeSSHWorkflow::executeRepositoryOperations() called at [/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php:188]
#4 DiffusionSSHWorkflow::execute(PhutilArgumentParser) called at [/scripts/ssh/ssh-exec.php:284]
[2018-07-13 14:44:23] EXCEPTION: (Error) Cannot use string offset as an array at [/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php:344]
arcanist(head=master, ref.master=b199ca808660), phabricator(head=master, ref.master=b8b2d1672dc3), phutil(head=master, ref.master=20eff1c8d14f)
#0 DiffusionSubversionServeSSHWorkflow::willReadMessageCallback(PhabricatorSSHPassthruCommand, string) called at [/src/infrastructure/ssh/PhabricatorSSHPassthruCommand.php:223]
#1 PhabricatorSSHPassthruCommand::willReadData(string) called at [/src/infrastructure/ssh/PhabricatorSSHPassthruCommand.php:167]
#2 PhabricatorSSHPassthruCommand::execute() called at [/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php:186]
#3 DiffusionSubversionServeSSHWorkflow::executeRepositoryOperations() called at [/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php:188]
#4 DiffusionSSHWorkflow::execute(PhutilArgumentParser) called at [/scripts/ssh/ssh-exec.php:284]

I think that’s all the input I used. I suddenly ran out of time writing this so I cut and pasted from the other question topic I already opened. Ping me if it doesn’t reproduce and I’ll check the full traffic I entered.


#2

I made a brief attempt to reproduce some flavor of this. You can run:

./bin/ssh-exec --phabricator-ssh-user epriestley --ssh-command 'svnserve'

…and pipe in some text to simulate an SVN session more directly.

On its own, the given input doesn’t produce the given error for me:

$ cat command.txt 
( success ( ( ANONYMOUS EXTERNAL ) 36:4a5ca636-0b49-4f9e-8811-fcb4d745bd92 ) ) ( get-latest-rev ( ) )
$ cat command.txt | ./bin/ssh-exec --phabricator-ssh-user epriestley --ssh-command 'svnserve'
( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops depth log-revprops atomic-revprops partial-replay inherited-props ephemeral-txnprops file-revs-reverse ) ) ) [2018-07-23 15:20:09] ERROR 8: Undefined offset: 2 at [/Users/epriestley/dev/core/lib/phabricator/src/applications/diffusion/ssh/DiffusionSubversionServeSSHWorkflow.php:117]
arcanist(head=experimental, ref.master=875d01836037, ref.experimental=c1b1e69b8fbf), corgi(head=master, ref.master=6371578c9d32), instances(head=stable, ref.master=74af1ae74b54, ref.stable=8dd0c51cef31), libcore(), phabricator(head=master, ref.master=6b6e1f0ba890, custom=3), phutil(head=stable, ref.master=1613e68f4740, ref.stable=340445cf6947), services(head=stable, ref.master=cb3b22be8019, ref.stable=6db651c1f957)
  #0 DiffusionSubversionServeSSHWorkflow::identifyRepository() called at [<phabricator>/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php:164]
  #1 DiffusionSSHWorkflow::execute(PhutilArgumentParser) called at [<phabricator>/scripts/ssh/ssh-exec.php:284]
phabricator-ssh-exec: Protocol for URI "" MUST be "svn+ssh".

This particular output could be more clear (it could say “expected first protocol frame to be ‘version’ command” or similar) but whatever you’re hitting is presumably deeper in the protocol.

If you can generate a complete set of commands which reproduce the issue when piped in like this, fixing it is likely very easy.

We could also add some kind of way to log the protocol frames to make this easier, but issues with the protocol parser are rare and usually more straightforward to reproduce.


#3

I found my log of the conversation. After you connect, SVN says:

( success ( 2 2 ( ) ( edit-pipeline svndiff1 absent-entries commit-revprops depth log-revprops atomic-revprops partial-replay inherited-props ephemeral-txnprops file-revs-reverse ) ) )

You say (edit URI as required):

( 2 ( edit-pipeline svndiff1 accepts-svndiff2 absent-entries depth mergeinfo log-revprops ) 54:svn+ssh://phabricator.dynautics.local/source/Dynautics 38:SVN/1.10.0-dev (x64-microsoft-windows) ( 24:TortoiseSVN-1.10.0.28176 ) )

SVN says:

( success ( ( ANONYMOUS ) 9:dynautics ) )

I missed this next one out because I have no idea what it is doing and suspected that the 64 bit encoded string would need editing but didn’t know what to.

EDIT: I managed to decode it and it is just “anonymous@”. You can probably send it quite happily. I guess it will be ignored. If you don’t get the problem when sending this, and do get it otherwise, then maybe that’s the cause, but I doubt it.

( ANONYMOUS ( 21:YW5vbnltb3VzQE9rcmE= ) )

Then SVN should reply:

( success ( ) ) ( success ( 36:2a5dbed0-91aa-734c-96e1-ee4cbcb244ea 13:svn://unicorn ( mergeinfo ) ) )

Then you say:

( get-latest-rev ( ) )

And SVN should say:

( success ( ( ) 0: ) ) ( success ( 5734 ) )

but in fact we get the errors I reported earlier.


#4

I have the rest of the conversation if you need it.

I can also grab the conversation sent by the MSys2 version of the Subversion command line tool, which works, as well.

If there is anything else I can do to debug this or otherwise help it be solved/worked around then let me know. I like Phabricator, but we mainly started using it fdor code reviews and obviously if the repo isn’t locally hosted then that doesn’t work so well.


#5

Is there any progress on this? Do you need any more information from me?

This is blocking us from using Phabricator as our corporate repository host.


#6

It’s been several months so I am guessing that this issue is dead and that the Phabricator team has no plans to support TortoiseSVN.

This issue, plus problems with Differential (odd diff display, cannot get the control on whitespace that we want, etc. etc.) are making Phabricator no go for us. It’s a really nice idea and I wish you all the luck, but the only part of this tool we are using is the wiki and there are plenty of other wiki tools out there.