Зробіть git автоматично видаляти пробіли пробілів перед вчиненням


220

Я використовую git зі своєю командою і хотів би видалити зміни білого простору з моїх розрізних журналів, журналів, об'єднань тощо. Я припускаю, що найпростішим способом зробити це було б, щоб git автоматично видаляв пробіли пробілів (та інші помилки пробілів ) з усіх комісій під час їх застосування.

Я спробував додати наступне у ~/.gitconfigфайл, але це не робить нічого, коли я виконую. Можливо, він розроблений для чогось іншого. Яке рішення?

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

Я використовую рубін, якщо хтось має якісь ідеї щодо рубіну. Автоматичне форматування коду перед введенням було б наступним кроком, але це важка проблема і насправді не викликає великої проблеми.


Якщо директива core.whitespace не виправляє ваші проблеми, ви також можете змінити гачок попереднього вчинення (.git / hooks / pre-commit), щоб знайти та виправити їх для вас. Детальний опис дивіться у цій публікації.
VolkA

2
Я розчарувався у подібних помилках пробілу та часткових рішеннях, і написав гнучку та досить повнофункціональну утиліту, яка може виправити або просто повідомити про помилки пробілів у системах контролю версій bedevil: Whitespace Total Fixer на Github (вибачте, якщо це занадто самореклама)
Дан Ленскі

Відповіді:


111

Ці налаштування ( core.whitespaceі apply.whitespace) не існують, щоб видалити пробіли, але вони:

  • core.whitespace: виявляти їх та створювати помилки
  • apply.whitespace: і зніміть їх, але лише під час виправлення, не "завжди автоматично"

Я вважаю, що git hook pre-commitце зробить кращу роботу для цього (включає вилучення пробілів із заднім числом)


Зауважте, що в будь-який момент часу ви можете не запускати pre-commitгачок:

  • тимчасово: git commit --no-verify .
  • постійно: cd .git/hooks/ ; chmod -x pre-commit

Попередження: pre-commitсценарій (як цей ) за замовчуванням має не функцію "видалити трейлінг", а функцію "попередження", наприклад:

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

Однак ви можете створити кращий pre-commitгачок , особливо якщо врахувати це:

Здійснення в Git із лише деякими змінами, доданими до області постановки, все ще призводить до "атомного" перегляду, який, можливо, ніколи не існував як робоча копія і може не працювати .


Наприклад, Олдман пропонує в іншу відповідь на pre-commitгачок , який детектирует і видалити пробіли.
Оскільки цей гачок отримує назву кожного файлу, я рекомендую бути обережним для певного типу файлів: ви не хочете видаляти пробіли пробілів у .mdфайлах (розмітка)!


1
Виявляється, git можна переконати, що він виправляє пробіли у вашій робочій копії за допомогою apply.whitespace, обманувши Git, щоб ваш робочий примірник розглядав зміни як патч. Дивіться мою відповідь нижче .
ntc2

> "Ви не хочете видаляти пробіли пробілів у файлах .md (розмітка)" - Чому це? Яка мета відстеження пробілів у файлах розмітки? Я помітив, що деякі .editorconfigфайли мають для цього певне правило.
friederbluemle

5
@friederbluemle залежно від типу розмітки,<br>
проміжок

Налаштування core.whitespaceна trailing-spaceз git configне призводить до помилок під час виконання в git2.5.0.
Карл Ріхтер

43

Ви можете обдурити Git, щоб виправити пробіл для вас, обманувши Git в трактуванні змін як виправлення. На відміну від рішень "попередньо здійснити гак", ці рішення додають команди Git для фіксації пробілів до Git.

Так, це хаки.


Міцні рішення

Наступні псевдоніми Git взяті з мого~/.gitconfig .

Під "надійним" я маю на увазі, що ці псевдоніми працюють без помилок, роблячи правильно, незалежно від того, чи дерево чи індекс забруднені. Однак вони не працюють, якщо інтерактив git rebase -iвже працює; Зверніться до моїх~/.gitconfig додаткових перевірок, якщо вам цікавий цей кутовий випадок, де git add -eфокус, описаний в кінці, повинен працювати.

Якщо ви хочете запустити їх безпосередньо в оболонці, не створюючи псевдонім Git, просто скопіюйте та вставте все між подвійними лапками (припустимо, що ваша оболонка схожа на Bash).

Зафіксуйте індекс, але не дерево

Наступний fixwsпсевдонім Git виправляє всі помилки пробілу в індексі, якщо такі є, але не торкається дерева:

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

Ідея полягає в тому, щоб запуститись git fixwsраніше, git commitякщо в індексі є помилки пробілу.

Зафіксуйте індекс і дерево

Наступний fixws-global-tree-and-indexпсевдонім Git виправляє всі помилки пробілів в індексі та дереві, якщо такі є:

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

Щоб також виправити пробіли в неперевершених файлах, виконайте це

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

Прості, але не надійні рішення

Ці версії простіше скопіювати та вставити, але вони не роблять правильно, якщо їх побічні умови не дотримані.

Виправте під деревце, вкорінене в поточному каталозі (але скидає індекс, якщо він не порожній)

Використання git add -eдля "редагування" патчів з редактором особистих даних ::

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

Виправити та зберегти індекс (але не вдалося, якщо дерево забруднене чи індекс порожній)

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

Виправити дерево та індекс (але скидає індекс, якщо він не порожній)

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

Пояснення export GIT_EDITOR=: && git -c apply.whitespace=fix add -ue .хитрості

Перш ніж я дізнався про git rebase --whitespace=fixхитрість з цієї відповіді, я git addвсюди використовував складніший трюк.

Якщо ми це зробили вручну:

  1. Встановіть apply.whitespaceв fix(ви повинні зробити тільки один раз):

    git config apply.whitespace fix
    

    Це говорить Git виправити пробіли в патчах .

  2. Переконайте Git ставитися до змін як виправлення :

    git add -up .
    

    Натисніть a+, enterщоб вибрати всі зміни для кожного файлу. Ви отримаєте попередження про виправлення Git помилок у пробілі.
    ( git -c color.ui=auto diffв цей момент виявляється, що ваші неіндексовані зміни - це саме помилки пробілу).

  3. Видаліть помилки пробілу з робочої копії:

    git checkout .
    
  4. Поверніть свої зміни (якщо ви не готові їх здійснити):

    git reset
    

У GIT_EDITOR=:засобі для використання в :якості редактора, і як команда :є тотожним.


1
Я щойно перевірив це в Windows: це працює чудово в командному рядку DOS: set VISUAL= && git add -ue . && git checkout .Зверніть увагу на ' .', що використовується з git add: тобто через git1.8.3
VonC

@VonC Чи не буде це налаштування VISUAL назавжди, що може, наприклад, спричинити подальше використання git commitнеправильного редактора? Я загортаю VISUAL=частину в підзаголовку в моїй версії unix, щоб уникнути цього, але я не знаю, чи є в DOS підзаголовки.
ntc2

1
Дякую за чудовий хак! FYI, якщо ви core.editorвстановили, то експорт VISUALне має ефекту, оскільки налаштування конфігурації має перевагу в пер man git-var. Щоб змінити це, вам потрібно експортувати GIT_EDITOR=:.
Нік Фельд

1
Крім того, я підробив свою версію, fixwsщоб швидко провалитися, якщо ви вже перебуваєте в інтерактивній базі даних, оскільки в іншому випадку вона загине за git rebase --whitespace=fixлінією і залишить вас у дивному стані. Я запозичив це питання і лише додав додатковий випадок перед тим, якщо: 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


29

Я знайшов гак, який попередньо здійснює фіксацію, який видаляє пробіли .

#!/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
Друге sedвиклик ( sed -r 's/:[0-9]+:.*//') може бути замінено на cut -f1 -d:. Це має працювати однаково на обох платформах Linux та BSD.
Ігор Кахарліченко

2
@IhorKaharlichenko: насправді використання cutне настільки безпечно, як друге sed: вирізання не вдасться у (вкрай малоймовірному) випадку з іменами файлів, які містять ":". Ви могли awk 'NF>2{NF-=2}1'б бути в безпеці
MestreLion

1
BTW, Якщо ви перебуваєте в Windows (msysgit) і користуєтесь core.autocrlf=true, можливо, ви захочете додати dos2unix -D "$FILE"всередині циклу for for, після sed. В іншому випадку вона змінить всі CRLF на LF, видавши лише sed.
jakub.g

49
Робитися git addвсередині гачка для фіксації здається мені досить злим. Що робити, якщо ви виконуєте часткову постановку / фіксацію файлу? Ви не хочете, щоб повний файл був зроблений за вашою спиною, чи не так?
Стефаан

19

У Mac OS (або, швидше за все, у будь-якому BSD) параметри команди sed мають бути дещо іншими. Спробуйте це:

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

Збережіть цей файл як .git/hooks/pre-commit - або шукайте той, який вже є, і вставте нижній фрагмент десь усередині нього. І пам’ятайте про chmod a+xце теж.

Або для глобального використання (через гачки Git commit - глобальні налаштування ) ви можете помістити його $GIT_PREFIX/git-core/templates/hooks(де GIT_PREFIX є / usr або / usr / local або / usr / share або / opt / local / share) та запустити git initвсередину існуючих репостів.

Згідно з git help init :

Запуск git init у наявному сховищі безпечний. Він не переписує речі, які вже є. Основною причиною відновлення git init є підбір нещодавно доданих шаблонів.


7
Хіба цей гачок не змінює робочий файл і замінює індекс зміненим робочим файлом? Якби ви створили свій індекс, "git add -p", цей гак фіксації це відірве.
Меттью Даттон

2
Так, ти, мабуть, маєш рацію. Комусь, можливо, доведеться переписати цей скрипт для використання git hash-object -wта git update-index(повторного) вставлення відредагованого файлу безпосередньо в індекс. Хтось дуже сміливий.
AlexChaffee

11

Я б краще залишити це завдання улюбленому редактору.

Просто встановіть команду для видалення пробілів під час збереження.


2
In vim ви можете зробити це за допомогою: autocmd BufWritePre .cpp, .c, *. H:% / \ s \ + $ // e
Роберт Массайолі

3
Вибачте, я підтримав вищезазначений коментар перед його тестуванням. Після знака відсотка відсутнє "s", і він перемістить курсор, якщо буде знайдено пробіл, і він видалить останній шаблон пошуку. Дивіться vim.wikia.com/wiki/Remove_unwanted_spaces для кращих альтернатив.
Сет Джонсон,

1
У emacs - це Mx delete-trailing-whitespace.
Мовіс Ледфорд

2
Ще краще, для emacs встановіть гачок, щоб видалити пробіли пробілу перед збереженням, додавши (add-hook 'before-save-hook 'delete-trailing-whitespace)у свій .emacsфайл. Трюки пробілів Emacs
Duncan Parkes

1
Я використовую (додати гачок "до збереження-гачок" пробіл-очищення), який також перетворює вкладки в пробіли.
Нілс Фагербург

10

Використання атрибутів git та налаштування фільтрів за допомогою git config

Гаразд, це нова проблема вирішення цієї проблеми ... Мій підхід полягає в тому, щоб не використовувати жодних гачків, а скоріше використовувати фільтри та атрибути git. Це дозволяє вам зробити, це налаштування на кожній машині, на якій ви розробляєте, набір фільтрів, які знімуть зайвий пробіл та зайві порожні рядки в кінці файлів, перш ніж робити їх. Потім встановіть файл .gitattributes, в якому вказано, до яких типів файлів слід застосувати фільтр. Фільтри мають дві фази, cleanяка застосовується при додаванні файлів до індексу, іsmudge яка застосовується при додаванні їх у робочий каталог.

Скажіть своєму git шукати глобальний файл атрибутів

По-перше, скажіть глобальному конфігуратору використовувати глобальний файл атрибутів:

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

Створіть глобальні фільтри

Тепер створіть фільтр:

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

Додайте сценарій сімейства сценаріїв

Нарешті, покладіть fixup-eol-eof скрипт кудись на свій шлях і зробіть його виконуваним. Сценарій використовує sed, щоб зробити деякі під час редагування льоту (видалити пробіли та пробіли в кінці рядків, а також сторонні порожні рядки в кінці файлу)

fixup-eol-eof має виглядати так:

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

моя суть цього

Скажіть git, до яких типів файлів слід застосувати ваш новостворений фільтр

Нарешті, створіть або відкрийте ~ / .gitattributes_global у своєму улюбленому редакторі та додайте рядки, такі як:

pattern attr1 [attr2 [attr3 […]]]

Отже, якщо ми хочемо вирішити проблему з пробілом, для всіх наших вихідних файлів c ми додамо рядок, який виглядає приблизно так:

*.c filter=fix-eol-eof

Обговорення фільтра

Фільтр має дві фази: чиста фаза, яка застосовується, коли речі додаються до індексу або зареєстрована, і фаза розмазування, коли git вводить речі у вашу робочу директорію. Тут наш розмазок просто запускає вміст за допомогою catкоманди, яка повинна залишити їх незмінними, за винятком, можливо, додавання символу для нового рядка, якщо в кінці файлу не було такого. Команда clean - це фільтрація пробілів, яку я зчепив із записів на http://sed.sourceforge.net/sed1line.txt . Здається, що його потрібно ввести в сценарій оболонки, я не міг зрозуміти, як ввести команду sed, включаючи перевірку сторонніх зайвих рядків у кінці файлу безпосередньо у файл git-config. (Ти ВИ МОЖЕТЕпозбудьтеся проміжних заготовок, однак, не потребуючи окремого сценарію sed, просто встановіть filter.fix-eol-eofна щось подібне, sed 's/[ \t]*$//' %fде \tфактична вкладка, натиснувши вкладку.)

Вимога = true викликає помилку, якщо щось піде не так, щоб уникнути неприємностей.

Вибачте, будь ласка, якщо моя мова щодо git є неточною. Я думаю, що я досить добре розумію ці поняття, але все ще вивчаю термінологію.


Цікавий підхід. +1
VonC

Дякую @VonC! Я також хочу скористатися цією можливістю, щоб зазначити, що атрибути git можуть бути налаштовані в режимі переписування в .gitпапці, а не в глобальному масштабі, що може мати більше сенсу.
zbeekman

9

Я написав цей гачок перед фіксацією, який видаляє лише пробіл із рядків, які ви змінили / додали, оскільки попередні пропозиції, як правило, створюють нечитабельні коміти, якщо цільові файли мають занадто багато пробілів.

#!/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
Цікаво. +1. Дивіться іншу мою відповідь щодо обчислення порожнього дерева.
VonC

1
Гарна ідея, це саме те, що я хотів би. Однак будьте обережні при використанні цього! Для мене на OSX та git версії 2.3.5 він знімає будь-які додавання, але невідомі зміни, які я здійснив. Я б все-таки зацікавився робочим рішенням для цього.
Каспер

9

Будь ласка, спробуйте мої гачки попереднього введення , вона може автоматично визначити пробіл білого кольору та видалити його . Дякую!

це може працювати під GitBash(windows), Mac OS X and Linux!


Знімок:

$ 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
Цікаво. +1. Я посилався на ваш гачок у власній відповіді
VonC

@VonC Дякуємо за ваше підтвердження! До ".md" я лише виявив git commit -no-verify, якісь пошкодження?
старець

Я б скоріше змусив гачок вміти виявляти .mdфайл і не видаляти пробіли, а не просити кінцевого користувача додати --no-verifyпараметр на git commit.
VonC

Помилка, якщо зробити файл / каталог, який починається з +або-
Роді Олденхуйс

6

Ось сумісна версія 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

Весело


Схоже, єдина різниця між вашою і моєю полягає в тому, що ви перевіряєте, що sed насправді замінить щось перед переписуванням файлу ... Я не впевнений, що це має значення, оскільки git не робить змін, які насправді нічого не змінюють. Я вважаю, що це гранично безпечніше, але також незначно повільніше, і я вважаю за краще чіткість не повторювати регулярні виразки на одному рядку. De gustibus non sportandum est!
AlexChaffee

немає різниці в тому, що версія використовує спочатку синтаксис ubuntu, а потім (якщо це виходить з ладу) після цього.
sdepold

1
я відредагував повідомлення sdepold, він повинен мати можливість також дозволити пробіли у ім’ях файлів зараз.
imme

5

Думав про це сьогодні. Це все, що я закінчив робити для проекту java:

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

3

Для користувачів Sublime Text .

Встановіть, як слід, у налаштуваннях користувача- налаштування

"trim_trailing_white_space_on_save": true


1
Це спосіб встановити це за типом файлу? У мене є *.mdфайли (розмітка), які покладаються на "" (трейлінг-пробіли) для позначення простого <br />, і ця настройка, схоже, стосується всіх файлів, включаючи ті, з яких я не хочу видаляти проміжні місця.
VonC

@VonC Існує ієрархія щодо того, як тут використовується більш детальна конфігурація, stackoverflow.com/questions/16983328/… сподіваюся, що це допоможе
Haris Krajina

2

цикл for-циклу для файлів використовує змінну оболонки $ IFS. у даному скрипті назви файлів із символом у них, який також є у змінній $ IFS, будуть розглядатися як два різних файли у циклі for. Цей скрипт це виправляє: модифікатор багаторядкового режиму, як даний посібник sed, не працює за замовчуванням на моєму ubuntu вікні, тому я шукав іншу імплементацію і знайшов це за допомогою ітераційної мітки, по суті, вона запустить лише заміну на останній рядок файлу, якщо я правильно його зрозумів.

#!/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] шаблон затримки sed: Як я можу замінити новий рядок (\ n) за допомогою sed? .


2

Це не видаляє пробіли автоматично перед фіксацією, але це досить просто. Я розміщую наступний скрипт perl у файл під назвою git-wsf (виправлення білого простору git) у dir у $ PATH, щоб я міг:

git wsf | ш

і він видаляє весь пробіл лише з рядків файлів, які git звіти як розл.

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

Трохи пізно, але оскільки це може допомогти комусь там, тут іде.

Відкрийте файл у VIM. Щоб замінити вкладки пробілами, введіть наступне у командному рядку vim

:%s#\t#    #gc

Щоб позбутися інших задніх пробілів

:%s#\s##gc

Це в значній мірі зробив це для мене. Нудно, якщо у вас є багато файлів для редагування. Але мені це було легше, ніж попередньо здійснити гачки та працювати з кількома редакторами.


Якщо це стає нудним - і якщо у вас є резервна копія того, що ви збираєтесь редагувати, - я часто просто використовую sed для зміни вкладок на пробіли: sed -i 's|\t| |g' filenames(пробіли в позиції заміни). Зауважте, що ви можете використовувати find, щоб отримати свої імена файлів. Якщо ви не думали, як отримати цю резервну копію, я зазвичай просто виконую все, а потім 'скасовую' команду з м'яким скиданням назад, де я є; іноді я додаю все до дерева, але не беруть зобов’язань, а іноді використовую приховування / застосування (не поп!). Якщо я відчуваю занепокоєння, я rsync все своє дерево до безпечного місця перед втручанням ...
мудрець

0

Щоб видалити проміжку пробілів у кінці рядка у файлі портативно, використовуйте ed:

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

-1

Це, ймовірно, безпосередньо не вирішить вашу проблему, але ви, можливо, захочете встановити їх через git-config у вашому фактичному просторі проекту, який редагує ./.git/config на відміну від ~ / .gitconfig. Приємно зберігати налаштування між усіма учасниками проекту.

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

3
afaik, налаштуваннями всередині .git не ділиться ні з ким іншим; вони характерні для вашого місцевого репо
AlexChaffee
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.