ver password modificados archivos and git whitespace githooks

password - Hacer que git elimine automáticamente los espacios en blanco finales antes de comprometerse



git push-u (16)

Usando los atributos de git y la configuración de filtros con git config

Bien, esta es una nueva táctica para resolver este problema ... Mi enfoque es no usar ningún gancho, sino usar filtros y atributos de git. Lo que esto le permite hacer es configurar, en cada máquina en la que se desarrolla, un conjunto de filtros que eliminarán el espacio en blanco extra al final y las líneas en blanco adicionales al final de los archivos antes de confirmarlos. Luego, configure un archivo .gitattributes que indique a qué tipos de archivos se debe aplicar el filtro. Los filtros tienen dos fases, limpia, que se aplica al agregar archivos al índice, y difuminada, que se aplica al agregarlos al directorio de trabajo.

Dile a tu git que busque un archivo de atributos globales

Primero, diga a su configuración global que use un archivo de atributos globales:

git config --global core.attributesfile ~/.gitattributes_global

Crear filtros globales

Ahora, crea el filtro:

git config --global filter.fix-eol-eof.clean fixup-eol-eof %f git config --global filter.fix-eol-eof.smudge cat git config --global filter.fix-eol-eof.required true

Añadir la magia de scripting sed

Finalmente, ponga el script fixup-eol-eof algún lugar de su ruta y fixup-eol-eof ejecutable. La secuencia de comandos usa sed para hacer algunas ediciones al vuelo (eliminar espacios y espacios en blanco al final de las líneas, y líneas en blanco extrañas al final del archivo)

fixup-eol-eof debería verse así:

#!/bin/bash sed -e ’s/[ ]*$//‘ -e :a -e ''/^/n*$/{$d;N;ba'' -e ''}'' $1

mi esencia de esto

Indique a git a qué tipos de archivos aplicar su filtro recién creado

Por último, crea o abre ~ / .gitattributes_global en tu editor favorito y agrega líneas como:

pattern attr1 [attr2 [attr3 […]]]

Entonces, si queremos solucionar el problema del espacio en blanco, para todos nuestros archivos de código fuente c, agregaríamos una línea que se parece a esto:

*.c filter=fix-eol-eof

Discusión del filtro.

El filtro tiene dos fases, la fase de limpieza que se aplica cuando las cosas se agregan al índice o se registran, y la fase de borrón cuando git pone cosas en su directorio de trabajo. Aquí, nuestra mancha simplemente está ejecutando el contenido a través del comando cat que debería dejarlos sin cambios, con la excepción de que posiblemente se agregue un carácter de nueva línea final si no hubiera uno al final del archivo. El comando de limpieza es el filtrado de espacios en blanco que formé a partir de las notas en http://sed.sourceforge.net/sed1line.txt . Parece que se debe colocar en un script de shell, no pude averiguar cómo inyectar el comando sed, incluido el saneamiento de las líneas extrañas extrañas al final del archivo directamente en el archivo git-config. (Sin embargo, PUEDE deshacerse de los espacios en blanco finales, sin la necesidad de un script sed separado, simplemente configure el filter.fix-eol-eof a algo como sed ''s/[ /t]*$//'' %f donde el /t es una pestaña real, presionando tab.)

Require = true hace que se genere un error si algo sale mal, para mantenerlo fuera de problemas.

Por favor, perdóname si mi lenguaje con respecto a git es impreciso. Creo que tengo un buen conocimiento de los conceptos pero todavía estoy aprendiendo la terminología.

Estoy usando git con mi equipo y me gustaría eliminar los cambios de espacios en blanco de mis diferencias, registros, fusiones, etc. Supongo que la forma más sencilla de hacerlo sería que git elimine automáticamente los espacios en blanco finales (y otros errores de espacios en blanco ) De todas las confirmaciones que se apliquen.

He intentado agregar lo siguiente al archivo ~/.gitconfig pero no hace nada cuando me comprometo. Tal vez está diseñado para algo diferente. ¿Cual es la solución?

[core] whitespace = trailing-space,space-before-tab [apply] whitespace = fix

Estoy usando ruby ​​en caso de que alguien tenga alguna idea específica de ruby. El siguiente paso sería el formato automático del código antes de comprometerse, pero ese es un problema difícil y en realidad no causa un gran problema.


Aquí hay una versión compatible con ubuntu + mac os x:

#!/bin/sh # # A git hook script to find and fix trailing whitespace # in your commits. Bypass it with the --no-verify option # to git-commit # if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi # Find files with trailing whitespace for FILE in `exec git diff-index --check --cached $against -- | sed ''/^[+-]/d'' | (sed -r ''s/:[0-9]+:.*//'' > /dev/null 2>&1 || sed -E ''s/:[0-9]+:.*//'') | uniq` ; do # Fix them! (sed -i ''s/[[:space:]]*$//'' "$FILE" > /dev/null 2>&1 || sed -i '''' -E ''s/[[:space:]]*$//'' "$FILE") git add "$FILE" done # Now we can commit exit

Que te diviertas


En Mac OS (o, probablemente, cualquier BSD), los parámetros del comando sed deben ser ligeramente diferentes. Prueba esto:

#!/bin/sh if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi # Find files with trailing whitespace for FILE in `exec git diff-index --check --cached $against -- | sed ''/^[+-]/d'' | sed -E ''s/:[0-9]+:.*//'' | uniq` ; do # Fix them! sed -i '''' -E ''s/[[:space:]]*$//'' "$FILE" git add "$FILE" done

Guarde este archivo como .git/hooks/pre-commit , o busque el que ya está allí, y pegue la parte inferior en algún lugar dentro de él. Y recuerda chmod a+x también.

O para uso global (a través de ganchos de Git commit - configuración global ) puede ponerlo en $GIT_PREFIX/git-core/templates/hooks (donde GIT_PREFIX es / usr o / usr / local o / usr / share o / opt / local / compartir) y ejecute git init dentro de sus git init existentes.

Según git help init :

La ejecución de git init en un repositorio existente es segura. No sobrescribirá las cosas que ya están allí. La razón principal para volver a ejecutar git init es recoger las plantillas recién agregadas.


Encontré un gancho de pre-confirmación de git que elimina los espacios en blanco finales .

#!/bin/sh if git-rev-parse --verify HEAD >/dev/null 2>&1 ; then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi # Find files with trailing whitespace for FILE in `exec git diff-index --check --cached $against -- | sed ''/^[+-]/d'' | sed -r ''s/:[0-9]+:.*//'' | uniq` ; do # Fix them! sed -i ''s/[[:space:]]*$//'' "$FILE" git add "$FILE" done exit


Es probable que esto no resuelva directamente su problema, pero es posible que desee establecerlos a través de git-config en su espacio de proyecto real, que edita ./.git/config en lugar de ~ / .gitconfig. Agradable mantener la configuración constante entre todos los miembros del proyecto.

git config core.whitespace "trailing-space,space-before-tab" git config apply.whitespace "trailing-space,space-before-tab"


Escribí este enganche de confirmación previa, que solo elimina el espacio en blanco final de las líneas que ha cambiado / agregado, ya que las sugerencias anteriores tienden a crear confirmaciones ilegibles si los archivos de destino tienen demasiado espacio en blanco al final.

#!/bin/sh if git rev-parse --verify HEAD >/dev/null 2>&1 ; then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi IFS='' '' files=$(git diff-index --check --cached $against -- | sed ''/^[+-]/d'' | perl -pe ''s/:[0-9]+:.*//'' | uniq) for file in $files ; do diff=$(git diff --cached $file) if test "$(git config diff.noprefix)" = "true"; then prefix=0 else prefix=1 fi echo "$diff" | patch -R -p$prefix diff=$(echo "$diff" | perl -pe ''s/[ /t]+$// if m{^/+}'') out=$(echo "$diff" | patch -p$prefix -f -s -t -o -) if [ $? -eq 0 ]; then echo "$diff" | patch -p$prefix -f -t -s fi git add $file done


Esos ajustes ( core.whitespace y apply.whitespace ) no están allí para eliminar los espacios en blanco finales sino para:

  • core.whitespace : core.whitespace , y levanta errores
  • apply.whitespace : y los apply.whitespace , pero solo durante el parche, no "siempre automáticamente"

Creo que el git hook pre-commit haría un mejor trabajo para eso (incluye eliminar los espacios en blanco al final)

Tenga en cuenta que, en cualquier momento, puede optar por no ejecutar el pre-commit :

  • temporalmente: git commit --no-verify .
  • permanentemente: cd .git/hooks/ ; chmod -x pre-commit cd .git/hooks/ ; chmod -x pre-commit

Advertencia: de forma predeterminada, un script de pre-commit (como este ), no tiene una "característica final", sino una característica de "advertencia" como:

if (//s$/) { bad_line("trailing whitespace", $_); }

Sin embargo, podría crear un mejor gancho de pre-commit , especialmente si considera que:

El hecho de comprometerse en Git con solo algunos cambios agregados al área de preparación todavía resulta en una revisión "atómica" que puede que nunca haya existido como una copia de trabajo y que no funcione .

Por ejemplo, oldman propone en otra respuesta un gancho de pre-commit que detecta y elimina los espacios en blanco.
Ya que ese gancho obtiene el nombre de archivo de cada archivo, recomendaría tener cuidado con cierto tipo de archivos: ¡no desea eliminar los espacios en blanco finales en los .md (markdown)!


Estaba pensando en esto hoy. Esto es todo lo que terminé haciendo para un proyecto java:

egrep -rl '' $'' --include *.java * | xargs sed -i ''s//s/+$//g''


Esto no elimina los espacios en blanco automáticamente antes de un compromiso, pero es bastante fácil de realizar. Pongo el siguiente script de Perl en un archivo llamado git-wsf (git whitespace fix) en un directorio en $ PATH para que pueda:

git wsf | sh

y elimina todos los espacios en blanco solo de las líneas de archivos que git informa como un diff.

#! /bin/sh git diff --check | perl -x $0 exit #! /usr/bin/perl use strict; my %stuff; while (<>) { if (/trailing whitespace./) { my ($file,$line) = split(/:/); push @{$stuff{$file}},$line; } } while (my ($file, $line) = each %stuff) { printf "ex %s <<EOT/n", $file; for (@$line) { printf ''%ds/ *$//''."/n", $_; } print "wq/nEOT/n"; }


Para eliminar espacios en blanco al final de la línea en un archivo, use ed :

test -s file && printf ''%s/n'' H '',g/[[:space:]]*$/s///'' ''wq'' | ed -s file


Para usuarios de Sublime Text .

Establezca lo siguiente correctamente en su configuración de configuración de usuario .

"trim_trailing_white_space_on_save": true


Por favor, intente mis enlaces de confirmación previa , puede detectar automáticamente los espacios en blanco y eliminarlos . ¡Gracias!

¡Puede funcionar bajo GitBash(windows), Mac OS X and Linux !

Instantánea:

$ git commit -am "test" auto remove trailing whitespace in foobar/main.m! auto remove trailing whitespace in foobar/AppDelegate.m! [master 80c11fe] test 1 file changed, 2 insertions(+), 2 deletions(-)


Prefiero dejar esta tarea a tu editor favorito.

Solo establece un comando para eliminar los espacios finales al guardar.


Puedes engañar a Git para que arregle el espacio en blanco por ti, engañando a Git para que trate tus cambios como un parche. A diferencia de las soluciones de "gancho de pre-confirmación", estas soluciones agregan comandos de corrección de espacios en blanco a Git.

Sí, estos son hacks.

Soluciones robustas

Los siguientes alias de Git se toman de mi ~/.gitconfig .

Por "robusto" me refiero a que estos alias se ejecutan sin error, haciendo lo correcto, sin importar si el árbol o el índice están sucios. Sin embargo, no funcionan si una git rebase -i interactiva ya está en progreso; vea mi ~/.gitconfig para verificaciones adicionales si le interesa este caso de esquina, donde el truco de git add -e descrito al final debería funcionar.

Si desea ejecutarlos directamente en el shell, sin crear un alias de Git, simplemente copie y pegue todo entre comillas dobles (asumiendo que su shell es como Bash).

Corregir el índice pero no el árbol.

Las siguientes fixws alias Git alias corrigen todos los errores de espacio en blanco en el índice, si los hay, pero no tocan el árbol:

# Logic: # # The ''git stash save'' fails if the tree is clean (instead of # creating an empty stash :P). So, we only ''stash'' and ''pop'' if # the tree is dirty. # # The ''git rebase --whitespace=fix HEAD~'' throws away the commit # if it''s empty, and adding ''--keep-empty'' prevents the whitespace # from being fixed. So, we first check that the index is dirty. # # Also: # - ''(! git diff-index --quiet --cached HEAD)'' is true (zero) if # the index is dirty # - ''(! git diff-files --quiet .)'' is true if the tree is dirty # # The ''rebase --whitespace=fix'' trick is from here: # https://.com/a/19156679/470844 fixws = !"/ if (! git diff-files --quiet .) && / (! git diff-index --quiet --cached HEAD) ; then / git commit -m FIXWS_SAVE_INDEX && / git stash save FIXWS_SAVE_TREE && / git rebase --whitespace=fix HEAD~ && / git stash pop && / git reset --soft HEAD~ ; / elif (! git diff-index --quiet --cached HEAD) ; then / git commit -m FIXWS_SAVE_INDEX && / git rebase --whitespace=fix HEAD~ && / git reset --soft HEAD~ ; / fi"

La idea es ejecutar git fixws antes de git commit si tiene errores de espacio en blanco en el índice.

Fijar el índice y el árbol.

El siguiente fixws-global-tree-and-index corrige todos los errores de espacios en blanco en el índice y el árbol, si los hay:

# The different cases are: # - dirty tree and dirty index # - dirty tree and clean index # - clean tree and dirty index # # We have to consider separate cases because the ''git rebase # --whitespace=fix'' is not compatible with empty commits (adding # ''--keep-empty'' makes Git not fix the whitespace :P). fixws-global-tree-and-index = !"/ if (! git diff-files --quiet .) && / (! git diff-index --quiet --cached HEAD) ; then / git commit -m FIXWS_SAVE_INDEX && / git add -u :/ && / git commit -m FIXWS_SAVE_TREE && / git rebase --whitespace=fix HEAD~2 && / git reset HEAD~ && / git reset --soft HEAD~ ; / elif (! git diff-files --quiet .) ; then / git add -u :/ && / git commit -m FIXWS_SAVE_TREE && / git rebase --whitespace=fix HEAD~ && / git reset HEAD~ ; / elif (! git diff-index --quiet --cached HEAD) ; then / git commit -m FIXWS_SAVE_INDEX && / git rebase --whitespace=fix HEAD~ && / git reset --soft HEAD~ ; / fi"

Para corregir también los espacios en blanco en archivos no versionados, haz

git add --intent-to-add <unversioned files> && git fixws-global-tree-and-index

Soluciones simples pero no robustas.

Estas versiones son más fáciles de copiar y pegar, pero no hacen lo correcto si no se cumplen sus condiciones secundarias.

Arregle el subárbol enraizado en el directorio actual (pero restablece el índice si no está vacío)

Usando git add -e para "editar" los parches con el editor de identidad:

(export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue .) && git checkout . && git reset

Corrija y conserve el índice (pero falla si el árbol está sucio o el índice está vacío)

git commit -m TEMP && git rebase --whitespace=fix HEAD~ && git reset --soft HEAD~

Corrija el árbol y el índice (pero restablece el índice si no está vacío)

git add -u :/ && git commit -m TEMP && git rebase --whitespace=fix HEAD~ && git reset HEAD~

Explicación de la export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue . truco

Antes de aprender sobre el git rebase --whitespace=fix de esta respuesta , estaba usando el truco de git add más complicado en todas partes.

Si lo hiciéramos manualmente:

  1. Establezca apply.whitespace para fix (solo debe hacerlo una vez):

    git config apply.whitespace fix

    Esto le dice a Git que arregle los espacios en blanco en parches .

  2. Convence a Git para que trate tus cambios como un parche :

    git add -up .

    Pulse a + enter para seleccionar todos los cambios para cada archivo. Recibirá una advertencia sobre Git que corrige sus errores de espacios en blanco.
    ( git -c color.ui=auto diff en este punto revela que sus cambios no indexados son exactamente los errores de espacio en blanco).

  3. Elimine los errores de espacio en blanco de su copia de trabajo:

    git checkout .

  4. Recupere sus cambios (si no está listo para cometerlos):

    git reset

GIT_EDITOR=: significa usar : como editor, y como comando : es la identidad.


Un poco tarde, pero como esto podría ayudar a alguien, ahí va.

Abra el archivo en VIM. Para reemplazar las pestañas con espacios en blanco, escriba lo siguiente en la línea de comandos vim

:%s#/t# #gc

Para deshacerse de otros espacios en blanco finales

:%s#/s##gc

Esto casi lo hizo por mí. Es tedioso si tienes muchos archivos para editar. Pero me resultó más fácil que los ganchos de precompromiso y trabajar con varios editores.


el for-loop para archivos usa la variable de shell $ IFS. en el script dado, los nombres de archivo con un carácter en ellos que también están en la variable $ IFS se verán como dos archivos diferentes en el bucle for. Esta secuencia de comandos lo corrige: el modificador de modo multilínea dado que sed-manual no parece funcionar de manera predeterminada en mi caja de Ubuntu, por lo que busqué una implementación diferente y encontré esto con una etiqueta iterativa, esencialmente solo iniciará la sustitución en el Última línea del archivo si lo he entendido correctamente.

#!/bin/sh # # A git hook script to find and fix trailing whitespace # in your commits. Bypass it with the --no-verify option # to git-commit # if git rev-parse --verify HEAD >/dev/null 2>&1 then against=HEAD else # Initial commit: diff against an empty tree object against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 fi SAVEIFS="$IFS" # only use new-line character as seperator, introduces EOL-bug? IFS='' '' # Find files with trailing whitespace for FILE in $( git diff-index --check --cached $against -- / | sed ''/^[+-]/d'' / | ( sed -r ''s/:[0-9]+:.*//'' || sed -E ''s/:[0-9]+:.*//'' ) / | uniq / ) do # replace whitespace-characters with nothing # if first execution of sed-command fails, try second one( MacOSx-version) ( sed -i '':a;N;$!ba;s//n/+$//'' "$FILE" > /dev/null 2>&1 / || / sed -i '''' -E '':a;N;$!ba;s//n/+$//'' "$FILE" / ) / && / # (re-)add files that have been altered to git commit-tree # when change was a [:space:]-character @EOL|EOF git-history becomes weird... git add "$FILE" done # restore $IFS IFS="$SAVEIFS" # exit script with the exit-code of git''s check for whitespace-characters exec git diff-index --check --cached $against --

[1] patrón sed-subsition: ¿Cómo puedo reemplazar una nueva línea (/ n) usando sed? .