Función Bash para encontrar todas las confirmaciones de Git en las que un file (cuyo nombre coincide con una expresión regular) ha * cambiado *

Tengo la siguiente function bash , que busca todos los files en un repository, cuyo nombre de file coincide con una expresión regular. Actualmente encuentra todas las confirmaciones en las que existe un file. ¿Cómo se puede cambiar esto para que solo busque entre los files que fueron editados (creados, alterados o eliminados) en cada confirmación?

Esta fue mi intención original para la function. Me sorprendió ver que los resultados eran mucho más amplios de lo esperado. La razón por la que trato de hacer esto es que creé un file hace mucho time, y en algún punto entre ahora y entonces, accidentalmente borré una sección importante de él. Quiero una list de todos los puntos (confirmaciones) en las que este file ha cambiado, así puedo volver rápidamente a la versión que contiene la sección faltante y volver a pegarla en la versión actual del comunicador.

:<<COMMENT Searches all commits in the current git repository containing a file whose name matches a regular expression. Usage: gitf <regex> Parameter is requinetworking, and must be at least one non-whitespace character. The original version of this function was based on the GitHub gist - https://gist.github.com/anonymous/62d981890eccb48a99dc written by Stack Overflow user Handyman5 - http://sofes.miximages.com/users/459089/handyman5 which is based on this SO question: - http://sofes.miximages.com/questions/372506/how-can-i-search-git-branches-for-a-file-or-directory/372654#372654 The main section of this function was authonetworking by Stack Overflow user SwankSwashbucklers. - http://sofes.miximages.com/users/2615252/swankswashbucklers - http://sofes.miximages.com/a/28095750/2736496 Short description: Stonetworking in GITF_DESC COMMENT #GITF_DESC: For "aliaf" command (with an 'f'). Must end with a newline. GITF_DESC="gitf [searchterm]: Searches the current git repository for the file name that matches a regular expression.\n" 

Cuerpo:

 gitf() { #Exit if no parameter is provided (if it's the empty string) param=$(echo "$1" | trim) echo "$param" if [ -z "$param" ] #http://tldp.org/LDP/abs/html/comparison-ops.html then echo "Requinetworking parameter missing. Cancelled"; return fi wasFound="0"; LOC=refs/remotes/origin # to search local branches only: 'refs/heads' ref="%(refname)" for branch in `git for-each-ref --format="$ref" $LOC`; do for commit in `git rev-list $branch | grep -oP ^.\{7\}`; do found=$(git ls-tree -r --name-only $commit | grep "$param") if [ $? -eq 0 ]; then echo "${branch#$LOC/}: $commit:" while read line; do echo " $line" done < <(echo "$found") wasFound="1"; fi done done if [ "$wasFound" -eq "0" ]; then echo "No files in this repository match '$param'." fi } 

Si puedes vivir con un patrón de glob de concha en lugar de una expresión regular en toda regla, considera

 git log -p --diff-filter=AMD --branches --tags -- "foo*bar.sh" 

Con -p , puede ver los deltas junto con el post de confirmación, autor, SHA1, etc. La --diff-filter=AMD selecciona solo aquellos commits en los que los files en cuestión fueron A dded, M odified o D eleted. Para search controles remotos, así como las twigs y tags locales, use --all lugar de --branches --tags . Finalmente, tenga en count que introduce patrones de ruta, que usted querrá citar para permitir que git realice la correspondencia global.

Utilice git diff-tree -r --name-only --no-commit-id (quizás con --stdin ) en lugar de git ls-tree -r --name-only . Utilice -m o -c si le interesan las fusiones, -M o -C si desea tener en count, respectivamente, cambiar el nombre y copyr la detección.

O mejor, analice la salida de git diff-tree -r .

Nótese bien. el código que se da en cuestión es muy poco óptimo (entre otros, se comtesting varias veces las mismas confirmaciones).

Puede ver y usar git diff para ver qué cambió entre cada una de las confirmaciones. Algo como esto:

 for branch in `git for-each-ref --format="$ref" $LOC`; do previous_commit="" for commit in `git rev-list $branch | grep -oP ^.\{7\}`; do if [ "$previous_commit" != "" ]; then found=$(git diff --name-only $previous_commit $commit | grep "$param") if [ $? -eq 0 ]; then echo "${branch#$LOC/}: $commit:" while read line; do echo " $line" done < <(echo "$found") echo wasFound="1"; fi fi previous_commit="$commit" done done 

Se me ocurrió esta function, que se basa en la respuesta de Greg Bacon . Originalmente quería expresiones regulares, pero los globs encajan perfectamente. También esperaba que se requiriera una function de bucle, pero la única línea de git log es todo lo que se necesita.

Primero, una function de utilidad:

 #http://sofes.miximages.com/questions/369758/how-to-trim-whitespace-from-bash-variable#comment21953456_3232433 alias trim="sed -e 's/^[[:space:]]*//g' -e 's/[[:space:]]*\$//g'" 

Encabezado de la documentation:

 :<<COMMENT Searches all commits in the current git repository containing a file that has *changed*, whose name matches a glob. If the glob does not contain any asterisks, then it is surrounded by them on both sides. Usage: gitf "05" #Equivalent to "*05*" gitf "05_*" Parameter is requinetworking, and must be at least one non-whitespace character. See: - http://sofes.miximages.com/questions/28119379/bash-function-to-find-all-git-commits-in-which-a-file-whose-name-matches-a-rege/28120305 - http://sofes.miximages.com/questions/28094136/bash-function-to-search-git-repository-for-a-filename-that-matches-regex/28095750 - http://sofes.miximages.com/questions/372506/how-can-i-search-git-branches-for-a-file-or-directory/372654#372654 The main "git log" line is based on this answer - http://sofes.miximages.com/a/28119940/2736496 by Stack Overflow user Greg Bacon - http://sofes.miximages.com/users/123109/greg-bacon With thanks to SwankSwashbucklers - http://sofes.miximages.com/users/2615252/swankswashbucklers Short description: Stonetworking in GITF_DESC COMMENT #GITF_DESC: For "aliaf" command (with an 'f'). Must end with a newline. GITF_DESC="gitf [glob]: Searches all commits in the current git repository containing a file that has *changed*, whose name matches a glob.\n" 

Cuerpo:

 gitf() { #Exit if no parameter is provided (if it's the empty string) param=$(echo "$1" | trim) echo "$param" if [ -z "$param" ] #http://tldp.org/LDP/abs/html/comparison-ops.html then echo "Requinetworking parameter missing. Cancelled"; return fi #http://sofes.miximages.com/questions/229551/string-contains-in-bash/229606#229606 if [[ $param != *"*"* ]] then param="*$param*" fi echo "Searching for \"$param\"..." git log -p --name-only --oneline --diff-filter=AMD --branches --tags -- "$param" } 

Ejemplo de salida:

 $ gitf 05_ 05_ Searching for "*05_*"... 14e5cdd Quick save (no message): 01-21-2015__14_36_11 non_django_files/wordpress_posts/templates/05_login_remember_me.html 2efdeb1 Part four final. Changed auth/tests in post to auth/tests_login_basic. non_django_files/wordpress_posts/templates/05_login_remember_me.html 526ca01 Part four final. Renamed auth/tests to test_basic_login, so Java doesn't need to parse the py file in future par non_django_files/wordpress_posts/templates/05_login_remember_me.html 7c227f3 Escaped unescaped dollar-signs in initial_script_sh snippet, and added delete-all-but-.git command in comment at non_django_files/wordpress_posts/templates/05_login_remember_me.html e68a30a Part four final, moved post output folder into wordpress_posts. non_django_files/wordpress_posts/templates/05_login_remember_me.html 3c5e4ec Part two final. Corrections/minor changes to all posts. non_django_files/wordpress_posts/templates/05_login_remember_me.html 3a7dac9 Finished part one. non_django_files/wordpress_posts/templates/05_login_remember_me.html f87540e Initial commit non_django_files/wordpress_posts/templates/05_login_remember_me.html