TL; DR
Рассмотрим только использование git add -u
.Другой ваш основной вариант - написать собственную программу, но в этом нет особого смысла.
Длинный
Ответ Обсидиана немного неверный, не так уж и важный, но в исходном вопросе отсутствует часть (по крайней мере, на данный момент - вопрос может быть отредактирован, чтобы исправить это), которая может ввести в заблуждение:
(* Изменение, но пустое сравнение может произойти с использованием инструментовкоторые удаляют определенные части файлов раньше)
... раньше ... что?: -)
Мне кажется, я знаю, что вы хотели сказать здесь: у вас может быть чистый фильтр , который редактирует файлы, пока Git копирует содержимое файлов из рабочего дерева вindex / staging-area.
Помните, что в Git действуют три активных копии файла во время работы (или более, если вы находитесь в середине конфликтующего слияния, хотя тогда это зависит от того, как считать).Для каждого файла:
Существует версия HEAD
, предназначенная только для чтения.Вы можете git show HEAD:path
просмотреть его.На самом деле он хранится в специальном сжатом формате Git-only;git show
должен расширить его.
Существует версия индекса / промежуточной области.Первоначально это просто копия HEAD
версии файла.Как и версия HEAD
, она имеет специальный сжатый формат только для Git;но, в отличие от версии HEAD
, вы можете перезаписать этот файл.
Наконец, есть версия, которая сама по себе Git не заботится, но вы, вероятно, делаете: это версия в вашем рабочем дереве.Это в своем обычном формате, с которым может работать ваш компьютер, поэтому он предназначен для чтения / записи, и вы можете делать с ним все, что захотите.Git не будет волноваться;Git в основном касается версии индекса.
Поскольку версии индекса и рабочего дерева доступны для записи, вы можете изменить одну или обе версии.Обычно вы изменяете версию рабочего дерева, а затем говорите Git скопировать эту версию рабочего дерева обратно в индекс .Вот что делает git add
: копирование из рабочего дерева в индекс.Если у вас определен clean filter , и / или если вы настроили изменения конца строки, git add
копирует файл в индекс при применении фильтров .
Команды (множественное число), которые копируют файл из индекса в рабочее дерево, могут применять нечеткие фильтры и / или вносить изменения в конце строки.Обычный экземпляр, с которым мы работаем каждый день, - git checkout
, который копирует из индекса в рабочее дерево или копирует из коммита в и индекс и рабочийдерево, в зависимости от того, как вы вызываете git checkout
.
Поскольку существуют нечеткие и чистые фильтры, git diff
должен выполнить особую магию при сравнении индексной версии файла с версией рабочего дерева той же самойфайл.Git выбирает запуск чистого фильтра для копии рабочего дерева.См. мой ответ на связанный вопрос для деталей.Здесь также происходит некоторая оптимизация: Git пытается узнать, соответствует ли очищенный файл рабочего дерева индексной версии, без необходимости запуска чистого фильтра над файлом.Если вы измените свои фильтры - это включает в себя изменение настроек конца строки - Git может запутаться в чистоте каждого файла.Самое простое решение этой проблемы - использовать этот двухэтапный процесс:
- Remove
.git/index
: при этом удаляются все подготовленные файлы. - Run
git reset
(без дополнительных опций): это воссоздает индекс из коммита HEAD
.
Конечно, это также уничтожает любые тщательно подготовленные файлы, которые у вас были.Альтернативой является обновление метки времени модификации для каждого файла в рабочем дереве (например, find . -name .git -prune -o -print0 | xargs -0 touch
, но у этого также есть раздражающие побочные эффекты. Git требуется команда (или флаг git reset
) для аннулирования и повторного вычисления всехкэшировать данные, не стирая промежуточные файлы. У него их нет, поэтому мы все застряли.
Это возвращает нас к первоначальному вопросу:
Существует ли команда git для добавления всех измененных файлов, для которых выходные данные git diff <file>
не пусты?
Давроде: это git add
, в частности git add -u
, что задокументировано таким образом :
Я говорю «вроде», потому что это также удаляет файлов, которые отсутствуют в рабочем дереве, но присутствуют в индексе.Также, возможно, по крайней мере, re -адд-файлов, которые не показывают какую-либо разницу между копией индекса и копией рабочего дерева.
Когда git add
закончив добавление очищенного файла, Git обновляет информацию о кеше в индексе, чтобы теперь он знал, что файл чистый.Если это добавляет к индексу копию файла, которая соответствует копии, которая уже была в индексе, ну и что?Файл в индексе не изменился, за исключением того, что теперь кэшированная информация о метках времени в индексе верна.Вы тратите на это немного вычислительного времени, но это, вероятно, лучше, чем тратить свое личное время.