1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
#!/usr/bin/instantfpc
// Author: Mattias Gaertner 2016
{$mode objfpc}{$H+}
uses Classes, SysUtils;
procedure WriteUsage;
begin
writeln('Reads svn logs from trunk and fixes. Writes commits found in both.');
writeln;
writeln('Usage:');
writeln(' ./find_merged_revisions.pas <trunk.log> <fixes.log> <merged.txt>');
writeln;
writeln('Create trunk.log and fixes.log from svn with:');
writeln(' svn log --limit=1000 /path/lazarus/trunk > trunk.log ');
writeln(' svn log --limit=1000 /path/lazarus/fixes > fixes.log ');
writeln;
writeln('merged.txt are the already listed entries on');
writeln(' http://wiki.lazarus.freepascal.org/Lazarus_1.6_fixes_branch like this:');
writeln(' r51389 fpvectorial: Fix compilation error with fpc 2.6.4');
Halt(1);
end;
type
TLogEntry = class
public
Revision: string;
Message: string;
end;
function ReadLog(aFilename: string): TFPList; // list of TLogEntry
{ Entries have the format:
------------------------------------------------------------------------
r51652 ...
some text...
}
const
Separator = '------------------------------';
var
sl: TStringList;
i, j: Integer;
Line: String;
LogEntry: TLogEntry;
begin
Result:=TFPList.Create;
sl:=TStringList.Create;
try
sl.LoadFromFile(aFilename);
i:=0;
while i<sl.Count do begin
Line:=sl[i];
inc(i);
if LeftStr(Line,length(Separator))=Separator then begin
if i=sl.Count then break;
Line:=sl[i];
inc(i);
if (length(Line)>=2) and (Line[1]='r') and (Line[2] in ['0'..'9']) then begin
// read revsion, e.g. r51234 |...
j:=2;
while (j<=length(Line)) and (Line[j] in ['0'..'9']) do inc(j);
LogEntry:=TLogEntry.Create;
Result.Add(LogEntry);
LogEntry.Revision:=LeftStr(Line,j-1);
LogEntry.Message:='';
while i<sl.Count do begin
Line:=sl[i];
inc(i);
if LeftStr(Line,length(Separator))=Separator then break;
Line:=Trim(Line);
if Line<>'' then begin
if LogEntry.Message<>'' then
LogEntry.Message+=' ';
LogEntry.Message+=Line;
end;
end;
LogEntry.Message:=Trim(LogEntry.Message);
//writeln('GetLog Rev="',LogEntry.Revision,'" Msg="',LogEntry.Message,'"');
end;
end;
end;
finally
sl.Free;
end;
end;
function ReadOldMerged(aFilename: string): TFPList;
{ One entry per line like this:
r51379 Converter: Change global procedures into methods of TConvertSettings.
}
var
sl: TStringList;
i, j: Integer;
Line: String;
LogEntry: TLogEntry;
begin
Result:=TFPList.Create;
sl:=TStringList.Create;
try
sl.LoadFromFile(aFilename);
for i:=0 to sl.Count-1 do begin
Line:=Trim(sl[i]);
if (length(Line)>=2) and (Line[1]='r') and (Line[2] in ['0'..'9']) then begin
j:=2;
while (j<=length(Line)) and (Line[j] in ['0'..'9']) do inc(j);
LogEntry:=TLogEntry.Create;
Result.Add(LogEntry);
LogEntry.Revision:=LeftStr(Line,j-1);
LogEntry.Message:=Trim(copy(Line,j,length(Line)));
end;
end;
finally
sl.Free;
end;
end;
function FindMsg(aMessage: string; Entries: TFPList): TLogEntry;
var
i: Integer;
begin
for i:=0 to Entries.Count-1 do begin
Result:=TLogEntry(Entries[i]);
if Result.Message=aMessage then exit;
end;
Result:=nil;
end;
function ExpandFile(aFilename: string): string;
begin
if aFilename='' then
WriteUsage;
Result:=ExpandFilename(aFilename);
end;
var
TrunkLog, FixesLog, OldMerged: TFPList;
TrunkID: Integer;
FixesEntry, TrunkEntry: TLogEntry;
begin
if ParamCount<3 then WriteUsage;
TrunkLog:=ReadLog(ExpandFile(ParamStr(1)));
FixesLog:=ReadLog(ExpandFile(ParamStr(2)));
OldMerged:=ReadOldMerged(ExpandFile(ParamStr(3)));
TrunkID:=0;
writeln('Merged revisions:');
for TrunkID:=TrunkLog.Count-1 downto 0 do begin
TrunkEntry:=TLogEntry(TrunkLog[TrunkID]);
FixesEntry:=FindMsg(TrunkEntry.Message,FixesLog);
if FixesEntry=nil then continue;
if FindMsg(FixesEntry.Message,OldMerged)<>nil then continue;
writeln(TrunkEntry.Revision,' (',FixesEntry.Revision,') ',TrunkEntry.Message);
end;
end.
|