Локально удалить и игнорировать папку без фиксации - PullRequest
0 голосов
/ 30 августа 2018

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

Я попытался добавить путь к папке в .git / info / exclude, но, похоже, он не предназначен для предотвращения фиксации локальных файлов.

1 Ответ

0 голосов
/ 31 августа 2018

Короткий ответ - нет. Есть более длинный ответ: да, но , в частности, да, но будьте осторожны с этим! В частности, вы можете установить в индексе бит skip-worktree . Git sparse checkout mode использует этот бит, и вы можете использовать его для того же эффекта:

git update-index --skip-worktree <list of files>

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

Long

Индекс индексирует (отсюда и имя index ) ваше рабочее дерево: он перечисляет все файлы, которые должны присутствовать, и имеет их содержимое, которое фактически будет в следующий сделанный вами коммит, если, конечно, вы не измените индекс перед выполнением следующего коммита. Я пойду к тому, что должно присутствовать действительно означает немного, но давайте сначала посмотрим на нормальный случай.

Если вы удалите все файлы (и их каталог / папку) из вашего рабочего дерева, Git заметит, что ваш индекс и ваше рабочее дерево не совпадают, и сообщит вам, что у вас есть эти различия, то есть, что все эти файлы удалены. Они не подготовлены для фиксации , поскольку файлы находятся в индексе, а копия каждого файла в индекса совпадает с копией каждого файла в текущий коммит. Но они отсутствуют в рабочем дереве: они удалены.

Если вы также удалите файлы из индекса (используя git rm --cached), ваш индекс и рабочее дерево теперь будут совпадать: индекс не будет отображать dir/file, а dir/file фактически не будет существовать , Так что эта часть вывода git status больше не будет жаловаться на dir/file. Но если вы сделаете это, теперь ваш текущий коммит, который Git вызывает HEAD или @, имеет , имеет dir/file, а ваш индекс не имеет dir/file, поэтому следующий следующий коммит, который вы сделаете , будет не иметь dir/file. Это означает, что удаление dir/file является подготовленным для фиксации , а git status сообщит , что .

Другими словами, если dir/file отсутствует в рабочем дереве, но находится в @ (текущий или HEAD коммит), у вас есть только два варианта:

  • dir/file - это в индексе. Затем он удаляется с точки зрения index-vs-work-tree. git status скажет так.

  • dir/file - это , а не в индексе. Затем он удаляется с точки зрения @ -vs-index. git status скажет так.

Если вы не собираетесь делать коммит, в котором отсутствует dir/file, первый, безусловно, лучший выбор, но он все еще шумный.

Что должно присутствовать означает

1 Обратите внимание, что если индекс говорит, что должен существовать какой-либо файл с путем P , и он существует, все хорошо. Данные файла в P в рабочем дереве совпадают или не совпадают с данными в P в индексе и данными файла в P в индексе совпадает или не совпадает с тем, что находится в коммите @ или HEAD.

С другой стороны, если индекс говорит, что файл с путем P не не существует в рабочем дереве, но на самом деле этот файл делает существует в рабочем дереве, тогда путь P представляет собой неотслеживаемый файл . Здесь .gitignore и другие исключающие файлы входят: вы можете сказать git status не жаловаться на P , перечислив его в .gitignore.

Третий случай, конечно, тот, на который вы смотрите: файл с путем P существует в индексе, но отсутствует в рабочем дереве.

Разреженные проверки и бит пропуска рабочего дерева

Git имеет встроенную прямую поддержку того, что Git называет разреженным извлечением . Для этого вы устанавливаете переменную конфигурации core.sparseCheckout в true и перечисляете пути (или пути) в .git/info/sparse-checkout. Подробности см., Например, Можно ли выполнить разреженную проверку без предварительной проверки всего хранилища? В разделе документации git read-tree о разреженных проверках также есть дополнительная информация об этом. .

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

Когда git status или другие операции Git сканируют фактическое рабочее дерево, чтобы увидеть, что там на самом деле 1156 *, если они сталкиваются с индексной записью с установленным битом skip-worktree, они представьте , что файл там с содержимым, указанным в индексе. Они старательно избегают проверять, есть ли файл там или нет. То, что утверждает индекс согласно биту skip-worktree, должно быть , предполагается как истинное.

Если вы используете разреженную проверку, Git будет поддерживать биты skip-worktree самостоятельно (по крайней мере до некоторой степени - я не экспериментировал с этой функцией, чтобы увидеть, где она может иметь неровные края). В противном случае вы должны поддерживать их самостоятельно, вручную устанавливая (git update-index --skip-worktree) и сбрасывая (git update-index --no-skip-worktree) бит для каждого файла.

...