Git инструмент для удаления строк из этапа, если они состоят только из изменений в пробеле
Точка в удалении конечных пробелов заключается в том, что если каждый делает это всегда, то вы получаете минимальный diff, т.е. он состоит только из изменений кода, а не для изменения пробелов.
Однако, работая с другими людьми, которые этого не практикуют, удаление всех завершающих пробелов с помощью вашего редактора или привязка до фиксации приводит к еще большему различию. Вы делаете противоположное своему намерению.
Итак, я спрашиваю здесь, есть ли инструмент, который я могу запустить вручную, прежде чем я завершу, что строки с нестационарными настройками будут только изменениями в пробеле.
Также бонус должен был бы изменить поэтапную линию, чтобы удалить удаленные пробелы для строк с изменениями кода.
Кроме того, бонус должен был бы не делать этого для файлов Markdown (поскольку в трейлинг-пространстве есть значение в Markdown).
Я прошу здесь, поскольку я полностью намерен написать этот инструмент, если он еще не существует.
Ответы
Ответ 1
Ниже вы получите следующее:
$ clean=`git diff --cached -b`; \
git apply --cached <(git diff --cached -R); \
echo "$clean" | git apply --cached -; \
clean=
Для выпусков git до 1.7.0 он терпит неудачу, если один или несколько файлов имеют все пробелы. Например
$ git diff --cached -b
diff --git a/file1 b/file1
index b2bd1a5..3b18e51 100644
diff --git a/file2 b/file2
new file mode 100644
index 0000000..092bfb9
--- /dev/null
+++ b/file2
[...]
Пустая дельта (выше file1
, которая действительно должна быть подавлена) делает git-apply
несчастным:
fatal: patch with only garbage at line 3
ОБНОВЛЕНИЕ: Версия 1.7.0 git устраняет эту проблему.
Скажем, наш репозиторий находится в следующем состоянии:
$ git diff --cached
diff --git a/foo b/foo
index 3b18e51..a75018e 100644
--- a/foo
+++ b/foo
@@ -1 +1,2 @@
-hello world
+hello world
+howdy also
Затем мы могли бы выполнить приведенные выше команды, чтобы развернуть индекс и дерево работы:
$ git diff --cached
diff --git a/foo b/foo
index 3b18e51..1715a9b 100644
--- a/foo
+++ b/foo
@@ -1 +1,2 @@
hello world
+howdy also
$ git diff
diff --git a/foo b/foo
index 1715a9b..a75018e 100644
--- a/foo
+++ b/foo
@@ -1,2 +1,2 @@
-hello world
+hello world
howdy also
Если все изменения имеют только пробелы, вы увидите
error: No changes
Я подозреваю, что исправление индекса и отказ от нежелательных изменений в дереве работы могут удивить или даже раздражать большинство пользователей, но это поведение, о котором задал вопрос.
Ответ 2
Мое решение в git 1.7.2.5 было следующим (начиная без), если все изменения были поставлены):
git diff -w > temp.patch
git stash
git apply --ignore-space-change --ignore-whitespace temp.patch
# tidy up:
rm temp.patch
git stash drop
Это приведет к возврату вашего репо в исходное состояние с удалением любых пробелов.
Затем вы можете выполнить свои изменения, как обычно.
Ответ 3
Я использовал script на основе @GregBacon answer в течение многих лет, но в какой-то момент git изменил вывод git diff -b
так, чтобы переменные пробелов не отображаются, поскольку изменения были включены в строки контекста патча в состоянии after, а не в состоянии before.
Я обнаружил, что если бы я изменил чистый diff и соответствующий применил, script снова работал.
Итак, мой полный script выглядел так:
#!/bin/bash
clean=`git diff --cached -b`
git apply --cached <(git diff --cached -R)
echo "$clean" | git apply --cached -
clean=
Теперь выглядит:
#!/bin/bash
clean=`git diff --cached -b -R`
git apply --cached <(git diff --cached -R)
echo "$clean" | git apply --cached -R -
clean=
У меня также есть script, чтобы оставить только пробельные изменения в фиксации. Это полезно, если вы исправляете что-то, что вы делаете с некоторыми исправлениями в другом месте в файле, и хотите сначала зафиксировать исправления пробелов в отдельной фиксации. Это просто:
git apply --cached -R <(git diff --cached -w)