Пара 11 / ноябрь
Git: история, объекты и управление версиями Создать репозиторий, проверить diff и записать осмысленный атомарный commit.
Создать репозиторий, проверить diff и записать осмысленный атомарный commit. Git хранит историю содержимого проекта и связей между commit. Commit имеет идентификатор, автора и сообщение. Это не только резервная копия: история позволяет выяснить, что и зачем изменилось. Commit не доказывает, что код тестировался или был развёрнут. Для ML-проекта полезно отдельно фиксировать версию кода, зависимости, параметры и идентификатор артефакта; один SHA кода не воспроизводит неизвестный датасет. В учебном проекте JSON-артефакт мал и лежит рядом с кодом; реальные большие веса и данные требуют отдельного хранилища.
Контекст Разрыв с BitKeeper ускорил создание свободного распределённого VCS.
Создать репозиторий, проверить diff и записать осмысленный атомарный commit.
Linux долго принимал изменения в виде патчей и архивов. С 2002 года проект использовал проприетарный распределённый BitKeeper. В 2005-м отношения между сообществом Linux и владельцем инструмента нарушились, бесплатный режим использования прекратился. 6 апреля 2005 года в письме Kernel SCM saga Торвальдс сообщил о поиске замены после неудачных попыток разрешить конфликт вокруг использования BitKeeper. Он отдельно просил не сводить ситуацию к обвинению BitMover. Это создало практическую задачу быстро заменить важную часть процесса разработки. Торвальдс начал Git; дальнейшее развитие стало коллективным, а поддержка позже перешла к Джунио Хамано. Не сводим историю к «команда что-то не поделила»: конфликт касался условий и зависимости от внешнего проприетарного инструмента. Новый VCS должен был быстро работать с большой историей, поддерживать распределённую нелинейную разработку и локальные операции. Поэтому Git хранит историю локально и имеет дешёвые указатели ветвей. GitHub и GitLab — платформы вокруг Git, а не сам VCS.
Commit — снимок и объяснение История связывает состояние проекта с намерением изменения.
01 Код
→ 02 Diff
→ 03 Commit / SHA
→ 04 Повтор запуска
Аналогия: подписанные страницы лабораторного журнала вместо папки final_final.
Git хранит историю содержимого проекта и связей между commit. Commit имеет идентификатор, автора и сообщение. Это не только резервная копия: история позволяет выяснить, что и зачем изменилось. Commit не доказывает, что код тестировался или был развёрнут. Для ML-проекта полезно отдельно фиксировать версию кода, зависимости, параметры и идентификатор артефакта; один SHA кода не воспроизводит неизвестный датасет. В учебном проекте JSON-артефакт мал и лежит рядом с кодом; реальные большие веса и данные требуют отдельного хранилища.
Три области Git Рабочая папка, index и история — разные состояния.
01 Working tree
→ 02 git add → index
→ 03 git commit → история
Аналогия: стол с черновиками, конверт на отправку и зарегистрированное письмо.
Редактирование меняет рабочую папку. git add выбирает содержимое для следующего commit в index. git commit записывает выбранный снимок. Файл можно изменить после add: тогда staged и working tree будут различаться. git diff сравнивает рабочую папку с index; git diff --staged показывает подготовленные изменения. Перед commit смотрим обе проверки и status. Не используем git add . без осмотра в проекте, где могут оказаться секреты и большие файлы. История остаётся локальной до push; удалённый хостинг не является самим Git.
Что хранить в репозитории Храним исходники и рецепты восстановления среды.
01 Исходники / рецепты
02 Игнор: среда / секреты
03 Внешнее хранилище: большие артефакты
Аналогия: в книге рецептов хранится инструкция, а не холодильник со всеми продуктами.
В .gitignore включаем .venv, __pycache__, .env, временные логи и результаты запусков. .gitignore не убирает уже отслеживаемый файл и не стирает историю. README, Dockerfile, тесты и небольшой демонстрационный артефакт полезно хранить. Данные студентов, ключи и настоящие токены в учебный репозиторий не попадут. Сообщение commit должно объяснять изменение: feat:, fix:, docs: — понятное соглашение Conventional Commits. Не требуем идеальной истории ради оценки, но поощряем маленькие изменения с одной целью.
Git возник из требований разработки Linux Разрыв с BitKeeper ускорил создание свободного распределённого VCS.
Почему в 2005 году появился Git 1991–2002 Патчи и архивы Linux 2002 · BitKeeper Распределённый VCS 2005 · разрыв Нет бесплатного доступа 2005 · Git Торвальдс и сообщество Требования Linux-разработки Быстрые операции, локальная история, нелинейные ветви, проверка содержимого, большие проекты Это конфликт сообщества с владельцем проприетарного инструмента, а не «Linux-команда поделилась на Git и Linux». Git решает задачу учёта и обмена изменениями, а не резервного копирования секретов или доставки сервиса сам по себе.
Linux долго принимал изменения в виде патчей и архивов. С 2002 года проект использовал проприетарный распределённый BitKeeper. В 2005-м отношения между сообществом Linux и владельцем инструмента нарушились, бесплатный режим использования прекратился. 6 апреля 2005 года в письме Kernel SCM saga Торвальдс сообщил о поиске замены после неудачных попыток разрешить конфликт вокруг использования BitKeeper. Он отдельно просил не сводить ситуацию к обвинению BitMover. Это создало практическую задачу быстро заменить важную часть процесса разработки. Торвальдс начал Git; дальнейшее развитие стало коллективным, а поддержка позже перешла к Джунио Хамано. Не сводим историю к «команда что-то не поделила»: конфликт касался условий и зависимости от внешнего проприетарного инструмента. Новый VCS должен был быстро работать с большой историей, поддерживать распределённую нелинейную разработку и локальные операции. Поэтому Git хранит историю локально и имеет дешёвые указатели ветвей. GitHub и GitLab — платформы вокруг Git, а не сам VCS.
Git решает задачу учёта и обмена изменениями, а не резервного копирования секретов или доставки сервиса сам по себе.
Commit — узел графа снимков Branch — имя указателя; файлы и trees хранятся как объекты.
Git хранит граф снимков: commit ссылается на tree и родителей refs/heads/main Указатель на commit Commit C tree + parent + metadata Tree Имена → blobs / trees parent Commit B Предыдущий снимок Blob Содержимое файла Git — не GitHub. У коммита merge может быть несколько родителей; одинаковое содержимое переиспользуется. git cat-file -p HEAD показывает commit; git ls-tree HEAD — snapshot tree; git diff --staged — содержимое следующего снимка.
Blob хранит содержимое файла, tree связывает имена и режимы с blobs и вложенными trees, commit связывает корневой tree, родителей и metadata. Ветка — ref на commit, HEAD указывает на текущую ветку или прямо на commit в detached состоянии. Индекс/staging area описывает будущий снимок отдельно от текущего рабочего дерева. Поэтому git add выбирает состояние для commit, а последующая правка файла не меняет уже staged-версию автоматически. История — DAG: обычный commit имеет одного родителя, merge может иметь несколько. Git может эффективно хранить переиспользуемое содержимое, но пользовательская модель — снимки, а не копии папок branch-name. Hash идентифицирует объект согласно формату репозитория; это не универсальная подпись личности автора. Для практики создаём локальный репозиторий и смотрим cat-file, не начинаем с внешнего сервиса.
git cat-file -p HEAD показывает commit; git ls-tree HEAD — snapshot tree; git diff --staged — содержимое следующего снимка.
Наблюдение механизмов git log --oneline --graph --all
git cat-file -p HEAD
git ls-tree HEAD
git diff
git diff --stagedПолный разбор команд в конспекте → Сравните working tree, index и HEAD на одном маленьком файле. Не коммитьте .env, бинарный dataset и ключи доступа.
Команды и наблюдения Ubuntu / Bash, lab
cd ~/devops-course/lab
git init -b main
git config user.name "Student"
git config user.email "student@example.invalid"
git status
git add app.py models/model.json Dockerfile compose.yaml README.md .gitignore
git diff --staged --stat
git commit -m "feat: add reproducible StudyPulse service"
git log --oneline -3Имя и email настраиваются локально для учебного репозитория; не меняем глобальные настройки ноутбука. Ожидаемое наблюдение: main содержит первый commit; .venv и .env отсутствуют среди отслеживаемых файлов.
Разбор результата main содержит первый commit; .venv и .env отсутствуют среди отслеживаемых файлов.
Имя и email настраиваются локально для учебного репозитория; не меняем глобальные настройки ноутбука.
Проверка: git status --short; git diff; git diff --staged; git ls-files. Для отдельного commit: git add README.md; git commit -m "docs: explain port diagnostics". Если .env уже отслеживается, git rm --cached .env прекращает дальнейшее отслеживание, но при реальной утечке требуется ротация секрета и отдельная работа с историей.
На macOS Git-команды переносимы. Первый запуск git может предложить установку Apple Command Line Tools; выполните её заранее. Сохраняйте .gitignore и проверку секретов.
git --version
git status
git diff
git diff --staged
git log --oneline -3Команды macOS необходимо проверить на конкретном устройстве. Git-команды переносимы. Первый запуск git может предложить установку Apple Command Line Tools; выполните её заранее. Сохраняйте .gitignore и проверку секретов.
История исправления README Создайте репозиторий в своей копии lab и проверьте .gitignore. Измените README: добавьте диагностику неверного порта. Просмотрите diff, подготовьте только README и выполните docs: commit. Измените файл после add в отдельном опыте; покажите различие diff и diff --staged. Работа в парах: один оператор, второй проверяет гипотезу. Смена ролей в середине. Проверка: git status --short; git diff; git diff --staged; git ls-files. Для отдельного commit: git add README.md; git commit -m "docs: explain port diagnostics". Если .env уже отслеживается, git rm --cached .env прекращает дальнейшее отслеживание, но при реальной утечке требуется ротация секрета и отдельная работа с историей.
Что должно получиться Два осмысленных commit и пример staged/unstaged различия.
git ls-files не содержит .venv, .env или личных данных; изменения README понятны.
Проверка: git status --short; git diff; git diff --staged; git ls-files. Для отдельного commit: git add README.md; git commit -m "docs: explain port diagnostics". Если .env уже отслеживается, git rm --cached .env прекращает дальнейшее отслеживание, но при реальной утечке требуется ротация секрета и отдельная работа с историей.
Ошибка для диагностики Студент считает git add сохранением всей последующей работы.
Симптом → Гипотеза → Проверка
Проверка: git status --short; git diff; git diff --staged; git ls-files. Для отдельного commit: git add README.md; git commit -m "docs: explain port diagnostics". Если .env уже отслеживается, git rm --cached .env прекращает дальнейшее отслеживание, но при реальной утечке требуется ротация секрета и отдельная работа с историей.
Основные выводы Содержимое index, а не автоматически все текущие правки. Нет, Git — система контроля версий, GitHub — платформа вокруг репозиториев. Содержимое index, а не автоматически все текущие правки.
Нет, Git — система контроля версий, GitHub — платформа вокруг репозиториев.
После пары Оформить историю Linux-чекпоинта и передать SHA проверяемого состояния.
Конспект, команды и разбор → Проверьте критерии сдачи и дайте возможность повторной попытки. Первоисточники: https://git-scm.com/book/en/v2 https://www.conventionalcommits.org/en/v1.0.0/
История Git: две линии изменения main A → B → D → M
feature A ↳ C → merge в M
Ветка — указатель, не каталог-копия. M имеет двух родителей. Представьте несовместимые изменения B→D и B→C, обсудите review.
Пара 12 / ноябрь
Git в команде: ветки, review и конфликты Объединить два изменения и разрешить конфликт по смыслу, сохранив историю.
Объединить два изменения и разрешить конфликт по смыслу, сохранив историю. Ветка указывает на commit и продвигается при новой записи. git switch -c создаёт ветку, switch возвращает к другой. Рабочие файлы меняются согласно выбранному состоянию; незакоммиченные правки могут мешать переключению. В учебном workflow одна небольшая задача — одна ветка, затем review и merge. Pull request — способ обсуждения изменения на платформе, а не сущность самого Git. До внешнего хостинга всё упражнение можно выполнить локально, поэтому обучение не зависит от доступности GitHub в аудитории.
Контекст Ветка не создаёт отдельную полную копию проекта.
Объединить два изменения и разрешить конфликт по смыслу, сохранив историю.
Ветка указывает на commit и продвигается при новой записи. git switch -c создаёт ветку, switch возвращает к другой. Рабочие файлы меняются согласно выбранному состоянию; незакоммиченные правки могут мешать переключению. В учебном workflow одна небольшая задача — одна ветка, затем review и merge. Pull request — способ обсуждения изменения на платформе, а не сущность самого Git. До внешнего хостинга всё упражнение можно выполнить локально, поэтому обучение не зависит от доступности GitHub в аудитории.
Ветка — указатель на историю Ветка не создаёт отдельную полную копию проекта.
01 main: A → B
→ 02 feature: B → C
→ 03 review
→ 04 merge: D
Аналогия: отдельная линия эксперимента с точкой возврата в журнале.
Ветка указывает на commit и продвигается при новой записи. git switch -c создаёт ветку, switch возвращает к другой. Рабочие файлы меняются согласно выбранному состоянию; незакоммиченные правки могут мешать переключению. В учебном workflow одна небольшая задача — одна ветка, затем review и merge. Pull request — способ обсуждения изменения на платформе, а не сущность самого Git. До внешнего хостинга всё упражнение можно выполнить локально, поэтому обучение не зависит от доступности GitHub в аудитории.
Конфликт — вопрос смысла Git не может автоматически решить противоречие в одной области.
01 Изменение A
→ 02 Изменение B
→ 03 Конфликт
→ 04 Общий осмысленный результат
Аналогия: два редактора меняют одну фразу; программа не знает намерения авторов.
При merge Git может объединить независимые изменения. Если одна область изменена несовместимо, он оставляет маркеры конфликта. HEAD показывает текущую сторону, другая сторона — вливаемую ветку. Нельзя просто удалить маркеры и выбрать случайный вариант: прочитайте задачу и получите осмысленный итог. После исправления выполняем проверку, add и завершение merge. git merge --abort отменяет незавершённое слияние и возвращает к исходному состоянию при обычном чистом старте. Сначала убедитесь, что важные рабочие изменения сохранены. Конфликт — нормальный этап совместной работы, а не поломка Git.
Возврат изменений revert создаёт обратное изменение в истории.
01 Плохой commit
→ 02 git revert
→ 03 Новый commit
→ 04 Проверка поведения
Аналогия: бухгалтерская корректировка добавляется новой записью, а не стиранием старой.
git revert SHA полезен для отмены опубликованного commit: он создаёт новый commit, сохраняя понятную историю. reset изменяет указатели и в некоторых режимах рабочие файлы; на этом курсе не используем reset --hard как универсальную кнопку. rebase и force push вынесены за обязательный минимум. Перед merge проверяем status, читаем diff, запускаем подходящую проверку. Review отвечает на вопросы поведения, ошибок и безопасности, а не только форматирования. В парах рецензент должен пересказать изменение своими словами и предложить одну проверку.
Команды и наблюдения Ubuntu / Bash, lab
git switch -c docs/health
printf "Health endpoint: /healthz
" > route-note.txt
git add route-note.txt
git commit -m "docs: describe health endpoint"
git switch main
printf "Health endpoint: /readyz
" > route-note.txt
git add route-note.txt
git commit -m "docs: record alternate endpoint"
git merge docs/health
# Resolve route-note.txt using the actual API contract
git statusЭтот конфликт создаётся в отдельном учебном файле, не ломая README и код сервиса. Ожидаемое наблюдение: add/add conflict в route-note.txt; правильное решение сохраняет реально существующий /healthz.
Разбор результата add/add conflict в route-note.txt; правильное решение сохраняет реально существующий /healthz.
Этот конфликт создаётся в отдельном учебном файле, не ломая README и код сервиса.
После конфликта printf "Health endpoint: /healthz\n" > route-note.txt; git add route-note.txt; git commit. Для отдельного отменяемого изменения сначала создайте commit и сохраните его SHA, затем git revert SHA. Не отменяйте случайный commit из чужого примера. Финальная проверка grep маркеров в route-note.txt, git log --graph --oneline --all и curl к учебному сервису.
На macOS Ветки, конфликты и revert устроены одинаково. На APFS без различения регистра переименование только регистра имени требует осторожности; тестируйте checkout на Linux, если проект туда доставляется.
git switch -c docs/health
git status
git merge docs/health
git log --graph --oneline --allКоманды macOS необходимо проверить на конкретном устройстве. Ветки, конфликты и revert устроены одинаково. На APFS без различения регистра переименование только регистра имени требует осторожности; тестируйте checkout на Linux, если проект туда доставляется.
Парное review Создайте конфликт по демонстрации в собственной копии. Сосед объясняет, какой endpoint действительно существует, используя app.py и curl. Исправьте файл, git add route-note.txt и git commit завершат merge. Сделайте отдельный неправильный docs: commit и отмените его через revert; проверьте log. Работа в парах: один оператор, второй проверяет гипотезу. Смена ролей в середине. После конфликта printf "Health endpoint: /healthz\n" > route-note.txt; git add route-note.txt; git commit. Для отдельного отменяемого изменения сначала создайте commit и сохраните его SHA, затем git revert SHA. Не отменяйте случайный commit из чужого примера. Финальная проверка grep маркеров в route-note.txt, git log --graph --oneline --all и curl к учебному сервису.
Что должно получиться Разрешённый merge, revert и краткая запись review.
В файле нет маркеров; актуальный endpoint подтверждён; история сохранена.
После конфликта printf "Health endpoint: /healthz\n" > route-note.txt; git add route-note.txt; git commit. Для отдельного отменяемого изменения сначала создайте commit и сохраните его SHA, затем git revert SHA. Не отменяйте случайный commit из чужого примера. Финальная проверка grep маркеров в route-note.txt, git log --graph --oneline --all и curl к учебному сервису.
Ошибка для диагностики Выбрана красивая, но несуществующая версия URL.
Симптом → Гипотеза → Проверка
После конфликта printf "Health endpoint: /healthz\n" > route-note.txt; git add route-note.txt; git commit. Для отдельного отменяемого изменения сначала создайте commit и сохраните его SHA, затем git revert SHA. Не отменяйте случайный commit из чужого примера. Финальная проверка grep маркеров в route-note.txt, git log --graph --oneline --all и curl к учебному сервису.
Основные выводы Нет, он требует решения неоднозначного объединения. Он сохраняет след исходного изменения и его отмены. Нет, он требует решения неоднозначного объединения.
Он сохраняет след исходного изменения и его отмены.
После пары Составить чеклист review: назначение, тест, конфигурация, секреты и обратимость.
Конспект, команды и разбор → Проверьте критерии сдачи и дайте возможность повторной попытки. Первоисточники: https://git-scm.com/book/en/v2