Инструмент Git для удаления линий из промежуточной, если они состоят только из изменений в пробелах - PullRequest
10 голосов
/ 17 ноября 2009

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

Однако при работе с другими людьми, которые не практикуют это, удаление всех конечных пробелов с помощью вашего редактора или ловушка перед фиксацией приводит к еще хуже diff. Вы делаете противоположность своему намерению.

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

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

Также бонусом было бы не делать этого с файлами Markdown (поскольку конечный пробел имеет значение в Markdown).

Я спрашиваю здесь, поскольку я полностью намереваюсь написать этот инструмент, если он еще не существует.

Ответы [ 3 ]

8 голосов
/ 18 ноября 2009

Следующие инструкции помогут вам в этом:

$ 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

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

4 голосов
/ 02 января 2014

Мое решение на 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

При этом ваш репо возвращается в исходное состояние с удалением только пробелов.

Затем вы можете внести свои изменения как обычно.

2 голосов
/ 26 апреля 2013

Я использовал сценарий, основанный на @ ответе Грегбэкона в течение многих лет, но в какой-то момент git изменил вывод git diff -b, так что изменения пробелов не отображались, поскольку изменения были включены в контекстных строках патча в состоянии после, а не в состоянии перед.

Я обнаружил, что если бы я изменил чистую разницу и применил соответствующий метод, скрипт снова заработал бы.

Итак, мой полный сценарий выглядел так:

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

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

git apply --cached -R <(git diff --cached -w)
...