如何为指定的 URL 创建 TSvnItem

发布于 2025-01-15 19:15:15 字数 2112 浏览 0 评论 0原文

简短版本

如何在 Delphi 的 subversion api 包装器中执行 svn cat ?

长版本

我想在 subversion 中获取文件的内容。

这是一个随机的公共存储库,可让您 cat (即显示文件的内容):

>svn cat http://svn.code.sf.net/p/unicon/code/trunk/unicon/README
Unicon 13.x README


This is the Unicon distribution.  Please tell us
where it compiles, and when and how it doesn't.
...snip...

这样就可以了。

那么在Delphi中如何实现呢?

我如何读取 Delphi 的 Subversion API 包装器中的文件内容(即 cat)?

根据 this Stackoverflow 答案,我尝试:

SvnItem: TSvnItem;

SvnItem := TSvnItem.Create(SvnClient, nil, 'http://svn.code.sf.net/p/unicon/code/trunk/unicon/README');

不幸的是,创建 TSvnItem 的调用引发了异常:

EAprError:给定路径格式错误或包含无效字符

那么我做错了什么?

对于懒惰者,

program Project1;

{$APPTYPE CONSOLE}

uses
    SysUtils, SvnClient;

procedure Main;
var
    SvnClient: TSvnClient;
    SvnItem: TSvnItem;
    url: string;
begin
    // Set the global variable where the subversion DLLs can be found.
    BaseDllDir := ExtractFilePath(ParamStr(0)); //Setting a global variable (yes, seriously)

    SvnClient := TSvnClient.Create;
    SvnClient.Initialize;

    url := 'http://svn.code.sf.net/p/unicon/code/trunk/unicon/README';
    SvnItem := TSvnItem.Create(SvnClient, nil, url);
end;

begin
    try
        Main;
    except
        on E: Exception do
            begin
                ExitCode := 1;
                Writeln(Format('[%s] %s', [E.ClassName, E.Message]));
            end;
    end;
end.

另请参阅

Short Version

How to perform svn cat in Delphi's subversion api wrapper?

Long Version

I want to get the contents of a file in subversion.

Here's a random public repository that lets you cat (i.e. display the contents of) a file:

>svn cat http://svn.code.sf.net/p/unicon/code/trunk/unicon/README
Unicon 13.x README


This is the Unicon distribution.  Please tell us
where it compiles, and when and how it doesn't.
...snip...

So that works.

Now how to do it in Delphi?

How do i read the contents (i.e. cat) a file in Delphi's Subversion API wrapper?

Based on this Stackoverflow answer, i try:

SvnItem: TSvnItem;

SvnItem := TSvnItem.Create(SvnClient, nil, 'http://svn.code.sf.net/p/unicon/code/trunk/unicon/README');

Unfortunately the call to create a TSvnItem throws an exception:

EAprError: The given path is misformatted or contained invalid characters

So what am i doing wrong?

For The Lazy

program Project1;

{$APPTYPE CONSOLE}

uses
    SysUtils, SvnClient;

procedure Main;
var
    SvnClient: TSvnClient;
    SvnItem: TSvnItem;
    url: string;
begin
    // Set the global variable where the subversion DLLs can be found.
    BaseDllDir := ExtractFilePath(ParamStr(0)); //Setting a global variable (yes, seriously)

    SvnClient := TSvnClient.Create;
    SvnClient.Initialize;

    url := 'http://svn.code.sf.net/p/unicon/code/trunk/unicon/README';
    SvnItem := TSvnItem.Create(SvnClient, nil, url);
end;

begin
    try
        Main;
    except
        on E: Exception do
            begin
                ExitCode := 1;
                Writeln(Format('[%s] %s', [E.ClassName, E.Message]));
            end;
    end;
end.

See also

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

流年已逝 2025-01-22 19:15:15

这不是一个答案;而是一个答案。但这是下一个人的解决方法。

应该起作用(但不起作用)的黑客

function GetSubversionFileContents(Client: TSvnClient; Url: string): TStream;
var
    item: TSvnItem;
    buffer: TBytes;
    ms: TMemoryStream;
begin
    //WARNING: This code doesn't work.
    item := TSvnItem.Create(Client, nil, Url); //throws exception
    buffer := item.GetBaseFile;
    item.Free;

    ms := TMemoryStream.Create;
    ms.Size := Length(buffer);
    if Length(buffer) > 0 then
        ms.Write(buffer[0], Length(buffer));
    ms.Seek(0, soFromBeginning);
end;

解决方法

function GetSubversionFileContents(Client: TSvnClient; Url: string): TStream;
var
    http: IWinHttpRequest;
    stm: IStream;
begin
    // Issue the WebDAV HTTP GET ourselves.
    // (SVN is just a wrapper around WebDAV)

    http := CoWinHttpRequest.Create;
    http.Open('GET', url, False);
    if Client.UserName <> '' then
        http.SetCredentials(Client.UserName, Client.Password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER);
    http.Send(EmptyParam);

    stm := IUnknown(http.ResponseStream) as IStream;
    Result := TOleStream.Create(stm);

    //TODO: Re-write the rest of the Subversion API into something modern (i.e. post-1995).
end;

Subversion 只是 WebDAV 的一个实现 - 它只是 REST 但没有很酷的名字。这意味着您可以向 url 发出 GET 来直接获取内容。

It's not an answer; but it is a workaround for the next guy.

Thing that should work (but doesn't)

function GetSubversionFileContents(Client: TSvnClient; Url: string): TStream;
var
    item: TSvnItem;
    buffer: TBytes;
    ms: TMemoryStream;
begin
    //WARNING: This code doesn't work.
    item := TSvnItem.Create(Client, nil, Url); //throws exception
    buffer := item.GetBaseFile;
    item.Free;

    ms := TMemoryStream.Create;
    ms.Size := Length(buffer);
    if Length(buffer) > 0 then
        ms.Write(buffer[0], Length(buffer));
    ms.Seek(0, soFromBeginning);
end;

Hack workaround

function GetSubversionFileContents(Client: TSvnClient; Url: string): TStream;
var
    http: IWinHttpRequest;
    stm: IStream;
begin
    // Issue the WebDAV HTTP GET ourselves.
    // (SVN is just a wrapper around WebDAV)

    http := CoWinHttpRequest.Create;
    http.Open('GET', url, False);
    if Client.UserName <> '' then
        http.SetCredentials(Client.UserName, Client.Password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER);
    http.Send(EmptyParam);

    stm := IUnknown(http.ResponseStream) as IStream;
    Result := TOleStream.Create(stm);

    //TODO: Re-write the rest of the Subversion API into something modern (i.e. post-1995).
end;

Subversion is just an implementation of WebDAV - which is just REST but without the cool name. Which means you can issue a GET to the url to get the contents yourself directly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文