2010-04-29 13 views
33

¿Hay alguna manera de encontrar una revisión SVN buscando una cadena de texto que se eliminó en el archivo? Sé el texto exacto para buscar y qué archivo buscar, pero hay cientos de revisiones.find svn revisión por texto eliminado

+0

¿Te refieres a los cambios que hiciste o a un texto que está en el mensaje de registro? Puede usar svn log URL/file para obtener la lista de revisiones donde se ha cambiado este archivo. Usando svn blame -rRevision: URL/archivo de revisión imprimirá la línea que ha sido modificada en la revisión y un grep (unix) que proporcionará la información necesaria ... – khmarbaise

+0

Me refiero a los cambios de archivo reales, no a los mensajes de registro. svn blame + grep era casi lo bastante bueno, pero el cambio consistía en eliminar el texto en lugar de agregarlo, por lo que no apareció allí. He actualizado la pregunta con aclaraciones; gracias khmarbaise. –

+1

svn culpa mostrará líneas en ambos casos si agrega una línea o elimina una línea. Si usa la forma que sugerí en mi respuesta (svn blame -r Rev: Rev URL/file). – khmarbaise

Respuesta

31

Basándose en el guión de khmarbaise, se me ocurrió esto:

#!/bin/bash 
file="$1" 
REVISIONS=`svn log $file -q --stop-on-copy |grep "^r" | cut -d"r" -f2 | cut -d" " -f1` 
for rev in $REVISIONS; do 
    prevRev=$(($rev-1)) 
    difftext=`svn diff [email protected]$prevRev [email protected]$rev | tr -s " " | grep -v " -\ \- " | grep -e "$2"` 
    if [ -n "$difftext" ]; then 
     echo "$rev: $difftext" 
    fi 
done 

pasar el nombre de archivo y la cadena de búsqueda en la línea de comandos:

xyz.sh "filename" "text to search" 

svn diff me da tanto el rev donde está agregado y donde se elimina; Lo dejaré aquí en caso de que sea útil para cualquiera. Hay un mensaje de error en la última revisión del que no sé cómo deshacerme (todavía tengo mucho que aprender :) pero los números de rev son correctos.

+1

Eso funcionó bien para mí, gracias! –

+0

Este script funciona muy bien incluso para cadenas/texto que se agrega porque funciona en svn diff. Gracias por el guion. –

+0

En 'grep"^r "| cut -d "r" -f2 | cut -d "" -f1' estás usando tres procesos; Yo usaría algo como 'sed -ne '/^r/{s/^ r //; s /. * //; p} '' en su lugar. – musiphil

9

solo una pequeña secuencia de comandos bash que filtra las líneas modificadas ... Si cambia pom.xml en su archivo puede con la URL complementaria tiene lo que necesita ... (Si está en Unix como sistema). Coloque lo siguiente en un archivo de script (xyz.sh) y realice un filtro en la salida.

#!/bin/bash 
REVISIONS=`svn log pom.xml -q|grep "^r" | cut -d"r" -f2 | cut -d" " -f1` 
for rev in $REVISIONS; do 
    svn blame -r$rev:$rev pom.xml | tr -s " " | grep -v " -\ \- " 
done 


xyz.sh | grep "Text you are searching for" 

La impresión será algo como:

256 ...... 

El 256 es la revisión en la que se había realizado el cambio.

+0

Esto no imprime líneas eliminadas, ¿o sí? – musiphil

+0

@musiphil Correcto. – khmarbaise

1

Me gusta blameall.py.

Su salida para un archivo contiene todas las líneas existentes y eliminadas para que pueda ver las líneas eliminadas en el contexto circundante.

1

hizo una sencilla versión de PHP de la respuesta aceptada para ser ejecutado en la línea de comandos:

<?php 
$file = $argv[1]; 
$searchfor = $argv[2]; 

if (!$file) die('Please specify file name to search through as the first argument.'); 
if (!$searchfor) die('Please specify text to search for as the second argument.'); 

echo PHP_EOL .'Searching '. $file .' for: '. $searchfor . PHP_EOL . PHP_EOL; 

$cmd = 'svn log '. $file .' -q'; 
$output = array(); 
exec($cmd, $output); 

// Find all revisions 
$all_revisions = array(); 
foreach ($output as $line) { 
    if (preg_match("/^r(\\d+) /", $line, $match)) { 
     $all_revisions[] = $match[1]; 
    } 
} 

echo 'Checking '. count($all_revisions) .' revisions...'. PHP_EOL . PHP_EOL; 

// Get diff for each revision 
foreach ($all_revisions as $keykey => $rev) { 
    $prev_rev = $all_revisions[$keykey+1]; 

    $cmd = 'svn diff --old='. $file .'@'. $prev_rev .' --new='. $file .'@'. $rev; 
    $output = array(); 
    exec($cmd, $output); 

    // Check if string is present 
    $str = implode(PHP_EOL, $output); 
    if (strpos($str, $searchfor) !== false) { 
     echo 'Found in revision '. $prev_rev .' but removed from '. $rev .'.'. PHP_EOL; 
     break; 
    } else { 
     echo 'Not found in revision '. $rev .'.'. PHP_EOL; 
    } 
} 
echo 'Done.'. PHP_EOL; 

ejecutar el script de la secuencia de comandos con el comando siguiente:

php scriptname.php "filetosearchthrough.php" "text to search for"

El guión podría ser ajustado, pero hace lo que necesita. Tenga en cuenta que lleva mucho tiempo buscar en muchas revisiones.

0

Si usted no puede o no desea utilizar secuencias de comandos:

svn log --diff [path_to_file] > log.txt 

(el [vía_al_archivo] es opcional, si no se especifica, se incluirán todos los archivos de la carpeta y subcarpetas actuales)

Allí puede encontrar todas las líneas agregadas (comienzan con +), todas las líneas eliminadas (comienzan con -) y algunas líneas de contexto (comienzan con un espacio). Las líneas modificadas aparecerán con el signo + y se repetirán con el -

Puede procesar el archivo resultante con cualquier editor de texto decente (por ejemplo, Notepad ++), grep, scripts o cualquier cosa que desee.

Cuestiones relacionadas