Ежедневный цикл: изменить, добавить в индекс, сохранить в историю
git restore--amend и знать, когда этого делать нельзяС точки зрения Git каждый файл в рабочем каталоге находится в одном из состояний:
| Состояние | В выводе git status | Что значит |
|---|---|---|
| Неотслеживаемый | Untracked files | Git этот файл ещё не сохранял |
| Изменённый | Changes not staged for commit | Файл отличается от последнего коммита, но не добавлен в индекс |
| В индексе | Changes to be committed | Изменение попадёт в следующий коммит |
| Неизменённый | не показывается | Совпадает с последним коммитом |
Короткий вид статуса — две колонки: левая — индекс, правая — рабочий каталог:
$ git status -s
M index.html # изменён и добавлен в индекс
M style.css # изменён, но не в индексе
A about.html # новый, добавлен в индекс
?? notes.txt # неотслеживаемый
$ git add README.md # один файл
$ git add index.html style.css # несколько
$ git add css/ # всю папку
$ git add . # все изменения в текущей папке и ниже
git add . добавляет всё подряд: временные файлы, логи, файлы с паролями. Перед ним всегда смотрите git status. Как навсегда исключить лишние файлы — .gitignore, модуль 08.Если в одном файле два несвязанных изменения, их можно разнести по разным коммитам. Флаг -p (patch) показывает каждый изменённый фрагмент и спрашивает, добавлять ли его:
$ git add -p index.html
@@ -12,7 +12,7 @@
- <h1>Портфолио Анны Смирновй</h1>
+ <h1>Портфолио Анны Смирновой</h1>
(1/2) Stage this hunk [y,n,q,a,d,s,e,?]? y
@@ -40,3 +40,8 @@
+ <section id="contacts">
+ ...
(2/2) Stage this hunk [y,n,q,a,d,s,e,?]? n
y — добавить фрагмент, n — пропустить, s — разбить на части помельче, q — выйти. В индексе теперь только исправление опечатки.
$ git commit -m "Исправить опечатку в фамилии"
[main 4c1e9b2] Исправить опечатку в фамилии
1 file changed, 1 insertion(+), 1 deletion(-)
В ответе: ветка (main), начало хеша нового коммита и сколько строк изменилось. Без флага -m Git откроет редактор для сообщения — так удобнее писать сообщение из нескольких строк.
Флаг -a добавляет в коммит все изменения отслеживаемых файлов, минуя git add. Новые файлы он не берёт:
$ git commit -am "Увеличить отступы в карточках проектов"
История читается по сообщениям. Через полгода по ним ищут, когда сломалась форма и зачем удалили блок. Сравните две истории одного проекта:
# плохо: непонятно, что и зачем
f3a01c9 fix
b82e4d1 правки
0c9d7e2 wip
a1b2c3d update index.html
# хорошо: каждое сообщение отвечает «что сделает этот коммит»
f3a01c9 Исправить отправку формы при пустом телефоне
b82e4d1 Перенести контакты в подвал страницы
0c9d7e2 Добавить раздел с проектами
a1b2c3d Сверстать шапку главной страницы
git log --oneline и веб-интерфейсы.Ограничить размер загружаемого фото до 5 МБ
Пользователи загружали фото с телефона по 20–30 МБ, страница
проекта открывалась больше минуты. Сжатие на сервере — отдельной
задачей.
feat: добавить фильтр по тегам, fix: исправить отправку формы, docs: дополнить README. Если в проекте есть соглашение — следуйте ему.Две ситуации и две команды:
# убрать файл из индекса — изменения в файле остаются
$ git restore --staged style.css
# выбросить изменения в рабочем каталоге — вернуть как в последнем коммите
$ git restore style.css
git restore <файл> без --staged уничтожает несохранённые правки безвозвратно: их не было ни в одном коммите, восстановить неоткуда. Перед этой командой посмотрите git diff <файл>.В старых инструкциях и в подсказках старых версий Git вместо restore встречаются git checkout -- файл и git reset HEAD файл. Они делают то же самое, но checkout перегружен смыслами (переключает и ветки), поэтому в Git 2.23 его разделили на switch и restore.
$ git rm old-page.html # удалить файл и записать удаление в индекс
$ git rm --cached secrets.txt # перестать отслеживать, файл на диске остаётся
$ git mv about.html about-me.html # переименовать
$ git status -s
D old-page.html
D secrets.txt
R about.html -> about-me.html
?? secrets.txt
Если удалить или переименовать файл обычными средствами (проводником, rm), Git тоже это заметит — останется выполнить git add для нового и старого имени. git rm и git mv делают это за один шаг.
git rm --cached убирает файл из следующих коммитов, но не из прошлых. Если пароль уже попал в коммит, а коммит — на сервер, считайте пароль скомпрометированным и меняйте его.Опечатка в сообщении или забытый файл — частые ошибки сразу после коммита. --amend заменяет последний коммит новым:
# исправить сообщение
$ git commit --amend -m "Добавить раздел с проектами"
# добавить забытый файл, сообщение оставить
$ git add img/project1.png
$ git commit --amend --no-edit
--amend создаёт коммит с новым хешем. Если старый коммит уже отправлен на сервер и его забрали коллеги, их история разойдётся с вашей. Правило: исправлять можно только то, что ещё не отправлено. Для отправленного — новый коммит с исправлением.git status → git add → git status → git commitgit add -p разносит несвязанные правки одного файла по разным коммитамgit restore --staged убирает из индекса, git restore без флага — стирает правки--amend — только для коммитов, которые ещё не отправлены на сервер