значение команды git rm -cached из документации git -scm.com - PullRequest
0 голосов
/ 16 января 2020

Сейчас я играю с Git, чтобы привыкнуть к этому. Когда я читал определение git rm --cached, я натолкнулся на следующее определение:

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

В приведенном выше определении, что именно представляют собой пути? Любая помощь будет оценена.

Ответы [ 2 ]

1 голос
/ 16 января 2020

A path - это просто имя файла. Например:

  • README.md - это имя файла, а также путь. Путь не содержит папкообразных частей.
  • src/main.py - это имя файла, а также путь. Путь содержит часть, похожую на папку, src, и часть, похожую на файл, main.py, и ваш компьютер, вероятно, требует, чтобы Git фактически создал папку / каталог с именем src, прежде чем Git сможет создать файл с именем main.py. Для Git это в основном просто файл с именем src/main.py, но Git будет учитывать причуду вашего компьютера, требующую такого странного разделения "файлов" и "папок", или как вы хотите их называть.

Обратите внимание, что Git не хранит папки. Файлы - это просто файлы в области index / staging, даже если в их именах есть части folder-i sh. Git builds new фиксирует коммит из того, что находится в индексе во время выполнения git commit, 1 , поэтому коммиты не могут хранить пустые папки, потому что индекс не может хранить имя, заканчивающееся на a sla sh. 2

Сам индекс, который также называется промежуточной областью , или (редко в наши дни) кеш , странная, но важная вещь Git застревает между текущим коммитом и вашим рабочим деревом . Ваше рабочее дерево - это то место, где у вас есть файлы в их обычной повседневной форме, с которыми вы можете работать, но GIt не использует их для новых коммитов; Git использует индекс. Таким образом, индекс можно довольно точно описать как 3 , как ваш предложенный следующий коммит . Запуск git add копирует файл из вашего рабочего дерева в индекс. 4 Это делает файл готовым к фиксации, если, конечно, вы его не измените: тогда вам придется снова скопировать его в индекс.

Файл, который существует в вашем рабочем дереве, принадлежит вам, как и вы. Git не будет перезаписывать его, кроме:

  • , когда вы извлекаете коммит, в котором есть файл с этим именем (после создания любых папок, необходимых для достижения этой точки, как отмечено выше), или
  • , когда вы делаете git merge, который требует от Git наилучших усилий при объединении в файл, или
  • , когда вы специально просите Git перезаписать его.

Если в index указан один и тот же путь, т. Е. Все части папки-y плюс окончательное имя файла, этот файл рабочего дерева будет отслежен . Если нет, файл рабочего дерева не отслеживается .

Поскольку Git делает следующий коммит из того, что находится в индексе, каждый отслеживается * Файл 1064 * включается в следующий коммит (в той форме, в которой он находится в индексе, поэтому вы должны оставить его git add). Если файл не в индексе, следующий коммит не будет иметь этот файл.


1 Если вы используйте git commit -a или некоторые другие формы git commit, они эффективно запускают git add для вас непосредственно перед фактическим принятием. Но это всего лишь сокращенная версия git add <those files>; git commit: Git по-прежнему создает коммит из области index / staging-area.

2 Это не совсем так. Git может поместить такой путь в индекс. Но части Git продолжают настаивать на том, что эта вещь Git вызывает gitlink , что является частью того, как Git отслеживает то, что Git называет подмодулями . Поэтому они не работают должным образом для хранения пустых папок / каталогов: эти вещи превращаются в сломанные подмодули, то есть в gitlinks без необходимой информации, чтобы заставить остальную часть этого работать.

3 У index есть несколько дополнительных ролей, особенно во время конфликтующих слияний, которые делают это не совсем правильным. Но это разумная ментальная модель: вы можете думать об индексе как о копиях всех файлов, которые go войдут в следующий коммит. Они начинают быть копиями файлов с текущего коммита. См. Также сноску 4.

4 Технически, индекс содержит ссылку на внутренний Git объект BLOB , а не на копию файла. Но это техническое различие действительно проявляется только в том случае, если вы начинаете искать в индексе, например, с git ls-files --stage, или начинаете использовать git update-index для помещения в него идентификаторов объекта ha sh. Если вы просто думаете об индексе как о Git -определенной копии каждого файла, который будет go в следующем коммите, эта ментальная модель работает довольно хорошо.


Когда rm --cached получает tricky

Если мы находимся в обычном повседневном хранилище, мы можем добавить совершенно новый файл:

$ git checkout -b feature master
<make all-new file>
$ git add newfile.ext
$ git commit

У нового коммита есть новый файл, которого нет в старом коммите , Новая ветвь feature содержит файл в своем коммите-коммите, а master не имеет файла.

Неудивительно, если мы сейчас:

$ git checkout master

файл newfile.ext исчезает из рабочего дерева.

В общем, предположим, что вы переходите от коммита, который имеет , к файлу, который не . То есть вы запускаете git checkout для коммита (в конце некоторой ветви), в котором нет файла newfile.ext. Но newfile.ext есть сейчас и в вашем рабочем дереве, и в индексе. Так что Git должен вытащить копию из индекса. Он также удаляет копию из вашего рабочего дерева. Это то, что мы только что сделали, переключившись с develop (у которого есть новый файл) на master (у которого нет файла).

Теперь давайте go вернемся к develop:

$ git checkout develop

В коммите на кончике develop есть файл newfile.ext. В данный момент у вас его нет в индексе или в рабочем дереве, поэтому для Git безопасно скопировать newfile.ext из коммита подсказки develop в индекс, а затем скопировать его в ваше рабочее дерево. И теперь у вас действительно есть файл, и жизнь прекрасна.

Но: о-о, мы не должны были совершать newfile.ext в конце концов. Это файл конфигурации, или база данных живых пользователей, или что-то еще. Мы не хотим этого в feature. Поэтому мы удалили его:

$ git rm newfile.ext
$ git commit

Но, о-о, мы потеряли нашу конфигурацию (или базу данных, или что бы то ни было)! Так что вместо git rm давайте не будем выполнять две вышеуказанные команды. Вместо этого давайте сделаем:

$ git rm --cached newfile.ext
$ git commit

На этот раз Git удаляет newfile.ext из index , но не из нашего рабочего дерева . Файл все еще находится в нашем рабочем дереве. Оно ушло из индекса, поэтому его нет в новом коммите на feature.

Но теперь, если мы возьмем старый коммит на feature например, по его sh ID, что происходит? Ну, этот коммит содержит newfile.ext. Git хочет поместить этот файл в индекс и скопировать его в рабочее дерево.

Обычно мы получаем жалобу, что этот git checkout перезапишет newfile.ext. Иногда - это немного сложно, именно тогда, когда Git перезапишет newfile.ext в любом случае! И если мы заставим оформить заказ, Git перезапишет newfile.ext, как мы и просили. И теперь этот файл находится как в индексе, как видно из коммита, в котором мы его сохранили, так и в обычной (не Git -идентифицированной) форме в нашем рабочем дереве.

Так как он находится в обоих индексах и рабочее дерево, если мы теперь git checkout feature или git checkout master - оба из которых идентифицируют коммиты, которые не имеют файл - Git теперь удалит файл, из индекса и рабочего дерева. Наша драгоценная конфигурация или база данных или что бы то ни было, снова исчезли!

Итак, знайте, что делает git rm --cached, но помните, что он также устанавливает эти ловушки: коммиты, в которых файл делает существуют и могут перезаписать что-нибудь ценное, когда вы их проверите. Вы не можете изменить эти существующие коммиты: у них будет этот файл навсегда. Лучшее, что вы можете сделать, это избежать их или вообще прекратить их использование, если это проблема.

0 голосов
/ 16 января 2020

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

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

Это может быть полезно, если вы удаляете поврежденные файлы. файлы с намерением их исправить. В хранилище они будут удалены, но у вас останутся файлы, в которые вы сможете внести необходимые изменения.

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