Haga que git elimine automáticamente los espacios en blanco al final antes de confirmar


220

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 fácil 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 a medida que se aplican.

Intenté agregar lo siguiente por ~/.gitconfigarchivo, 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 formateo automático del código antes de comprometerse, pero ese es un problema difícil y realmente no está causando un gran problema.


Si la directiva core.whitespace no soluciona sus problemas, también puede cambiar el enlace de precompromiso (.git / hooks / pre-commit) para encontrarlos y solucionarlos. Vea esta publicación para una descripción detallada.
VolkA

2
Me sentí frustrado con errores similares de espacios en blanco y soluciones parciales, y escribí una utilidad flexible y bastante completa que puede corregir o simplemente informar errores de espacios en blanco que perturban los sistemas de control de versiones: Whitespace Total Fixer en Github (disculpas si esto es demasiado autopromocional)
Dan Lenski

Respuestas:


111

Esas configuraciones ( core.whitespacey apply.whitespace) no están ahí para eliminar los espacios en blanco finales sino para:

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

Creo git hook pre-commitque haría un mejor trabajo para eso (incluye eliminar los espacios en blanco finales)


Tenga en cuenta que en cualquier momento puede elegir no ejecutar el pre-commitenlace:

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

Advertencia: de forma predeterminada, una pre-commitsecuencia de comandos (como esta ) no tiene una función de "eliminación final", sino una función de "advertencia" como:

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

Sin embargo, podría construir un pre-commitgancho mejor , especialmente si considera que:

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


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


1
Resulta que se puede convencer a git para que corrija los espacios en blanco en su copia de trabajo apply.whitespace, engañando a git para que trate sus cambios de copia de trabajo como un parche. Vea mi respuesta a continuación .
ntc2

> "no desea eliminar espacios en blanco finales en archivos .md (markdown)" - ¿Por qué es eso? ¿Cuál es el propósito de los espacios en blanco finales en los archivos de rebajas? Noté que algunos .editorconfigarchivos tienen una regla específica para eso.
friederbluemle

55
@friederbluemle dependiendo del tipo de descuento, un espacio doble al final indica <br>: github.com/FriendsOfPHP/PHP-CS-Fixer/issues/…
VonC

Establecer core.whitespacea trailing-spacecon git configno genera error al cometer en git2.5.0.
Karl Richter

43

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. En contraste con las soluciones de "enlace previo al compromiso", estas soluciones agregan comandos de fijación de espacios en blanco a Git.

Sí, estos son hacks.


Soluciones robustas

Los siguientes alias de Git están tomados de mi~/.gitconfig .

Por "robusto" quiero decir que estos alias se ejecutan sin error, haciendo lo correcto, independientemente de si el árbol o el índice están sucios. Sin embargo, no funcionan si un interactivo git rebase -iya está en progreso; vea mi~/.gitconfig para verificaciones adicionales si le importa este caso de esquina, donde el git add -etruco descrito al final debería funcionar.

Si desea ejecutarlos directamente en el shell, sin crear un alias Git, simplemente copie y pegue todo entre las comillas dobles (suponiendo que su shell sea Bash).

Arregla el índice pero no el árbol

El siguiente fixwsalias de Git corrige todos los errores de espacios en blanco en el índice, si los hay, pero no toca 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://stackoverflow.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 correr git fixws antes git commitsi tiene errores de espacio en blanco en el índice.

Repara el índice y el árbol

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

# 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, haga

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.

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

Utilizando git add -epara "editar" los parches con el editor de identidad ::

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

Repara y preserva 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~

Repara 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 del export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue .truco.

Antes de conocer el git rebase --whitespace=fixtruco de esta respuesta , estaba usando el git addtruco más complicado en todas partes.

Si lo hicimos manualmente:

  1. Establezca apply.whitespaceen fix(solo tiene que hacer esto una vez):

    git config apply.whitespace fix
    

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

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

    git add -up .
    

    Presione a+ enterpara seleccionar todos los cambios para cada archivo. Recibirás una advertencia sobre Git arreglando tus errores de espacio en blanco.
    ( git -c color.ui=auto diffen 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 confirmarlos):

    git reset
    

El GIT_EDITOR=:medio para usar :como editor y como comando :es la identidad.


1
Lo acabo de probar en Windows: esto funciona bien en un símbolo del sistema de DOS : tenga en set VISUAL= && git add -ue . && git checkout .cuenta el ' .' utilizado con git add: eso se debe a git1.8.3
VonC

@VonC ¿No se deshabilitará VISUAL permanentemente, lo que puede, por ejemplo, causar un uso posterior de git commitusar el editor incorrecto? Envuelvo la VISUAL=parte en un subshell en mi versión de Unix anterior para evitar esto, pero no sé si DOS tiene subshells.
ntc2

1
Gracias por el gran truco! Para su información, si ha core.editorconfigurado, exportar VISUALno tiene ningún efecto porque la configuración tiene prioridad por man git-var. Para anular esto, debe exportar en su GIT_EDITOR=:lugar.
Nick sintió el

1
Además, modifiqué mi versión fixwspara que falle rápidamente si ya estás en un rebase interactivo ya que de lo contrario morirá en la git rebase --whitespace=fixlínea y te dejará en un estado extraño. Tomé prestado de esta pregunta y acabo de agregar un caso adicional antes del if: fixws = !"\ if test -d $(git rev-parse --git-dir)/rebase-merge ; then \ echo 'In rebase - cannot fixws' ; \ elif (! git diff-files --quiet .) && \ (! git diff-index --quiet --cached HEAD) ; then \ ...
Nick Felt

1
FYI: adapté esto en un gancho previo al compromiso
Ian Kelling

29

Encontré un gancho de confirmación previa 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

3
La segunda sedinvocación ( sed -r 's/:[0-9]+:.*//') podría sustituirse por cut -f1 -d:. Esto debería funcionar igual en plataformas basadas en Linux y BSD.
Ihor Kaharlichenko

2
@IhorKaharlichenko: en realidad, el uso cutno es tan seguro como el segundo sed: el corte fallará en el caso (muy poco probable) de los nombres de archivo que contienen ":". Podrías awk 'NF>2{NF-=2}1'estar a salvo
MestreLion

1
Por cierto, si está en Windows (msysgit) y usa core.autocrlf=true, es posible que desee agregar dos2unix -D "$FILE"dentro del bucle for, después de sed. De lo contrario, cambiará todos los CRLF a LF emitiendo solo sed.
jakub.g

49
Hacer git adddentro de un gancho de compromiso me parece bastante malvado. ¿Qué sucede si está realizando una puesta en escena / confirmación parcial de un archivo? No desea que el archivo completo se confirme a sus espaldas, ¿verdad?
Stefaan

19

En Mac OS (o, probablemente, cualquier BSD), los parámetros del comando sed tienen que 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-commito busque el que ya está allí y pegue el fragmento inferior en algún lugar dentro de él. Y recuérdalo chmod a+xtambién.

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

De acuerdo a git help init:

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


77
¿No está este gancho modificando el archivo de trabajo y sobrescribiendo el índice con el archivo de trabajo modificado? Si tuviera que 'git add -p' para construir su índice, este enlace de confirmación lo dejaría sin palabras.
Matthew Dutton el

2
Sí, probablemente tengas razón. Es posible que alguien deba volver a escribir este script para usarlo git hash-object -wy git update-index(re) insertar el archivo modificado directamente en el índice. Alguien muy valiente.
AlexChaffee

11

Prefiero dejar esta tarea a tu editor favorito.

Simplemente configure un comando para eliminar los espacios finales al guardar.


2
En vim puede hacer esto con: autocmd BufWritePre .cpp, .c, *. H:% / \ s \ + $ // e
Robert Massaioli

3
Lo siento, he votado el comentario anterior antes de probarlo. Falta una "s" después del signo de porcentaje, y moverá el cursor si se encuentra un espacio en blanco, y eliminará el último patrón de búsqueda. Consulte vim.wikia.com/wiki/Remove_unwanted_spaces para obtener mejores alternativas.
Seth Johnson

1
En emacs es Mx delete-trailing-whitespace.
Mauvis Ledford

2
Mejor aún, para emacs, establezca un enlace para eliminar los espacios en blanco finales antes de guardar agregando (add-hook 'before-save-hook 'delete-trailing-whitespace)a su .emacsarchivo. Trucos de espacios en blanco de Emacs
Duncan Parkes

1
Yo uso (add-hook 'before-save-hook' whitespace-cleanup) que también convierte las pestañas en espacios.
Nils Fagerburg

10

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

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

Dile a tu git que busque un archivo de atributos globales

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

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

Crea 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

Agregue la magia de scripting sed

Finalmente, pon el fixup-eol-eof script en algún lugar de su ruta y hágalo ejecutable. La secuencia de comandos utiliza sed para realizar algunas modificaciones sobre la marcha (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

Dígale a git a qué tipos de archivo debe aplicar su filtro recién creado

Por último, cree o abra ~ / .gitattributes_global en su editor favorito y agregue líneas como:

pattern attr1 [attr2 [attr3 […]]]

Por lo tanto, si queremos solucionar el problema de los espacios en blanco, para todos nuestros archivos fuente c, agregaríamos una línea que se ve así:

*.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 borrones cuando git pone cosas en su directorio de trabajo. Aquí, nuestra mancha solo está ejecutando el contenido a través del catcomando que debería dejarlos sin cambios, con la excepción de posiblemente agregar un carácter de nueva línea final si no hubiera uno al final del archivo. El comando clean es el filtro de espacios en blanco que improvisé a partir de notas en http://sed.sourceforge.net/sed1line.txt . Parece que debe colocarse en un script de shell, no pude descubrir cómo inyectar el comando sed, incluido el saneamiento de las líneas extrañas al final del archivo directamente en el archivo git-config. (Tú PUEDESsin embargo, sin la necesidad de un script sed separado, elimine los espacios en blanco al final, simplemente configure filter.fix-eol-eofalgo como sed 's/[ \t]*$//' %fdonde \testá una pestaña real, presionando la pestaña).

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

Perdóname si mi lenguaje sobre git es impreciso. Creo que entiendo bastante bien los conceptos, pero todavía estoy aprendiendo la terminología.


Enfoque interesante +1
VonC

Gracias @VonC! También quiero aprovechar esta oportunidad para señalar que los atributos de git se pueden configurar de forma individual en la .gitcarpeta en lugar de hacerlo globalmente, lo que podría tener más sentido.
zbeekman

9

Escribí este enlace previo a la confirmación, 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 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

1
Interesante. +1. Vea mi otra respuesta para calcular el árbol vacío.
VonC

1
Buena idea, esto es exactamente lo que quisiera. ¡Sin embargo, tenga cuidado al usar esto! Para mí en OSX y git versión 2.3.5, elimina todos los cambios adicionales pero no confirmados que he organizado. Sin embargo, todavía estaría interesado en una solución de trabajo para esto.
Casper

9

Pruebe mis ganchos de precompromiso , puede detectar automáticamente el espacio en blanco al final y eliminarlo . ¡Gracias!

puede funcionar debajo 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(-)

1
Interesante. +1. He hecho referencia a su anzuelo en mi propia respuesta
VonC

@VonC ¡Gracias por tu afirmación! Al '.md', solo encontré git commit -no-verifyalguna sugerencia.
oldman

Prefiero que el gancho pueda detectar el .mdarchivo y no eliminar los espacios en blanco, en lugar de pedirle al usuario final que agregue una --no-verifyopción en el git commit.
VonC

Falla si confirma un archivo / directorio que comienza con un +o-
Rody Oldenhuis

6

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


Parece que la única diferencia entre la tuya y la mía es que compruebas que sed realmente reemplazará algo antes de reescribir el archivo ... No estoy seguro de que eso importe, ya que git no confirma cambios que en realidad no cambian nada. Supongo que es marginalmente más seguro, pero también marginalmente más lento, y prefiero la claridad de no repetir las expresiones regulares dos veces en una línea. De gustibus non disputandum est!
AlexChaffee

no, la diferencia es que la versión está usando la sintaxis de ubuntu primero y (si eso falla) luego la de osx.
publicado el

1
Edité la publicación de sdepold, ahora también debería permitir espacios en blanco en los nombres de archivo.
Imme

5

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

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

3

Para usuarios de Sublime Text .

Establezca lo siguiente correctamente en su configuración de Configuración-Usuario .

"trim_trailing_white_space_on_save": true


1
¿Es una forma de configurar esto por tipo de archivo? Tengo *.mdarchivos (de reducción) que dependen de "" (espacios dobles finales) para marcar un simple <br />, y esa configuración parece aplicarse a todos los archivos, incluidos los que no quiero eliminar.
VonC

@VonC Hay una jerarquía sobre cómo se aplica la configuración. Más detalles aquí, stackoverflow.com/questions/16983328/… espero que ayude
Haris Krajina

2

el for-loop para archivos usa la variable de shell $ IFS. en el script dado, los nombres de archivo con un carácter que también está en la variable $ IFS se verán como dos archivos diferentes en el ciclo for. Este script lo corrige: el modificador de modo multilínea dado que el manual de sed dado no parece funcionar de manera predeterminada en mi cuadro de ubuntu, así que busqué una implementación diferente y encontré esto con una etiqueta iterativa, esencialmente solo comenzará 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 de sed-subsition: ¿Cómo puedo reemplazar una nueva línea (\ n) usando sed? .


2

Esto no elimina los espacios en blanco automáticamente antes de una confirmación, pero es bastante fácil de realizar. Puse el siguiente script de Perl en un archivo llamado git-wsf (corrección de espacio en blanco git) 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 una diferencia.

#! /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";
}

0

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

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

:%s#\t#    #gc

Para deshacerse de otros espacios en blanco finales

:%s#\s##gc

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


Si se vuelve tedioso, y si tiene una copia de seguridad de lo que está a punto de editar, a menudo solo uso sed para cambiar las pestañas a espacios: sed -i 's|\t| |g' filenames(espacios en la posición de reemplazo). Tenga en cuenta que puede usar find para obtener sus nombres de archivo. Si no ha pensado en cómo obtener esa copia de seguridad, generalmente solo confirmo todo y luego 'deshago' la confirmación con un restablecimiento parcial de nuevo a donde estoy; a veces agrego todo al árbol pero no me comprometo, y a veces uso el alijo / aplicar (¡no pop!). Si me siento ansioso, RSYNC toda mi árbol a un lugar seguro antes de entrometerse ...
salvia

0

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

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

-1

Esto probablemente no resolverá 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. Es bueno mantener la configuración consistente entre todos los miembros del proyecto.

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

3
afaik, la configuración dentro de .git no se comparte con nadie más; son específicos de su repositorio local
AlexChaffee
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.