2008-09-23 16 views
8

Jestem świadomy tego polecenia: cvs log -N -w<userid> -d"1 day ago"Jak wyszukiwać cvs komentarz historii

Niestety to generuje sformatowany raport z partii newlines w nim, takie, że plik-ścieżki, to plik-wersji, a komentarz -tekst są w osobnych liniach. Dlatego trudno jest go zeskanować pod kątem wszystkich wystąpień tekstu komentarza (np. Grep) i skorelować dopasowania z plikiem/wersją.

(Zauważ, że wyjście z bali byłby całkowicie dopuszczalne, jeśli tylko cvs mógł wykonać filtrowanie natywnie.)

EDIT: Przykładowe wyjście. Blok tekstu jak to podano dla każdego pliku repozytorium:

 

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. 
============================================================================= 

Odpowiedz

9

Opcje wydają się działać lepiej dzięki opcji -S. W przeciwnym razie są dodatkowe wyniki, które nie wydają się być związane z identyfikatorem użytkownika. Być może ktoś może to wyjaśnić.

cvs log -N -S -w<userid> -d"1 day ago" 

Przy że byłem coraz rozsądny sukces orurowanie go grep:

cvs log -N -S -w<userid> -d"1 day ago" | grep -B14 "some text" > afile 

Mam przekierowanie wyjścia do pliku ponieważ log CVS jest głośny i nie jestem pewien, jak zrobić jest cicho. Przypuszczam, że alternatywą jest przekierowanie stderr do /dev/null.

+1

To niesamowite Steve. Nie wiedziałem o opcji -B grep: "wydrukuj NUM linii wiodącego kontekstu". Tak więc z 15-wierszowym raportem, który generuje dziennik cvs dla każdego pliku (komentarz jest 15.), -B14 daje mi cały blok dla każdego pasującego pliku. –

+0

Oczywiście działa najlepiej, gdy tekst, którego szukasz, znajduje się w pierwszej linii, ale jest to początek. –

+1

przy okazji, cvs log -N -S -w -d "1 dzień temu" będzie domyślnie wyszukiwał wpisy starsze niż 1 dzień temu. Myślę, że to, czego chcesz, to -d "> 1 dzień temu" –

0

Może to być sposób przesadą, ale można użyć git-cvsimport importować historię CVS repozytorium Git i szukać go za pomocą narzędzi git. Możesz nie tylko wyszukiwać tekst w wiadomościach zatwierdzania, ale możesz też wyszukiwać kod, który kiedykolwiek został dodany lub usunąć z plików w repozytorium.

+2

I to byłoby zrobione JAK? – dokaspar

2

Moje pierwsze myśli były w użyciu egrep (lub grep -E, myślę), aby wyszukać wiele wzorów, takich jak:

<Cmd> | egrep 'Filename:|Version:|Comment:' 

, ale potem zdałem sobie sprawę, że chcesz filtrować bardziej inteligentnie

W tym celu użyłbym awk (lub perl) do przetworzenia wyjścia linia po linii, ustawienie zmiennej echa, gdy znajdziesz sekcję zainteresowania; pseudokod tutaj:

# 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 
+0

Podatkowa część rozwiązania do przetwarzania końcowego polega na tym, że treść użyteczna znajduje się w dalszej części bloków tekstu. Dlatego konieczne będzie buforowanie każdego bloku, a następnie odrzucenie lub wyprowadzenie go. Wierzę, że awk może to zrobić, ale prawdopodobnie będzie to dla mnie projekt wielodniowy. –

1

Oto co zrobiłem - prosty skrypt 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(); 
     } 
    } 
} 

A oto jak użyłem go:

cvs log -N -S -washamsut | java ParseCVSLog GS-242 
4

Chcesz cvsps - który wygeneruje patchsets z historii CVS. Następnie powinieneś mieć tylko jedno wystąpienie twojego komentarza w pliku wyjściowym cvsps, z dokładnie wymienionymi plikami

1

To polecenie i skrypt gawk pomaga mi znaleźć tylko nazwę pliku, datę i wiersz komentarza każdego wpisu dziennika.

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;}'