SharpSvn GetFileVersions and GetContentStream throws InvalidOperationException
Pergunta
I'm trying to use SharpSvn to get the contents of a file at a particular revision. I have the following code:
var svnClient = new SvnClient();
var revisionInfo = new SvnFileVersionsArgs
{
Start = 80088,
End = 80093
};
Collection<SvnFileVersionEventArgs> fileVersions;
svnClient.GetFileVersions(
new SvnUriTarget("https://DbDiff.svn.codeplex.com/svn/DbDiffCommon/DataAccess/SqlCommand11.xml"),
revisionInfo,
out fileVersions);
var stream = fileVersions[0].GetContentStream();
However on the last line I'm getting the following exception:
System.InvalidOperationException was unhandled
Message=This method can only be invoked from the eventhandler handling this eventargs instance
Source=SharpSvn
StackTrace:
at SharpSvn.SvnFileVersionEventArgs.GetContentStream(SvnFileVersionWriteArgs args) in g:\dist\src\sharpsvn\commands\fileversions.cpp:line 545
at SharpSvn.SvnFileVersionEventArgs.GetContentStream() in g:\dist\src\sharpsvn\commands\fileversions.cpp:line 534
at SharpSvnFileVersions.Program.Main(String[] args) in c:\temp\SharpSvnFileVersions\Program.cs:line 29
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
How should I go about getting the contents of the file at each revision?
Solução
Looks like I can use SvnClient.Write()
to grab the file contents:
SvnClient svnClient = new SvnClient();
SvnUriTarget target = new SvnUriTarget("https://DbDiff.svn.codeplex.com/svn/DbDiffCommon/DataAccess/SqlCommand11.xml", 80088);
Stream stream = new MemoryStream();
svnClient.Write(target, stream);
Outras dicas
GetFileVersions is only useful for specific scenarios. Subversion itself uses it to implement blame. I happened to create this test program for a different scenario: migrate all revisions of one file to a new repository. Posting it here for others to use.
using System;
using System.IO;
using SharpSvn;
using SharpSvn.UI;
class SvnDumpFileToRepository
{
static void Main(string[] args)
{
Uri uri = null;
if (args.Length < 2
|| !Uri.TryCreate(args[0], UriKind.Absolute, out uri))
{
Console.Error.WriteLine("Usage: SvnDumpFileToRepository URL PATH");
}
using (SvnRepositoryClient repos = new SvnRepositoryClient())
{
repos.CreateRepository(args[1]);
}
Uri reposUri = SvnTools.LocalPathToUri(args[1], true);
using (SvnClient client = new SvnClient())
using (SvnClient client2 = new SvnClient())
{
SvnUI.Bind(client, new SvnUIBindArgs());
string fileName = SvnTools.GetFileName(uri);
bool create = true;
client.FileVersions(uri,
delegate(object sender, SvnFileVersionEventArgs e)
{
Console.Write("Copying {0} in r{1}", fileName, e.Revision);
using (MemoryStream ms = new MemoryStream())
{
e.WriteTo(ms); // Write full text to memory stream
ms.Position = 0;
// And now use 'svnmucc' to update repository
client2.RepositoryOperation(reposUri,
new SvnRepositoryOperationArgs { LogMessage = e.LogMessage },
delegate(SvnMultiCommandClient mucc)
{
if (create)
{
mucc.CreateFile(fileName, ms);
create = false;
}
else
mucc.UpdateFile(fileName, ms);
});
}
});
}
}
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow