Faça o git remover automaticamente o espaço em branco à direita antes de confirmar


220

Estou usando o git com minha equipe e gostaria de remover alterações de espaço em branco dos meus diffs, logs, mesclagens etc. Estou assumindo que a maneira mais fácil de fazer isso seria o git remover automaticamente o espaço em branco à direita (e outros erros de espaço em branco) ) de todas as confirmações conforme são aplicadas.

Eu tentei adicionar o seguinte ao ~/.gitconfigarquivo, mas ele não faz nada quando eu confirmo. Talvez tenha sido projetado para algo diferente. Qual a solução?

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

Estou usando ruby, caso alguém tenha alguma idéia específica sobre rubi. A formatação automática de código antes da confirmação seria o próximo passo, mas esse é um problema difícil e realmente não está causando um grande problema.


Se a diretiva core.whitespace não corrigir seus problemas, você também poderá alterar o gancho de pré-confirmação (.git / hooks / pre-commit) para encontrar e corrigi-los para você. Veja este post para uma descrição detalhada.
— VolkA

2
Fiquei frustrado com erros semelhantes de espaço em branco e soluções parciais e escrevi um utilitário flexível e bastante completo que pode corrigir ou simplesmente relatar erros de espaço em branco que perturbam os sistemas de controle de versão: Whitespace Total Fixer no Github (desculpas se isso for muito autopromocional)
— Dan Lenski

Respostas:


111

Essas configurações ( core.whitespacee apply.whitespace) não existem para remover o espaço em branco à direita, mas para:

  • core.whitespace: detectá-los e gerar erros
  • apply.whitespace: e retire-os, mas apenas durante o patch, nem sempre "automaticamente"

Eu acredito que o git hook pre-commitfaria um trabalho melhor para isso (inclui remover espaços em branco à direita)


Observe que a qualquer momento você pode optar por não executar o pre-commitgancho:

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

Aviso: por padrão, um pre-commitscript (como este ) não possui um recurso "remover à direita", mas um recurso de "aviso" como:

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

No entanto, você pode criar um pre-commitgancho melhor , especialmente quando considera que:

A confirmação no Git com apenas algumas alterações adicionadas à área de preparação ainda resulta em uma revisão "atômica" que pode nunca ter existido como uma cópia de trabalho e pode não funcionar .


Por exemplo, oldman propõe em outra resposta um pre-commitgancho que detecta e remove os espaços em branco.
Como esse gancho obtém o nome de cada arquivo, eu recomendaria ter cuidado com certos tipos de arquivos: você não deseja remover o espaço em branco à direita nos .mdarquivos (descontos)!


1
Acontece que o git pode ser convencido a corrigir espaços em branco na sua cópia de trabalho apply.whitespace, enganando o git a tratar suas alterações na cópia de trabalho como um patch. Veja minha resposta abaixo .
— Ntc2 13/03/2013

> "você não deseja remover o espaço em branco à direita nos arquivos .md (markdown)" - Por que isso? Qual é o objetivo de rastrear espaços em branco nos arquivos de remarcação? Notei que alguns .editorconfigarquivos têm uma regra específica para isso.
— Friederbluemle

5
@friederbluemle, dependendo do tipo de remarcação, um espaço duplo à direita indica <br>: github.com/FriendsOfPHP/PHP-CS-Fixer/issues/…
— VonC

Definir core.whitespacepara trailing-spacecom git confignão gera erro ao confirmar no git2.5.0.
— Karl Richter

43

Você pode induzir o Git a corrigir o espaço em branco para você, enganando o Git a tratar suas alterações como um patch. Ao contrário das soluções "gancho de pré-confirmação", essas soluções adicionam comandos de correção de espaço em branco ao Git.

Sim, estes são hacks.


Soluções robustas

Os seguintes aliases do Git são retirados do meu~/.gitconfig .

Por "robusto", quero dizer que esses aliases são executados sem erros, fazendo a coisa certa, independentemente de a árvore ou o índice estarem sujos. No entanto, eles não funcionam se uma interativa git rebase -ijá estiver em andamento; consulte o meu~/.gitconfig para verificações adicionais se você se importa com este caso de canto, onde o git add -etruque descrito no final deve funcionar.

Se você deseja executá-los diretamente no shell, sem criar um alias do Git, basta copiar e colar tudo entre aspas duplas (assumindo que o seu shell seja do tipo Bash).

Corrija o índice, mas não a árvore

O seguinte fixwsalias do Git corrige todos os erros de espaço em branco no índice, se houver, mas não toca na árvore:

# 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"

A ideia é executar git fixwsantes git commitse houver erros de espaço em branco no índice.

Corrija o índice e a árvore

O fixws-global-tree-and-indexalias do Git a seguir corrige todos os erros de espaço em branco no índice e na árvore, se houver:

# 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 também corrigir espaços em branco em arquivos não versionados, faça

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

Soluções simples, mas não robustas

Essas versões são mais fáceis de copiar e colar, mas não fazem a coisa certa se suas condições colaterais não forem atendidas.

Corrija a subárvore com raiz no diretório atual (mas redefina o índice se não estiver vazio)

Usando git add -epara "editar" os patches com o editor de identidade ::

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

Corrija e preserve o índice (mas falhará se a árvore estiver suja ou o índice estiver vazio)

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

Corrija a árvore e o índice (mas redefine o índice se não estiver vazio)

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

Explicação do export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue .truque

Antes de aprender sobre o git rebase --whitespace=fixtruque desta resposta, eu estava usando o git addtruque mais complicado em todos os lugares.

Se o fizermos manualmente:

  1. Defina apply.whitespacecomo fix(você só precisa fazer isso uma vez):

    git config apply.whitespace fix
    

    Isso diz ao Git para corrigir espaços em branco nos patches .

  2. Convença o Git a tratar suas alterações como um patch :

    git add -up .
    

    Pressione a+ enterpara selecionar todas as alterações para cada arquivo. Você receberá um aviso sobre o Git corrigindo os erros de espaço em branco.
    ( git -c color.ui=auto diffneste momento, revela que suas alterações não indexadas são exatamente os erros de espaço em branco).

  3. Remova os erros de espaço em branco da sua cópia de trabalho:

    git checkout .
    
  4. Traga de volta suas alterações (se você não estiver pronto para confirmá-las):

    git reset
    

O GIT_EDITOR=:meio de usar :como editor e como comando :é a identidade.


1
Acabei de testar no Windows: isso funciona muito bem em um prompt de comando do DOS: set VISUAL= && git add -ue . && git checkout .Observe o ' .' usado com git add: isso é devido ao git1.8.3
— VonC

@VonC Isso não desativará o VISUAL permanentemente, o que pode, por exemplo, fazer com que um uso subseqüente git commituse o editor errado? Envolvo a VISUAL=parte em um subshell na versão unix acima para evitar isso, mas não sei se o DOS tem subshells.
— Ntc2 26/07

1
Obrigado pelo ótimo hack! Para sua informação, se você core.editorconfigurou, a exportação VISUALnão terá efeito, pois a configuração terá precedência por man git-var. Para substituir isso, você precisa exportar GIT_EDITOR=:.
— perfil completo de Nick Felt

1
Além disso, aprimorei minha versão fixwspara falhar rapidamente, se você já estiver em uma recuperação interativa, pois, caso contrário, ela morrerá na git rebase --whitespace=fixlinha e deixará você em um estado estranho. I emprestado esta pergunta e acabou de adicionar um caso extra antes do caso: 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: Eu adaptado isso em um gancho pré-comprometer
— Ian Kelling

29

Encontrei um gancho de pré-confirmação do git que remove os espaços em branco à direita .

#!/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
A segunda sedinvocação ( sed -r 's/:[0-9]+:.*//') pode ser substituída por cut -f1 -d:. Isso deve funcionar da mesma forma nas plataformas Linux e BSD.
— Ihor Kaharlichenko

2
@IhorKaharlichenko: na verdade, o uso cutnão é tão seguro quanto o segundo sed: o corte falhará no caso (altamente improvável) de nomes de arquivos que contêm ":". Você poderia usar awk 'NF>2{NF-=2}1'para ser seguro
— MestreLion

1
BTW, se você estiver no Windows (msysgit) e core.autocrlf=trueestiver usando , poderá adicionar dos2unix -D "$FILE"dentro do loop for, depois do sed. Caso contrário, ele mudará todos os CRLFs para LFs emitindo apenas sed.
— 31412 jokub.g

49
Fazer git adddentro de um gancho de confirmação parece muito ruim para mim. E se você estiver fazendo teste / confirmação parcial de um arquivo? Você não quer que o arquivo completo seja confirmado pelas costas, não é?
— Stefaan

19

No Mac OS (ou, provavelmente, em qualquer BSD), os parâmetros do comando sed precisam ser um pouco diferentes. Tente o seguinte:

#!/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

Salve este arquivo como .git/hooks/pre-commit- ou procure o que já está lá e cole o pedaço inferior em algum lugar dentro dele. E lembre-se chmod a+xdisso também.

Ou para uso global (via Git commit hooks - configurações globais ), você pode colocá-lo $GIT_PREFIX/git-core/templates/hooks(onde GIT_PREFIX é / usr ou / usr / local ou / usr / share ou / opt / local / share) e executar git initdentro de seus repositórios existentes.

De acordo com git help init:

A execução do git init em um repositório existente é segura. Ele não substituirá as coisas que já estão lá. O principal motivo para executar novamente o git init é pegar os modelos adicionados recentemente.


7
Esse gancho não está modificando o arquivo de trabalho e substituindo o índice pelo arquivo de trabalho modificado? Se você 'git add -p' construísse seu índice, esse gancho de commit iria acabar com isso.
— Matthew Dutton

2
Sim, você provavelmente está certo. Alguém pode precisar reescrever esse script para usar git hash-object -we git update-index(re) inserir o arquivo munged diretamente no índice. Alguém muito corajoso.
— AlexChaffee

11

Prefiro deixar essa tarefa para o seu editor favorito.

Basta definir um comando para remover os espaços finais ao salvar.


2
No vim você pode fazer isso com: BufWritePre autocmd .cpp, .c, * h:% / \ s \ + $ // e.
— Robert Massaioli

3
Desculpe, votei no comentário acima antes de testá-lo. Há um "s" ausente após o sinal de porcentagem, e ele moverá o cursor se houver espaço em branco e removerá o último padrão de pesquisa. Consulte vim.wikia.com/wiki/Remove_unwanted_spaces para obter melhores alternativas.
— Seth Johnson

1
No emacs, é Mx delete-trailing-whitespace.
— Mauvis Ledford

2
Melhor ainda, para o emacs, defina um gancho para excluir o espaço em branco à direita antes de salvar adicionando (add-hook 'before-save-hook 'delete-trailing-whitespace)ao seu .emacsarquivo. Emacs espaços em branco truques
— Duncan Parkes

1
Eu uso (add-hook 'before-save-hook' whitespace-cleanup) que também converte guias em espaços.
— Nils Fagerburg #

10

Usando atributos git e configuração de filtros com git config

OK, esta é uma nova abordagem para resolver esse problema ... Minha abordagem é não usar ganchos, mas usar filtros e atributos git. O que isso permite, é configurar, em cada máquina em que você desenvolve, um conjunto de filtros que eliminam o espaço em branco e as linhas em branco no final dos arquivos antes de enviá-los. Em seguida, configure um arquivo .gitattributes que indique em quais tipos de arquivos o filtro deve ser aplicado. Os filtros têm duas fases, cleanque são aplicadas ao adicionar arquivos ao índice e smudgeque são aplicadas ao adicioná-los ao diretório de trabalho.

Diga ao seu git para procurar um arquivo de atributos globais

Primeiro, diga à sua configuração global para usar um arquivo de atributos globais:

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

Crie filtros globais

Agora, crie o 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

Adicione a mágica do script sed

Por fim, coloque o fixup-eol-eofscript em algum lugar do seu caminho e torne-o executável. O script usa sed para fazer algumas edições dinâmicas (remova espaços e espaços em branco no final das linhas e linhas em branco estranhas no final do arquivo)

fixup-eol-eof deve ficar assim:

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

minha essência disso

Diga ao git quais tipos de arquivo aplicar o filtro recém-criado

Por fim, crie ou abra ~ / .gitattributes_global no seu editor favorito e adicione linhas como:

pattern attr1 [attr2 [attr3 […]]]

Portanto, se quisermos corrigir o problema de espaço em branco, para todos os nossos arquivos de origem c, adicionaremos uma linha parecida com esta:

*.c filter=fix-eol-eof

Discussão do filtro

O filtro tem duas fases, a fase limpa, que é aplicada quando as coisas são adicionadas ao índice ou registradas, e a fase de borrar, quando o git coloca coisas no seu diretório de trabalho. Aqui, nossa mancha está apenas executando o conteúdo através do catcomando que deve mantê-lo inalterado, com a exceção de possivelmente adicionar um caractere de nova linha à direita, se não houver um no final do arquivo. O comando clean é a filtragem de espaço em branco que juntei das notas em http://sed.sourceforge.net/sed1line.txt . Parece que deve ser colocado em um shell script, não consegui descobrir como injetar o comando sed, incluindo o saneamento de linhas extras estranhas no final do arquivo diretamente no arquivo git-config. (Você PODEse livrar dos espaços em branco à direita, no entanto, sem a necessidade de um script sed separado, defina-o filter.fix-eol-eofcomo algo como sed 's/[ \t]*$//' %fonde \testá uma guia real, pressionando tab.)

A exigência = true faz com que um erro seja gerado se algo der errado, para mantê-lo longe de problemas.

Por favor, perdoe-me se minha linguagem sobre o git for imprecisa. Acho que tenho uma compreensão bastante boa dos conceitos, mas ainda estou aprendendo a terminologia.


Abordagem interessante. +1
— VonC

Obrigado @VonC! Eu também quero aproveitar esta oportunidade para salientar que os atributos git podem ser configurados em uma base per-repisitory no.git pasta e não globalmente, o que pode fazer mais sentido.
— Zbeekman

9

Eu escrevi esse gancho de pré-confirmação, que remove apenas o espaço em branco à direita das linhas que você alterou / adicionou, pois as sugestões anteriores tendem a criar confirmações ilegíveis se os arquivos de destino tiverem muito espaço em branco à direita.

#!/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
Interessante. +1. Veja minha outra resposta para calcular a árvore vazia.
— VonC

1
Boa ideia, é exatamente isso que eu gostaria. No entanto, tenha cuidado ao usar isso! Para mim, no OSX e na versão 2.3.5 do git, ele afasta qualquer alteração adicional, mas não confirmada, que eu tenha realizado. Eu ainda estaria interessado em uma solução funcional para isso.
— Casper

9

Por favor, tente meus ganchos pré-confirmação , ele pode detectar automaticamente o espaço em branco à direita e removê-lo . Obrigado!

pode funcionar em baixo GitBash(windows), Mac OS X and Linux!


Instantâneo:

$ 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
Interessante. +1. Eu referenciei o seu gancho na minha própria resposta
— VonC 28/03

@VonC Obrigado pela sua afirmação! Para o '.md', eu só encontrei git commit -no-verify, alguma sugestão?
— oldman 28/03

Prefiro tornar o gancho capaz de detectar .mdarquivos e não remover os espaços em branco, em vez de pedir ao usuário final para adicionar uma --no-verifyopção no git commit.
— VonC 28/03

Falha ao confirmar um arquivo / diretório que começa com um +ou-
— Rody Oldenhuis

6

Aqui está uma versão compatível com 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

Diverta-se


Parece que a única diferença entre a sua e a minha é que você verifique se o sed realmente substituirá algo antes de reescrever o arquivo ... Não tenho certeza de que isso importe, já que o git não comete alterações que na verdade não alteram nada. Suponho que seja marginalmente mais seguro, mas também marginalmente mais lento, e prefiro a clareza de não repetir as regexes duas vezes em uma linha. De gustibus non disputandum est!
— AlexChaffee

não, a diferença é que a versão está usando a sintaxe do ubuntu primeiro e (se isso falhar) depois da osx.
— sdepold

1
Se eu editei a postagem de sdepold, ele também deve permitir espaços em branco nos nomes de arquivos agora.
— Imme

5

Estava pensando sobre isso hoje. Isso é tudo o que acabei fazendo em um projeto java:

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

3

Para usuários de texto sublime .

Defina o seguinte corretamente na sua configuração User-Setting .

"trim_trailing_white_space_on_save": true


1
É uma maneira de definir isso por tipo de arquivo? Eu tenho *.mdarquivos (markdown) que dependem de "" (espaços duplos à direita) para marcar um simples <br />, e essa configuração parece se aplicar a todos os arquivos, incluindo os que eu não quero remover os espaços à direita.
— VonC

@VonC Há hierarquia sobre como a configuração é aplicada mais detalhes aqui, stackoverflow.com/questions/16983328/... espero que ajude
— Haris Krajina

2

o loop for para arquivos usa a variável de shell $ IFS. no script fornecido, os nomes de arquivos com um caractere que também esteja na variável $ IFS serão vistos como dois arquivos diferentes no loop for. Este script o corrige: o modificador de modo multilinha, dado o sed-manual, não parece funcionar por padrão na minha caixa do ubuntu, então procurei uma implementação diferente e a encontrei com um rótulo iterativo, essencialmente ele só começará a substituição no última linha do arquivo, se eu entendi corretamente.

#!/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] padrão sed-subsition: como substituir uma nova linha (\ n) usando sed? .


2

Isso não remove os espaços em branco automaticamente antes de uma confirmação, mas é bastante fácil de efetuar. Coloquei o seguinte script perl em um arquivo chamado git-wsf (correção de espaço em branco do git) em um diretório em $ PATH para que eu possa:

git wsf | sh

e remove todo o espaço em branco apenas das linhas de arquivos que o git reporta como um 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";
}

0

Um pouco tarde, mas como isso pode ajudar alguém lá fora, aqui vai.

Abra o arquivo no VIM. Para substituir guias por espaços em branco, digite o seguinte na linha de comando do vim

:%s#\t#    #gc

Para se livrar de outros espaços em branco à direita

:%s#\s##gc

Isso praticamente fez por mim. É entediante se você tiver muitos arquivos para editar. Mas achei mais fácil do que pré-confirmar ganchos e trabalhar com vários editores.


Se for tedioso - e se você tiver um backup do que está prestes a editar -, geralmente uso o sed para alterar as guias para os espaços: sed -i 's|\t| |g' filenames(espaços na posição de substituição). Observe que você pode usar o find para obter seus nomes de arquivos. Se você ainda não pensou em como obter esse backup, normalmente apenas confirmo tudo e depois 'desfazo' o commit com uma redefinição suave de volta para onde estou; às vezes eu adiciono tudo à árvore, mas não faço commit, e às vezes eu uso o stash / apply (não pop!). Se me sinto ansioso, sincronizo toda a minha árvore em um local seguro antes de me intrometer ...
— sáb

0

Para excluir espaços em branco à direita no final da linha em um arquivo, use ed:

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

-1

Provavelmente, isso não resolverá diretamente o seu problema, mas você pode configurá-los via git-config no espaço real do projeto, que edita ./.git/config em oposição a ~ / .gitconfig. É bom manter as configurações consistentes entre todos os membros do projeto.

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

3
afaik, as configurações no .git não são compartilhadas com mais ninguém; Eles são específicos para o seu repo locais
— AlexChaffee
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.