Как игнорировать все изменения в конкретном файле при нажатии - PullRequest
0 голосов
/ 28 ноября 2018

Я клонировал проект на свой компьютер из репозитория и получил ошибки, потому что у нескольких файлов в именах файлов были звездочки, которые явно не могут существовать в системе Windows.Так что теперь мой git status показывает, что я удаляю эти файлы, поскольку они не были скопированы в мой проект.Мне не нужно будет вносить какие-либо изменения в эти файлы (все они являются изображениями), поэтому есть ли способ, которым я могу сказать git не вносить никаких изменений (в данном случае, в частности, удаления) для этих конкретных файлов?

Я попытался сделать git update-index --assume-unchanged на одном из них, но, похоже, он не сработал, потому что мой git status по-прежнему показывает файл в очереди на удаление (соответствующая картинка).

enter image description here

Ответы [ 3 ]

0 голосов
/ 29 ноября 2018

Как было сказано несколько дней назад о подобном вопросе, это может быть проблема с оболочкой, а не проблема с git.

Вы пробовали использовать git bash вместо оболочки Windows?

Вы пытались переименовать этот файл сразу после извлечения, используя escape-символ для звездочки?

0 голосов
/ 29 ноября 2018

TL; DR

Установите бит --skip-worktree для этих конкретных путей в индексе:

git ls-files -dz | xargs -0 git update-index --skip-worktree

(я предполагаю, что ваш Windows-bash имеет xargs -0; если нет,вам, возможно, придется немного поиграться с этим.)

Long (ish)

Ваша команда git update-index не выдала ошибок, поэтому она не влияет на эти файлы, что означает, что вы просматриваетенеправильное место.

Одна фундаментальная проблема заключается в том, что git push не выдвигает файлы .Вместо этого он нажимает совершает .Это правда, что коммиты содержат файлы, так что вы можете утверждать, что это бесполезное различие, но это ключевое различие, которое делает Git, и оно лежит в основе как проблемы, так и лечения.

... у нескольких файлов в именах файлов были звездочки, которые, очевидно, не могут существовать в системе Windows

Это выглядит правильно ( Какие символы запрещены вИмена каталогов Windows и Linux? ).В каком-то смысле это не влияет и не беспокоит Git , потому что Git имеет дело с коммитами, а не с файлами.Это влияет на вас .: -)

Git хранит коммиты в своей базе данных репозитория.Git также хранит каждую версию каждого файла в этой базе данных.Каждый сохраненный элемент, называемый внутренне объектом , имеет специальную сжатую форму только для Git.Файлы внутри коммита дополнительно замораживаются таким образом до тех пор, пока коммит существует (как правило, навсегда). 1

Заморожен (только для чтения), файлы только для Git бесполезны для васи остальные программы на вашем компьютере.Поэтому Git нужен способ извлечь их в удобную для чтения / записи форму.Он делает это в два этапа: сначала он эффективно оттаивает файлы, перечисляя их в своем index (который на самом деле является просто файлом с именем .git/index).Индекс отслеживает, что находится - или, по крайней мере, должно быть - в рабочем дереве.Затем он распаковывает их и дает им полезные names - реальные имена файлов в реальной файловой системе - и помещает их в ваше рабочее дерево.

Это последний шаг поворотаоттаявшая, но все еще Git-версия, индексная запись в имени файла, например foo*bar, которая завершается неудачно из-за запрещенного имени.Таким образом, оттаявшая запись - это в индексе, но не в рабочем дереве.

Git всегда делает new коммитов из того, что находится в индексе.Даже такие команды, как git commit -a, на самом деле просто обновляют индекс, затем строят коммит из индекса (хотя некоторые используют временный вспомогательный индекс только на время фиксации, а затем исправляют реальный индекс).Поэтому, пока вы не измените копию файла, который находится в index , все, что вы делаете с рабочим деревом - включая удаление файла или то, что Git думает, удаляет, так как файл так и не был создан - это простоизменение, то есть, с точки зрения git status, , не подготовленное для коммита .

Однако нам бы хотелось, чтобы git status не жаловался и git add удалить индексную копию файла.То есть, если был файл foo*bar, и он не попал в наше рабочее дерево, это нормально, если мы не хотим делать что-либо с этим файлом,Мы можем оставить файл в индексе, отсутствующий в рабочем дереве, и каждый новый git commit, который мы делаем, повторно замораживает копию индекса.Просто раздражает , что мы должны на цыпочках осознать тот факт, что в рабочем дереве нет foo*bar.

Оба флаговых указателя, --assume-unchanged и --skip-worktree, пустьмы работаем вокруг этого факта.--skip-worktree - это флаг, который означал для этой цели: ребята из Git добавили его для «разреженной проверки», и это особый случай разреженной проверки.Таким образом, мы можем просто найти список файлов, которые git status будет считать удаленными из рабочего дерева, т.е. файлы, которые перечислены в индексе, отсутствуют в реальном рабочем дереве и не имеют специальных установленных флагов.в индексе - и установите флаг --skip-worktree.

git ls-files -d printСписок таких имен файлов.При -z он печатает их, оканчивающиеся символом ASCII NUL (\0) вместо новой строки.Команда xargs -0 читает эти строки, оканчивающиеся NUL, и запускает на них git update-index --skip-worktree, поэтому теперь все эти записи индекса имеют установленный флаг.Новые коммиты будут содержать файлы (так как их перечисляет индекс), но рабочее дерево не будет (так как не может);Между тем git add не будет пытаться удалить их, а git status не будет жаловаться на них.


1 Это на самом деле является частью общего правила: внутренняя часть Gitобъекты хранятся в хранилище значений ключей, к которому обращаются ключи, которые являются идентификаторами хеш-функции, а идентификатор хеш-функции любого объекта представляет собой уникальную криптографическую контрольную сумму содержимого объекта.Содержимое не может быть изменено, потому что если бы оно было изменено, контрольная сумма изменилась бы, после чего старый ключ все равно извлекал бы старый объект, и только новый ключ / хэш-идентификатор мог бы извлечь новый объект.

0 голосов
/ 29 ноября 2018

Просто: git update-index --skip-worktree [<file>...]

С skip-worktree, даже если git знает, что файл был изменен (или его нужно изменить с помощью reset --hard или подобного), он притворитсяне был, используя вместо этого версию из индекса.Это сохраняется до тех пор, пока индекс не будет отброшен. объяснение.

См. Как Iconfigure git игнорирует некоторые файлы локально : git update-index --skip-worktree

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...