«Git rm - кэшированный x» против «git reset head - x»?

163

GitRef.org - Базовый :

git rmудалит записи из области подготовки. Это немного отличается от git reset HEAD"unstages" файлов. Под «неэтапным» я подразумеваю, что он возвращает область подготовки к тому, что было до того, как мы начали что-то изменять. git rmс другой стороны, он просто удаляет файл со сцены, чтобы он не был включен в следующий моментальный снимок фиксации, тем самым эффективно удаляя его.

По умолчанию a полностью git rm fileудаляет файл из промежуточной области, а также с вашего диска> (рабочий каталог). Чтобы оставить файл в рабочем каталоге, вы можете использовать git rm --cached.

Но в чем именно разница между git rm --cached asdи git reset head -- asd?

Pacerier
источник

Ответы:

219

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

Когда вы делаете что-то подобное, git add fileвы добавляете это в индекс. И когда вы делаете это, вы также добавляете это в дерево.

Это, вероятно, поможет вам узнать еще три распространенных флага в git reset:

git reset [- <mode>] [ <commit>]

Эта форма сбрасывает текущий заголовок ветви <commit>и, возможно, обновляет индекс (сбрасывая его на дерево <commit>) и рабочее дерево в зависимости от того <mode>, что должно быть одним из следующих:
--soft

Не затрагивает ни индексный файл, ни рабочее дерево (но сбрасывает голову <commit>, как во всех режимах). Это оставляет все ваши измененные файлы «Изменениями, которые нужно зафиксировать», как это будет указано в git status.

--mixed

Сбрасывает индекс, но не рабочее дерево (т. Е. Измененные файлы сохраняются, но не помечаются для фиксации) и сообщает, что не было обновлено. Это действие по умолчанию.

--жесткий

Сбрасывает индекс и рабочее дерево. Любые изменения отслеживаемых файлов в рабочем дереве, так <commit>как отбрасываются.

Теперь, когда вы делаете что-то вроде: git reset HEADто, что вы на самом деле делаете, git reset HEAD --mixedэто «сбрасывает» индекс в состояние, в котором он находился до того, как вы начали добавлять файлы / добавлять модификации в индекс (через git add). В этом случае рабочая копия и Индекс (или подготовка) были синхронизированы, но вы сделали заголовок и индекс синхронизированными после сброса.

git rmс другой стороны, удаляет файл из рабочего каталога и индекса, а когда вы фиксируете файл, он также удаляется из дерева. git rm --cachedоднако удаляет файл только из индекса и сохраняет его в вашей рабочей копии. Это полная противоположность. git add file В этом случае вы сделали индекс отличным от HEAD и рабочего, в котором HEAD имеет ранее зафиксированную версию файла, рабочая копия имела последнее изменение, если таковое имеется, или содержимое из HEAD файл, и вы удалили файл из индекса. Коммит сейчас синхронизирует индекс и дерево, и файл будет удален.

manojlds
источник
Я заметил , что после того, как команда не показывают различия, но показывают различия, как будто он все еще в кэш. Однако показывает файл как . Кажется противоречивым. git rm --cachedgit diffgit diff --cachedgit statusUntracked
haridsv
7
Не бери в голову ... Я должен был использовать git reset --mixed. Я был немного смущен утверждением, которое git rm --cachedявляется противоположностью git add. В буквальном смысле это неверно и может привести к повреждению. В моем случае я использовал git addдля добавления измененного файла в промежуточную область и хотел, чтобы противоположное «добавлению» не было начальным добавлением файла. + Ответ Грега Хьюгилла помог мне получить более четкую картину.
haridsv
12
Я нахожу использование рабочей копии, дерева и рабочего дерева немного запутанным. Рабочее дерево - это рабочая копия или дерево?
Nealv
3
Как упомянул @haridsv, выражение git rm --cached«полная противоположность git add file» вводит в заблуждение. git reset fileближе к тому, чтобы быть противоположностью git add file.
Мэтт Браун
@Nealv запоздалый, но для других, кто находит этот поток: рабочая копия, дерево и рабочее дерево все ссылаются на одно и то же (в контексте git).
De Novo
83

Возможно, пример поможет:

git rm --cached asd
git commit -m "the file asd is gone from the repository"

против

git reset HEAD -- asd
git commit -m "the file asd remains in the repository"

Обратите внимание , что если вы ничего не изменилось еще , то второе обязательство не будет на самом деле ничего делать.

Грег Хьюгилл
источник
3
Можете ли вы сказать мне, что на самом деле означает этот двойной дефис - после HEAD?
Юва
30
@yuva: --используется для отделения параметров команды от имен файлов. Если бы были и ветка, и файл с именем asd, то это git reset HEAD asdбыло бы неоднозначно. --Говорит «все следующее это имя файла».
Грег Хьюгилл
Это git reset HEAD <file>точно так же, как git rm --cached <file>и тогда git add --intent-to-add <file>?
алкоголь это зло
1
@alcoholisevil нет, кроме как в особом случае. Посмотрите этот отличный, краткий ответ.
De Novo
45

git rm --cached fileбудет удалить файл со сцены. То есть при фиксации файл будет удален. git reset HEAD -- fileпросто сбросит файл в промежуточной области в состояние, в котором он находился в коммите HEAD, т.е. отменит все изменения, которые вы внесли в него со времени последнего коммита. Если это изменение происходит при добавлении файла заново, то они будут эквивалентны.

yuriks
источник
7
В сочетании с представлением (как упомянуто в других ответах), который git rm --cached fileявляется своего рода противоположностью git add, этот ответ имел для меня большой смысл и был довольно кратким. Почти такой же короткий, как этот комментарий;)
rbatt
2
@rbatt, просто чтобы разместить здесь комментарий и уточнить, git rm --cached fileэто не противоположностьgit add file . Поведение оказывается противоположным git add fileв конкретном случае, когда вы добавили новый, ранее не отслеживаемый файл. В любом другом случае противоположностью git add fileявляется git reset HEAD file. git reset HEAD fileтакже изменяет git add fileв первом случае (добавление неотслеживаемого файла) и в каждом случае, именно поэтому git предлагает сделать, если вы хотите отменить добавление git.
De Novo