Git удалить конечные пробелы в новых файлах перед фиксацией

Я знаю, что удаление конечных пробелов может быть выполнено с помощью привязки pre-commit. Я заинтересован в том, чтобы делать это вручную. Я прочитал вопрос здесь:
Сделать git автоматически удалять конечные пробелы перед совершением - переполнение стека
Ответ ближайший к тому, что я хочу, "автоматическая версия" из ntc2:

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


Эта команда работает хорошо, за исключением того, что она только для изменений в файлах, которые уже находятся в репо, а не в новых файлах. У меня есть куча файлов, которые являются новыми, то есть они еще не находятся в репо. Я хочу удалить пробелы из этих файлов, поэтому я попытался добавить -A вместо -u, но это не помогло.

Ответ 1

Чтобы вручную очистить пробелы от последних трех коммитов, вы можете сделать это:

git rebase --whitespace=fix HEAD~3

Когда я работаю над ветвью темы, я отслеживаю ветку вверх по течению (обычно создавая ее так)

git checkout -b topic -t

Позволяет мне удалить последний аргумент из git rebase. Поэтому, как только я закончу и буду сливаться, я могу быстро очистить всю ветку темы:

git ws # aliased to rebase --whitespace = fix

Обратите внимание, что, в отличие от примера HEAD ~ 3, это фактически переформатирует ваши изменения в ветке upstream, если она изменится! (Но это также то, что я хочу, в моем рабочем процессе.)

Ответ 2

Мне нравится Luke answer, за исключением ограничений, которые вам нужно либо вручную указать базовый коммит, либо использовать рабочий процесс в стиле rebase, где ваша история линеаризуется. Я предлагаю модификацию, которая не требует дополнительного аргумента и не изменяет топологию вашего графика фиксации. В качестве команды оболочки:

git rebase --whitespace=fix --onto $(git merge-base HEAD @{u})

Или как псевдоним ~/.gitconfig:

ws = "!git rebase --whitespace=fix --onto $(git merge-base HEAD @{u})"

Я предпочитаю это, потому что иногда я хочу переустановить свои изменения, но если я думаю, что может возникнуть конфликт слияния, который я предпочитаю объединить, чтобы как первоначальное изменение, так и разрешение конфликта были записаны в истории. Таким образом, я могу позже угадать разрешение конфликта и при необходимости переделать его.

Учитывая, что я не всегда переустанавливаю, я предпочитаю не смешивать пробелы с перезагрузкой; следовательно, эта модификация ответа Луки.

Кроме того, я включаю по умолчанию пре-фиксацию, которая прерывает ошибки пробела:

cp .git/hooks/pre-commit.sample .git/hooks/pre-commit

Это дает следующий рабочий процесс, который мне нравится, потому что он достаточно ручен, чтобы я знал, что происходит, но автоматизирован, чтобы не мешать:

  • взломать взломать, ввести ошибку пробела.
  • попытка совершить
  • commit завершается с ошибкой пробела из-за крюка pre-commit
  • git commit --no-verify для фиксации в любом случае
  • git ws используйте псевдоним, чтобы исправить

Обратите внимание на использование --onto: здесь это не нужно, но мне легче рассуждать о том, как эта функция работает так. В версии Luke HEAD~3 находится <upstream> на странице руководства, тогда как в моей версии <upstream> сохраняется значение по умолчанию реального вверх по течению от ветки. Вы заканчиваете тем же результатом в любом случае.

Ответ 3

Простое исправление

Вы указали команду

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

работает, если вы сначала добавите файлы, которые хотите исправить, с помощью git add -N <files you want to fix>. add -N по существу говорит Git притворяться, что вы ранее делали пустые версии файлов.

Ошибка, которую вы получили

Я не понимаю, почему вы получаете ошибку fatal: Empty patch. Aborted. с add -Ae, но она выглядит как ошибка, так как простая git add -A . && git diff --cached показывает, что патч не должен быть пустым.

Улучшенный фиксатор пробелов

Недавно я обновил мой ответ, который вы связали с с лучшим псевдонимом Git для исправления пробелов. Здесь переписывается этот псевдоним с помощью Люк-футзальный трюк и менее избыточный поток управления:

fixws =!"\
  if (! git diff-index --quiet --cached HEAD); then \
    \
    git diff-files --quiet `git rev-parse --show-toplevel` ; \
    export NEED_TO_STASH=$? ; \
    \
    git commit -m FIXWS_SAVE_INDEX && \
    if [ 1 = $NEED_TO_STASH ] ; then git stash save FIXWS_SAVE_TREE; fi && \
    git rebase --whitespace=fix HEAD~ && \
    git reset --soft HEAD~ && \
    if [ 1 = $NEED_TO_STASH ] ; then git stash pop; fi ; \
  fi"

Это фиксирует пробелы в индексе, сохраняя индекс, и оставляя дерево нетронутым. С помощью этого псевдонима вы можете исправить неверующий файлов в репо с

git add --all :/ && git fixws && git reset

Но он также обрабатывает более распространенный случай исправления пробелов в поручите, над чем вы работаете. Это сложно, потому что оно работает даже тогда, когда индекс или дерево чисты.

Ответ 4

Если вы используете emacs, вы можете использовать "M ^ x delete-trailing-whitespace", чтобы удалить их перед сохранением файла. (его также можно настроить в ваших .emacs)

vi также позволяет это: http://vim.wikia.com/wiki/Remove_unwanted_spaces