Добавить только изменения без пробелов - PullRequest
314 голосов
/ 18 августа 2010

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

Каждый раз, когда я пытаюсь отправить патч, ясначала необходимо вручную игнорировать все изменения только пробелов, чтобы выбрать только соответствующую информацию.Мало того, но когда я запускаю git rebase, я обычно сталкиваюсь с несколькими проблемами из-за них.

Поэтому я хотел бы иметь возможность добавлять в индекс только непробельные изменения, аналогично тому, чтоgit add -p делает, но без необходимости выбирать все изменения самостоятельно.

Кто-нибудь знает, как это сделать?

РЕДАКТИРОВАТЬ: я не могу изменить способ проектаработает, и они решили, обсудив это в списке рассылки, игнорировать это.

Ответы [ 8 ]

356 голосов
/ 22 августа 2011

@ Решение Frew было не совсем тем, что мне было нужно, так что это псевдоним, который я сделал для той же задачи:

alias.addnw=!sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero -'

Или вы можете просто запустить:

git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero -

Обновление

Добавлены опции -U0 и --unidiff-zero соответственно к вопросам обхода контекста, в соответствии с этим комментарием .

В основном применяется патч, который будетприменяется с add без изменений пробелов.Вы заметите, что после git addnw your/file все еще будут неустановленные изменения, это оставленные пробелы.

--no-color не требуется, но так как у меня установлены цвета всегда, я должен использоватьЭто.Во всяком случае, лучше, чем потом сожалеть.

36 голосов
/ 10 июня 2011

Это работает для меня:

Если вы хотите хранить тайник, это работает

git stash && git stash apply && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch

Мне не нравятся тайники, но у меня есть ошибка в git + cygwin, где я теряю изменения, поэтому, чтобы убедиться, что все пошло в reflog, я настроил следующее :

git add . && git commit -am 'tmp' && git reset HEAD^ && git diff -w > foo.patch && git checkout . && git apply foo.patch && rm foo.patch

По сути, мы создаем diff, который не включает изменения пространства, отменяем все наши изменения и затем применяем diff.

29 голосов
/ 01 мая 2015

Создайте файл исправления, содержащий только реальные изменения (исключая строки только с изменениями пробелов), затем очистите рабочее пространство и примените этот файл исправления:

git diff> backup
git diff -w> изменения
git reset --hard
patch <изменения </p>

Просмотрите оставшиеся различия, затем add и commit как обычно.

Эквивалентдля Mercurial это сделать:

hg diff> резервное копирование
hg diff -w> изменения
hg revert --all
hg import --no-commit changes

9 голосов
/ 14 сентября 2016

Добавьте следующее к вашему .gitconfig:

anw = !git diff -U0 -w --no-color -- \"$@\" | git apply --cached --ignore-whitespace --unidiff-zero "#"

Спасибо @ Колину Герберту за ответ за вдохновение.

Синтаксическое объяснение

Последний # должен быть заключен в кавычки, чтобы он не рассматривался как комментарий внутри .gitconfig, а вместо этого пропускается и обрабатывается как комментарий внутри оболочки - он вставляется между концом git apply и предоставленные пользователем аргументы, которые git автоматически помещает в конец командной строки. Эти аргументы здесь не нужны - мы не хотим, чтобы git apply потреблял их, следовательно, предыдущий символ комментария. Вы можете запустить эту команду как GIT_TRACE=1 git anw, чтобы увидеть это в действии.

-- сигнализирует об окончании аргументов и позволяет в случае, если у вас есть файл с именем -w или что-то похожее на переключение на git diff.

Избегающие двойные кавычки вокруг $@ требуются для сохранения любых предоставленных пользователем аргументов в кавычках. Если символ " не экранирован, он будет использован синтаксическим анализатором .gitconfig и не достигнет оболочки.

Примечание: .gitconfig синтаксический анализ псевдонимов не распознает одинарные кавычки как нечто особенное - его единственными специальными символами являются ", \, \n и ; (за пределами " - строка в кавычках). Вот почему " всегда должен быть экранирован, даже если он выглядит так, как будто он внутри строки в одинарных кавычках (о чем git совершенно не имеет значения).

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

sh = !bash -c '"$@"' -

Хотя правильным является:

sh = !bash -c '\"$@\"' -
9 голосов
/ 12 мая 2016

Ответ с наибольшим количеством голосов работает не во всех случаях из-за пробелов в контексте исправления в соответствии с пользователями в комментариях.

Я изменил команду следующим образом:

$ git diff -U0 -w --no-color | git apply --cached --ignore-whitespace --unidiff-zero

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

Соответствующий псевдоним, опять же пересмотр того, что уже было предоставлено другими пользователями:

addw = !sh -c 'git diff -U0 -w --no-color "$@" | git apply --cached --ignore-whitespace --unidiff-zero' -
6 голосов
/ 11 июня 2011

Как насчет следующего:

git add `git diff -w --ignore-submodules |grep "^[+][+][+]" |cut -c7-`

Команда внутри обратных кавычек получает имена файлов, которые не имеют пробелов.

0 голосов
/ 19 августа 2010

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

  #!/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"
  done
  exit
0 голосов
/ 18 августа 2010

Сначала вы должны рассмотреть, является ли конечный пробел намеренным. Многие проекты, в том числе ядро ​​Linux, Mozilla, Drupal и Kerberos (и многие другие на странице Википедии о стиле), запрещают использовать пробелы в конце. Из документации ядра Linux:

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

В вашем случае проблема в другом: предыдущие коммиты (и, возможно, текущие) не следовали этому руководству.

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

Вместо того, чтобы пытаться перенастроить git для игнорирования проблемы или отключить другие желательные функции в вашем редакторе, я бы начал с публикации в списке рассылки проекта, объясняющего проблему. Многие редакторы (и сам git) могут быть настроены для работы с конечными пробелами.

...