Рассмотрим, что делает git reset
(в трех режимах: «мягкий» и «смешанный» и «жесткий»), а не другие дополнительные функции, которые вообще не являются одним из этих трех режимов). Вы запускаете:
git reset --<mode> <commit-specifier>
, и он выполняет следующие три вещи, или, возможно, 2, или 1:
(--soft
, --mixed
, --hard
) Изменяет имя текущей ветви , сохраненное в HEAD
, чтобы указать на данный коммит. При --soft
он теперь останавливается.
(--mixed
и --hard
) Он заменяет существующее содержимое индекса содержимым выбранного коммита . на шаге 1. При --mixed
(или по умолчанию) он теперь останавливается.
(только --hard
). Он заменяет содержимое рабочего дерева на файлы, обновленные на шаге. 2.
Теперь вы можете , если вы выберете, выберите текущий коммит в качестве цели на шаге 1, запустив git reset HEAD
например. Если вы сделаете это, обновленный текущий коммит на шаге 1 будет текущим коммитом. То есть шаг 1 не вносит никаких изменений.
Если вы запустите git reset --soft HEAD
, шаг 1 не изменится, а git reset
затем выйдет. Так что это абсолютно ничего не делает.
Если вы запускаете git reset
без --soft
, однако - без аргументов вообще, по умолчанию --mixed
или с --hard
- переход к шагу 2 : замените содержимое индекса файлами, которые все время замораживаются в текущем коммите. По сути, это отменяет любые git add
, которые вы делали ранее.
Если ваша цель состоит в том, чтобы повторить все git add
снова после этого, это бесполезно. Но если ваша цель состоит в том, чтобы не повторить все эти git add
с, это может быть. Рассмотрим, например, этот пример - не очень полезный сам по себе, но предназначенный для иллюстрации:
git checkout somebranch
<edit for a while, test, `git add .`>
# think: wait, I don't want to commit everything
git reset # index now matches HEAD
<edit README file to announce that the NEXT commit changes a lot of things>
git add README
git commit # make a commit in which everything is the same except README
git add .
git commit # make final commit in which everything is changed
Чтобы разобраться во всем этом, помните, что всегда есть три копии каждого файла:
Существует копия только для чтения, замороженная на все время (README.md
, main.py
, et c., Какие файлы у вас есть) в текущем коммите . Вы можете изменить, какой коммит является текущим коммитом в любое время, используя git checkout
или git reset
, но сам коммит навсегда заморожен: ни один из его файлов никогда не изменится, ни будет его сообщение о коммите, авторе и т. д.
В индексе Git имеется замороженная копия формата . 1 Вы можете изменить это все, что захотите: вы можете перезаписать копию файла копией другого файла или другой версии того же файла. Вы можете даже полностью удалить файл из индекса, используя git rm
. Индексная копия в замороженном формате, готовая к go в коммит, но сама по себе не является коммитом, поэтому ее можно изменить.
Последний есть полезная версия файла. Он не в каком-то специальном Git -только формате, и rest ваших компьютерных программ может на самом деле использовать эту версию файла. Эта версия находится в вашем рабочем дереве .
Очень типично, когда индексная копия файла соответствует по крайней мере еще одной копии - HEAD
. копия рабочего дерева или и то и другое, но на самом деле все три файла могут быть разными. Для этого просто:
- отредактируйте копию рабочего дерева (обязательно сохраните ее, чтобы
git add
могла ее видеть); - используйте
git add
для копирования копирование рабочего дерева в индекс; и - еще раз отредактируйте копию рабочего дерева (и обязательно сохраните снова).
Теперь оба файла подготовлены для фиксации , что означает, что HEAD
и индексные копии различаются, а не подготовлены для фиксации , что означает, что копии индекса и рабочего дерева различаются.
1 Технически, в индексе есть только режим, имя файла и ссылка на внутренний Git объект blob . Объект BLOB-объектов представляет собой замороженную копию файла content . Сброс (git reset
) копирует режим, имя и идентификатор ha sh в указатель. Добавление (git add
) сжимает (делает готовым к замораживанию) файл рабочего дерева путем создания нового объекта BLOB-объекта или поиска уже существующего объекта BLOB-объекта, который позже будет повторно развернут в файл рабочего дерева.