Добавить только изменения без пробелов
У меня есть текстовый редактор, который автоматически обрезает пробельные пробелы при сохранении файла, и я вношу свой вклад в проект с открытым исходным кодом, который имеет серьезные проблемы с завершающим пробелом.
Каждый раз, когда я пытаюсь отправить патч, я должен сначала игнорировать все изменения только в виде пробелов, чтобы выбрать только соответствующую информацию. Не только это, но когда я запускаю 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