Come cercare nella cronologia dei commenti cvs
-
02-07-2019 - |
Domanda
Sono a conoscenza di questo comando:
cvs log -N -w<userid> -d"1 day ago"
Sfortunatamente questo genera un rapporto formattato con molte nuove righe, in modo tale che il percorso del file, la versione del file e il testo del commento siano tutti su righe separate. Pertanto è difficile scansionarlo per tutte le occorrenze del testo del commento, (ad esempio, grep) e correlare le corrispondenze al file / versione.
(Notare che l'output del log sarebbe perfettamente accettabile, se solo cvs potesse eseguire il filtro in modo nativo.)
EDIT: output di esempio. Un blocco di testo come questo è riportato per ogni file di repository:
RCS file: /data/cvs/dps/build.xml,v Working file: build.xml head: 1.49 branch: locks: strict access list: keyword substitution: kv total revisions: 57; selected revisions: 1 description: ---------------------------- revision 1.48 date: 2008/07/09 17:17:32; author: noec; state: Exp; lines: +2 -2 Fixed src.jar references ---------------------------- revision 1.47 date: 2008/07/03 13:13:14; author: noec; state: Exp; lines: +1 -1 Fixed common-src.jar reference. =============================================================================
Soluzione
Le opzioni -w
sembrano funzionare meglio con l'opzione -S
. In caso contrario, ci sono risultati aggiuntivi che non sembrano correlati all'ID utente. Forse qualcuno può spiegarlo.
cvs log -N -S -w<userid> -d"1 day ago"
Con quello sto ottenendo un ragionevole successo collegandolo a grep:
cvs log -N -S -w<userid> -d"1 day ago" | grep -B14 "some text" > afile
Sto reindirizzando l'output su un file poiché il registro cvs è rumoroso e non sono sicuro di come renderlo silenzioso. Suppongo che un'alternativa sia reindirizzare lo standard a /dev/null
.
Altri suggerimenti
Desideri cvsps - che genererà patch set dalla cronologia CVS. Quindi, dovresti avere solo un'istanza del tuo commento nell'output di cvsps, con i file elencati ordinatamente sotto di esso
I miei primi pensieri sono stati di usare egrep (o grep -E, penso) per cercare più schemi come:
<Cmd> | egrep 'Filename:|Version:|Comment:'
ma poi ho capito che volevi filtrare in modo più intelligente.
A tal fine, userei awk (o perl) per elaborare l'output riga per riga, impostando una variabile eco quando trovi una sezione di interesse; pseudocodice qui:
# Assume the sections are of the format:
# Filename: <filename>
# Version: <version>
# Comment: <comment>
# <more comment>
Set echo to false
While more lines left
Get line
If line starts with "Filename: " and <filename> is of interest
Set echo to true
If line starts with "Filename: " and <filename> is not of interest
Set echo to false
If echo is true
Output line
End while
Ecco cosa ho fatto: un semplice script Java:
import java.io.IOException;
public class ParseCVSLog
{
public static final String CVS_LOG_FILE_SEPARATOR = "=============================================================================";
public static final String CVS_LOG_REVISION_SEPARATOR = "----------------------------";
public static final String CVS_LOG_HEADER_FILE_NAME = "Working file";
public static final String CVS_LOG_VERSION_PREFIX = "revision";
public static void main(String[] args) throws IOException
{
String searchString = args[0];
System.out.println( "SEARCHING FOR: " + searchString );
StringBuffer cvsLogOutputBuffer = new StringBuffer();
byte[] bytes = new byte[1024];
int numBytesRead = 0;
while( (numBytesRead = System.in.read( bytes )) > 0 )
{
String bytesString = new String(bytes, 0, numBytesRead);
cvsLogOutputBuffer.append( bytesString );
}
String cvsLogOutput = cvsLogOutputBuffer.toString();
String newLine = System.getProperty("line.separator");
String[] fileArray = cvsLogOutput.split( CVS_LOG_FILE_SEPARATOR );
for ( String fileRecord : fileArray )
{
if ( !fileRecord.contains( searchString ) )
{
continue;
}
String[] revisionArray = fileRecord.split( CVS_LOG_REVISION_SEPARATOR );
String[] fileHeaderLineArray = revisionArray[ 0 ].split( newLine );
String fileName = "";
for ( String fileHeadeLine : fileHeaderLineArray )
{
if ( fileHeadeLine.contains( CVS_LOG_HEADER_FILE_NAME ) )
{
fileName = fileHeadeLine.split( ": " )[ 1 ];
break;
}
}
System.out.print( fileName );
for ( int i = 1; i < revisionArray.length; i++ )
{
String versionRecord = revisionArray[ i ];
if ( !versionRecord.contains( searchString ) )
{
continue;
}
String[] versionLineArray = versionRecord.split( newLine );
for ( String versionLine : versionLineArray )
{
if ( versionLine.contains( CVS_LOG_VERSION_PREFIX ) )
{
System.out.print( " " + versionLine.split( " " )[ 1 ] );
}
}
}
System.out.println();
}
}
}
Ed ecco come l'ho usato:
cvs log -N -S -washamsut | java ParseCVSLog GS-242
Questo comando e questo script gawk mi aiutano a trovare solo il nome file, la data e la riga di commento di ogni voce del registro.
cvs log -N -S -b -w<userid> -d ">1 day ago" 2>/dev/null | gawk 'BEGIN{out=0;} /^Working file:/ { print $0; } /^date:/ { out=1; } /^===/ { print ""; out=0; } (out==1){print $0;}'
Potrebbe essere eccessivo, ma potresti usare git-cvsimport per importare la cronologia CVS in un repository Git e cercarla utilizzando gli strumenti di Git. Non solo puoi cercare testo all'interno dei messaggi di commit, ma puoi anche cercare il codice che sia mai stato aggiunto o rimosso dai file nel tuo repository.
CVSSearch potrebbe essere d'aiuto, ma è un'applicazione CGI: '(