Shanraq.org Shanraq.org
Git: история вашего кода и путь назад
IT

Go: с нуля до своего блога Урок 16 из 50

Git: история вашего кода и путь назад

Шестнадцатый урок курса по Go. Git хранит не последнюю версию файла, а все состояния, к которым можно вернуться. git init, три места — папка, индекс и история, — git status как самая частая команда, что писать в сообщении, зачем нужен .gitignore и как достать вчерашний файл.

Зачем это нужно

Вы правите работающую программу, она перестаёт работать, и вернуть как было уже нельзя: старый текст затёрт. Знакомо всем, и все проходят через папки вида main_старый.go, main_рабочий2.go.

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

И вторая причина, прямее первой: без Git вас не возьмут на работу. Не потому, что это модно, а потому, что весь код в мире лежит в нём, и разработчик без Git не может ни взять чужую работу, ни отдать свою.

Образ. Не одна последняя страница, а тетрадь с закладками. Обычное сохранение оставляет только то, что вы написали сейчас. Git оставляет каждую отмеченную страницу — и вы в любой момент открываете нужную.

Сразу целиком

Git ставится отдельно от Go: git-scm.com — обычная установка. Проверьте:

git --version

Один раз на компьютере назовите себя — этим подписываются ваши записи:

git config --global user.name "Ваше имя"
git config --global user.email "pochta@example.com"

Теперь возьмите папку любого урока и выполните в ней по порядку:

git init
git add .
git commit -m "Первая программа"

Поправьте main.go — добавьте ещё одну строку вывода — и спросите Git, что изменилось:

git status
## main
 M main.go

M значит modified — изменён. Посмотрите, что именно:

git diff
--- a/main.go
+++ b/main.go
@@ -4,4 +4,5 @@ import "fmt"
 
 func main() {
 	fmt.Println("Привет, мир!")
+	fmt.Println("Это мой блог.")
 }

Сохраните это состояние и посмотрите историю:

git add main.go
git commit -m "Добавлена строка про блог"
git log --oneline
1a2b3c4 Добавлена строка про блог
1a2b3c4 Первая программа

Хеши в выдержках — образец: в вашем репозитории они будут другими.

Слева — короткие имена записей. У вас они будут другие: они вычисляются из содержимого, и двух одинаковых не бывает.

Разбор

git init — папка становится историей

Одна команда превращает обычную папку в репозиторий: рядом появляется скрытая папка .git, и в ней Git хранит все состояния. Удалите .git — останется обычная папка с последней версией файлов, история пропадёт.

Репозиторий заводят один раз на проект. Не на каждую папку урока по отдельности, а на весь курс — так вы увидите, как растёт работа.

Три места: папка, индекс, история

Это то, на чём спотыкаются все, и стоит запомнить сразу.

  1. Рабочая папка — файлы, которые вы правите. Git видит их, но ничего с ними не делает.
  2. Индекс — то, что вы выбрали для следующей записи. Туда кладёт git add.
  3. История — записанные состояния. Туда переносит git commit.

Поэтому шага два, а не один: add выбирает, commit записывает. Можно поправить пять файлов, а записать три — остальные подождут следующей записи.

Образ. Поднос перед кассой. В магазине вы ходите между полками (папка), кладёте на поднос то, что берёте (add), и только на кассе получаете чек (commit). В чек попадает то, что на подносе, а не всё, что вы трогали.

git add . кладёт всё изменённое разом — так делают чаще всего, но помните, что «всё» значит всё.

git status — самая частая команда

Её набирают десятки раз в день, и это нормально. Она отвечает на единственный вопрос: что сейчас в каком месте.

Пока непонятно, что происходит, — набирайте git status. Он подскажет и следующую команду.

Что писать в сообщении

Сообщение объясняет зачем, а не что. «Изменил main.go» бесполезно: что изменён main.go, и так видно из записи. «Добавил время чтения в карточку» — полезно.

Пишите коротко, в одну строку, в настоящем или прошедшем времени — как принято у вас. Через полгода вы будете читать эти строки, чтобы найти нужный момент, и спасибо скажете себе сегодняшнему.

.gitignore — чего в истории быть не должно

Собранная программа, временные файлы, пароли — им в истории не место. Создайте файл .gitignore и перечислите:

blog
*.exe
.env

Git перестанет их замечать. Правило простое: в историю попадает только то, что вы написали руками. Всё, что можно получить командой go build, получают командой go build.

Пароли — отдельно и без исключений. Записанный в историю пароль остаётся в ней даже после удаления файла, и вычистить его оттуда трудно.

Образ. Что не сдают в архив. Черновики, распечатки и стаканчик от кофе остаются на столе. В архив идут документы.

Вернуться назад

Ради этого всё и затевалось:

git log --oneline
git restore --source=HEAD~1 main.go

HEAD — текущее состояние, HEAD~1 — предыдущее. Команда достаёт файл таким, каким он был тогда, и кладёт в папку. Ничего не потеряно: последняя запись на месте, вы просто взяли из неё соседнюю версию файла.

Есть и обратный случай: вы наломали дров и хотите вернуть файл к последней записи, забыв правки, — git restore main.go. Осторожно: несохранённое пропадёт.

Одно правило на весь курс

Заканчивая урок, делайте запись. Одна строка в терминале, три секунды.

Через месяц у вас будет история из тридцати шагов, по которой видно, как вы учились. Это и есть то, что показывают работодателю, — не «прошёл курс», а сорок записей с внятными сообщениями.

Карта урока

Карта урока: два шага — git add выбирает, git commit записывает

Скажите своими словами

Не подглядывая, ответьте вслух или на бумаге. Ответы — в конце урока.

  1. Почему шага два — add и commit, — а не один?
  2. Что не должно попадать в историю и почему?
  3. Вы испортили файл и хотите вернуть вчерашнюю версию. Какие две команды помогут?

Задание

Обязательное. Заведите репозиторий для всех своих уроков: git init в общей папке курса, .gitignore с собранными программами, первая запись со всем, что уже написано. Затем поправьте любой файл, посмотрите git status и git diff, сделайте вторую запись и убедитесь, что git log --oneline показывает обе.

По желанию.

  • Достаньте файл из первой записи через git restore --source=HEAD~1 и убедитесь, что содержимое вернулось.
  • Добавьте в .gitignore строку *.log, создайте файл test.log и проверьте, что git status его не замечает.
  • Выполните git show HEAD и прочитайте, что Git хранит в одной записи: кто, когда, что именно.

Куда это встанет в блоге

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

В следующем уроке история переедет на GitHub: то же самое, но видно другим людям — и работодателю в том числе.

Ответы

Показать ответы
  1. Потому что записывать нужно не всё, что вы трогали, а то, что закончено. add выбирает, commit записывает выбранное. Поправив пять файлов, вы можете записать три, а остальные оставить на следующий раз.
  2. Всё, что не написано вами руками: собранная программа, временные файлы, а главное — пароли и ключи. Собранное всегда можно получить заново командой go build, а пароль, попавший в историю, остаётся в ней и после удаления файла.
  3. git log --oneline, чтобы увидеть записи и выбрать нужную, и git restore --source=HEAD~1 main.go, чтобы достать файл из предыдущей записи.

Источники

Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом

Проверить задание

Сначала решите и запустите в VS Code — редактор покажет ошибку на месте. Готовое решение вставьте сюда. Проверяет модель: она укажет на ошибку, но не даст готовый ответ.

Чтобы проверить, нужно войти. Войти

Комментарии (0)

Пока нет комментариев. Будьте первым.