如何从存储库中的SVN项目中获取属性?

时间:2017-04-16 17:42:50

标签: delphi svn

我可以连接到存储库:

var 
   client: TSvnClient;
   url: string;
begin
   BaseDllDir := ExtractFilePath(ParamStr(0))+'Subversion'; //dlls sitting in "Subversion" folder
   client := TSvnClient.Create;
   client.Initialize;

   url := 'https://repos.wowace.com/wow/bank-items/tags/6.1.0.0';

我可以使用client.List的基本功能来获取项目列表:

var
   sl: TStrings;
begin
   sl := TStringList.Create;
   client.List(Url, svnDepthImmediates, False, sl);
   Log(sl.Text);

这会返回项目本身的列表,以及它的直接文件和目录条目:

.=/tags/6.1.0.0
.pkgmeta=/tags/6.1.0.0/.pkgmeta
BankItems.lua=/tags/6.1.0.0/BankItems.lua
BankItems.toc=/tags/6.1.0.0/BankItems.toc
Bindings.xml=/tags/6.1.0.0/Bindings.xml
localization-deDE.lua=/tags/6.1.0.0/localization-deDE.lua
localization-enUS.lua=/tags/6.1.0.0/localization-enUS.lua
...snip...

我还可以使用TSvnList.LoadList获取TSvnListItem个对象的列表:

var
   list: TSvnList;
   item: TSvnListItem;
begin
   list := TSvnList.Create(client);
   list.LoadList(Url, svnDepthImmediates, False);

    s := '';
    for i := 0 to list.Count-1 do
begin
    li := list.Items[i];

    s := s+
          '- Item '+intToStr(i)+#13#10+
          '   - **Path**: '+li.Path+#13#10+
          '   - **AbsolutePath**: '+li.AbsolutePath+#13#10+
          '   - **Size**: '+IntToStr(li.Size)+#13#10+
          '   - **Kind**: '+SvnNodeKindString(li.Kind)+#13#10+
          '   - **HasProps**: '+IfThen(li.HasProps, 'Yes', 'No')+#13#10+
          '   - **LastAuthor**: '+li.LastAuthor+#13#10+
          '   - **Time**: '+DateTimeToStr(li.Time)+#13#10+
          '   - **CreatedRevision**: '+IntToStr(li.CreatedRevision)+#13#10+#13#10;
end;
Log(s);
  
      
  • 第0项

         
        
    • 路径
    •   
    • AbsolutePath :/tags/6.1.0.0
    •   
    • 尺寸:0
    •   
    • 种类:svnNodeDir
    •   
    • HasProps :否
    •   
    • LastAuthor :nbluewiz
    •   
    • 时间:2/25/2015 10:13:29 PM
    •   
    • CreatedRevision :227
    •   
  •   
  • 第1项

         
        
    • 路径:。pkgme​​ta
    •   
    • AbsolutePath :/tags/6.1.0.0
    •   
    • 尺寸:22
    •   
    • 种类:svnNodeFile
    •   
    • HasProps :否
    •   
    • LastAuthor :root
    •   
    • 时间:2008年9月29日下午5:33:49
    •   
    • CreatedRevision :96
    •   
  •   
  • 第2项

         
        
    • 路径:BankItems.lua
    •   
    • AbsolutePath :/tags/6.1.0.0
    •   
    • 尺寸:272471
    •   
    • 种类:svnNodeFile
    •   
    • HasProps :是
    •   
    • LastAuthor :burstroc
    •   
    • 时间:2/8/2015 11:46:51 PM
    •   
    • CreatedRevision :225
    •   
  •   
  • 第3项

         
        
    • 路径:BankItems.toc
    •   
    • AbsolutePath :/tags/6.1.0.0
    •   
    • 尺寸:1776
    •   
    • 种类:svnNodeFile
    •   
    • HasProps :是
    •   
    • LastAuthor :burstroc
    •   
    • 时间:2/25/2015 9:02:47 PM
    •   
    • CreatedRevision :226
    •   
  •   
     

...略...

这是一个很长的路要说我可以成功连接到存储库并查询事物。

现在是属性

现在我想从存储库中的项目中读取some properties;或者一些更高级的元数据。

您注意到TSvnListItem类具有HasProps属性;但无法阅读属性。为此我 ,我们需要TSvnItem对象:

TSvnItem = class
public
   //...snip...
   property SvnPathName: string;
   property URL: string;
   property Parent: TSvnItem;
   property PathName: string;
   property LastCommitAuthor: string;
   property LastCommitRevision: Integer;
   property LastCommitTime: TDateTime;
   property PropCount: Integer;
   property PropNames[Index: Integer]: string;
   property HistoryCount: Integer;
   property HistoryItems[Index: Integer]: TSvnHistoryItem;
end;

给定一个任意项目,获得其父项的URL肯定会很好。或者获取历史记录或属性:

item := TSvnItem.Create(client, Url);
s := '';
for i := 0 to item.PropCount-1 do
begin
   s := s+'"'+item.PropNames[i]+'" = "'+item.PropValueFromIndex[i]+'"'+#13#10;
end;
Log(s);

除了使用TSvnItem访问任何内容的任何尝试都会导致错误:

  

C:\ Program Files(x86)\ Contoso \ Grobber不是工作副本。

这是真的;它不是。

还有TSvnItem.Create的其他重载,其中一个是used here,显然是成功的:

item := TSvnItem.Create(client, nil, Url);

但是那个构造函数失败了:

  

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

它在构造函数内失败:

FSvnPathName := FSvnClient.NativePathToSvnPath(FPathName, SubPool);

反过来失败了
function TSvnClient.NativePathToSvnPath(const NativePath: string; SubPool: PAprPool = nil): string;    
begin
   //...snip...
   AprCheck(apr_filepath_merge(SvnPath, '', PAnsiChar(UTF8Encode(NativePath)), APR_FILEPATH_TRUENAME, SubPool));

所以我很难过。由于Delphi Svn库上没有任何文档,我很难过。

最小可重现的例子

网址是公开的,任何人都可以使用:

  

https://repos.wowace.com/wow/bank-items/tags/6.1.0.0/BankItems.lua

但你必须确保提供所有的Dll:

program Project1;

{$APPTYPE CONSOLE}

uses System.SysUtils, SvnClient;

var
  client: TSvnClient;
  item: TSvnItem;
begin
  try
     client := TSvnClient.Create;
     BaseDllDir := ExtractFilePath(ParamStr(0));
     client.Initialize;
     item := TSvnItem.Create(client, nil, 'https://repos.wowace.com/wow/bank-items/tags/6.1.0.0/BankItems.lua');
     Writeln('ItemCount: '+IntToStr(item.PropCount));
  except
     on E: Exception do
        Writeln(E.ClassName, ': ', E.Message);
  end;
end.

1 个答案:

答案 0 :(得分:2)

请注意SvnClient(1.9)中URL重载之上的注释。

  

{TSvnItem for URL是某种黑客,现在不要期待   除异步历史记录加载以外的任何其他工作   构造函数Create(ASvnClient:TSvnClient; const AURL:string);过载;

它适用于Working Dir

procedure TForm1.btLoadPropClick(Sender: TObject);
const 
  url = 'svn://hub/vcl/Trunk/Jedi/';
  WorkDir = 'D:\VCL\Jedi';
var
  i: Integer;
  item: TSvnItem;
begin
  item := TSvnItem.Create(FClient, nil, WorkDir);
  Memo1.Lines.Add('============== Props ============================');
  for i := 0 to Pred(item.PropCount) do begin
    Memo1.Lines.Add(item.PropNames[i] + '" = "' + item.PropValueFromIndex[i]);
  end;
  item.Free;
end;

编辑: 在第2085行的TSvnItem.ReloadProps中似乎有一个错误:

将第2085行更改为以下代码似乎解决了这个问题:

        AprCheck(apr_filepath_merge(TruePath, PAnsiChar(UTF8Encode(URL)), PAnsiChar(UTF8Encode(FPathName)), APR_FILEPATH_TRUENAME, SubPool));