Добавить только изменения без пробелов

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

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

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

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

EDIT: я не может изменить способ работы проекта, и они решили, обсудив его в списке рассылки, игнорировать это.

Ответ 1

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

alias.addnw=!sh -c 'git diff -U0 -w --no-color "[email protected]" | git apply --cached --ignore-whitespace --unidiff-zero -'

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

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

Update

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

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

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

Ответ 2

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

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

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

Мне не нравятся stashes, но я столкнулся с ошибкой в ​​ 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.

Ответ 3

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

git diff > резервное копирование
git diff -w > изменения
git reset --hard
patch < изменения

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

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

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

Ответ 4

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

anw = !git diff -U0 -w --no-color -- \"[email protected]\" | git apply --cached --ignore-whitespace --unidiff-zero "#"

Благодаря @Colin Herbert ответ за вдохновение.

Синтаксис Объяснение

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

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

Для сохранения любых котируемых аргументов, предоставленных пользователем, требуется избегать двойных кавычек вокруг [email protected]. Если символ " не экранирован, он будет потребляться парсером .gitconfig и не дойдет до оболочки.

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

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

sh = !bash -c '"[email protected]"' -

В то время как правильный:

sh = !bash -c '\"[email protected]\"' -

Ответ 5

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

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

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

Ответ 6

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

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

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

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

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

addw = !sh -c 'git diff -U0 -w --no-color "[email protected]" | git apply --cached --ignore-whitespace --unidiff-zero' -

Ответ 7

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

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

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

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

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

Ответ 8

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

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