anol
Tengo alrededor de 40 repositorios git, la mayoría de los cuales tienen un .git-blame-ignore-revs
archivo para usar con git blame
. Entonces, en lugar de configurar localmente cada uno de ellos con blame.ignorerevsfile=.git-blame-ignore-revs
lo apliqué a mi global configuración de git.
Sin embargo, los pocos repositorios que no no tienen un archivo de este tipo se ven afectados por él: ejecutando git blame
sobre ellos da como resultado fatal: could not open object name list: .git-blame-ignore-revs
.
¿Hay alguna manera de decirle a git que lea dicho archivo? si existiera, ignorándolo de otra manera? Eso sería ideal: simple de configurar, pero discreto si no existe dicho archivo.
Nota: otra razón por la que tener un opcional .git-blame-ignore-revs
file es útil, es que prácticamente todos los repositorios de git se crean sin dicho archivo, y solo más tarde se agrega. Sin embargo, al dividir en dos las confirmaciones antiguas, podemos terminar volviendo a un punto antes el archivo existe, y luego tenemos que touch
termine de dividirlo en dos, luego elimínelo nuevamente para poder volver a la confirmación HEAD. Incluso si uso un local config para el archivo, esta situación extremadamente molesta seguirá ocurriendo. Por esa razón, creo que el comportamiento predeterminado debería ser ignorar el archivo si no existe.
Doctor
¿Hay alguna manera de decirle a git que lea dicho archivo si existe, ignorándolo de lo contrario?
No hay. Cualquiera de los usos
git config --local blame.ignoreRevsFile .git-blame-ignore-revs
en lugar de --global
. O usar
git config --local blame.ignoreRevsFile ""
en aquellos repositorios donde el archivo no existe. Nombre de archivo vacío significa “no usar ningún archivo”.
O crear vacío .git-blame-ignore-revs
archivos
Actualizar. Prueba con un nuevo repositorio temporal:
git init test-git
cd test-git
git config --global blame.ignoreRevsFile test
git config --show-origin blame.ignoreRevsFile
file:/home/phd/.gitconfig test
git config --local blame.ignoreRevsFile ""
git config --show-origin blame.ignoreRevsFile
file:.git/config
Upd2
git blame testfile
fatal: could not open object name list: test
¡Ay!
-
Sería genial que la configuración local tomara el relevo de la global, permitiendo ignorar la primera. Sin embargo, a pesar de que su enlace dice que Los nombres de archivo vacíos restablecerán la lista de revisiones ignoradasy esta página diciendo que “Los archivos se leen en el orden dado arriba [global before local]con el último valor encontrado prevaleciendo sobre los valores leídos anteriormente”, todavía no funciona, probablemente debido a este comportamiento: “Cuando se toman varios valores, se utilizarán todos los valores de una clave de todos los archivos”.
– anol
21 de diciembre de 2021 a las 14:42
-
@anol Muestra el resultado de
git config --show-origin blame.ignoreRevsFile
en un repositorio sin el archivo.– Doctor
21 dic 2021 a las 14:50
-
Muestra
file:$HOME/.gitconfig .git-blame-ignore-revs
como era de esperar, ya que lo configuré a través de--global
previamente. Me parece que hay una ligera desviación de comportamiento de la documentación. Incluso al agregar la opción--ignore-revs-file ""
cual es documentado como Un nombre de archivo vacío, “”, borrará la lista de revoluciones de los archivos procesados previamenteno parece ser el caso para mí: git todavía busca el.git-blame-ignore-revs
archivo y el comando falla.– anol
21 dic 2021 a las 15:00
-
@anol Ups, tienes razón! Ver Upd2. Yo diría que esto es un error en
git blame
.– Doctor
21 de diciembre de 2021 a las 15:44
-
Aparentemente un parche relacionado se ha propuesto para git en agosto, pero desde entonces creo que no ha avanzado mucho. Pero algo similar podría aterrizar en una futura versión de Git.
– anol
21 de diciembre de 2021 a las 16:16
ryan ulch
Bueno, esta no es una solución perfecta ya que no se aplicará a una culpa de git sin procesar, pero usé un alias de comando de shell. Obviamente, cambie el comando según sea necesario, pero FWIW obtuve resultados mucho mejores para mis casos de uso con ‘-w’ (ignore los espacios en blanco) proporcionados:
git config --global alias.bl "!myGitBlame.sh"
Y el script de shell correspondiente (que se supone que está en la RUTA para el comando de configuración de git anterior):
#!/usr/bin/env bash
if [[ -z $GIT_PREFIX ]]; then
GIT_PREFIX=./
fi
# Assume (and impose limitation) that the last argument to this script is the
# file being blamed. Pull it out of the args list and make it relative to the
# root of the git repo to match the execution context of git shell aliases
LAST_ARG="${@: -1}"
set -- "${@:1:$(($#-1))}"
FILE_PATH=$GIT_PREFIX$LAST_ARG
# optional ignore revs file, specified relative to the root of the git repo
OPTIONAL_GIT_BLAME_REVS_FILE=.git-blame-ignore-revs
# if the revs file does not exist, ignore-revs-file accepts empty values
# without issue
if [[ ! -f $OPTIONAL_GIT_BLAME_REVS_FILE ]]; then
OPTIONAL_GIT_BLAME_REVS_FILE=""
fi
git blame -w --ignore-revs-file=$OPTIONAL_GIT_BLAME_REVS_FILE "$@" $FILE_PATH
Y como una sola línea si desea transmitirlo fácilmente a sus compañeros de trabajo:
git config --global alias.bl '!if [[ -z $GIT_PREFIX ]]; then GIT_PREFIX=./; fi; f() { LAST_ARG="${@: -1}"; set -- "${@:1:$(($#-1))}"; FILE_PATH=$GIT_PREFIX$LAST_ARG; GIT_BLAME_REVS_FILE=.git-blame-ignore-revs; if [[ ! -f $GIT_BLAME_REVS_FILE ]]; then GIT_BLAME_REVS_FILE=""; fi; git blame -w --ignore-revs-file=$GIT_BLAME_REVS_FILE "$@" $FILE_PATH; }; f'
NOTA: Esto supone que el último argumento para culpar a git es el archivo; eso significa que esto no es 1: 1 con lo que acepta una línea de comando de culpa normal de git porque técnicamente puede git blame <commit_hash> <file>
o git blame <file> <commit_hash>
en casos simples.
Definitivamente uso esto en la forma de script de shell, pero soy consciente de las ventajas de la configuración de 1 línea para propagar esto a los compañeros de trabajo y evitar la RUTA en general.
También asumo un entorno bash disponible aquí.
Inicialmente, intenté simplemente hacer una configuración local que apunte directamente al archivo, pero eso se encuentra con todo tipo de problemas que usted describió, y también interactúa muy mal con las configuraciones del árbol de trabajo. Esto debería funcionar de manera más general, aunque no completamente a la perfección.