Содержание

Основы Git: локальная работа и GitHub

Проблема: как не потерять код и не сломать проект

Представьте: вы пишете программу, всё работает. Решаете добавить новую фичу, меняете код в нескольких файлах... и всё ломается. Хуже того — вы уже не помните, что именно изменили. Откатиться назад невозможно.

Или другая ситуация: работаете над проектом вдвоём. Коллега прислал свою версию файла, вы — свою. Как объединить изменения? Копировать вручную? А если изменений сотни?

Типичные "решения" без системы контроля версий:

project/
├── main.go
├── main_v2.go
├── main_final.go
├── main_final_FINAL.go
├── main_backup_23dec.go
└── main_работает_не_трогать.go

Знакомо? Это хаос. Непонятно, какая версия актуальная, что изменилось между версиями, и почему "final" три штуки.

Что такое система контроля версий

Система контроля версий (VCS, Version Control System) — инструмент, который:

  1. Хранит историю изменений. Каждое сохранённое состояние проекта (коммит) остаётся в истории навсегда. Можно посмотреть, что было неделю назад, кто и зачем это изменил.

  2. Позволяет откатываться. Сломали что-то? Одна команда — и проект в рабочем состоянии.

  3. Объединяет работу нескольких людей. Два человека редактируют один файл — система поможет объединить изменения или покажет конфликты.

  4. Создаёт параллельные версии (ветки). Хотите поэкспериментировать? Создайте ветку, экспериментируйте. Не получилось — удалите. Получилось — объедините с основной версией.

Что такое Git

Git — самая популярная система контроля версий. Создана Линусом Торвальдсом в 2005 году для разработки ядра Linux (когда предыдущая система перестала быть бесплатной).

Ключевые особенности Git:

  • Распределённая архитектура. В отличие от старых систем (SVN, CVS), где вся история хранилась на центральном сервере, Git хранит полную копию репозитория на каждом компьютере. Вы можете работать офлайн — делать коммиты, смотреть историю, создавать ветки. Синхронизация с сервером происходит только когда вы явно этого хотите (push/pull).

  • Скорость. Большинство операций выполняются локально, без сети. Создание ветки — мгновенно (это просто указатель на коммит).

  • Целостность данных. Каждый коммит идентифицируется SHA-1 хешем. Изменить что-то в истории незаметно невозможно — хеш изменится.

GitHub — это не Git

GitHub — платформа для хранения Git-репозиториев в облаке. Это и бэкап кода, и портфолио, и площадка для совместной работы.

Git — инструмент командной строки, работает локально. GitHub — веб-сервис, построенный вокруг Git (есть альтернативы: GitLab, Bitbucket).

Можно использовать Git без GitHub (только локально), но GitHub без Git — нет.

Установка Git

macOS

Git обычно уже установлен. Проверьте:

git --version

Если нет — установите через Homebrew:

brew install git

Или скачайте с git-scm.com.

Linux (Ubuntu/Debian)

sudo apt update sudo apt install git

Windows

Скачайте установщик с git-scm.com. При установке выберите "Git Bash" — это даст вам Unix-подобный терминал.

Первоначальная настройка

Перед первым коммитом Git должен знать, кто вы. Выполните один раз:

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

Проверить настройки:

git config --list

Локальная работа с Git

Создание репозитория

В папке вашего проекта:

git init

Эта команда создаёт скрытую папку .git, где Git хранит всю историю. Проект стал репозиторием.

Три состояния файлов

Git разделяет файлы на три области:

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

Как Git устроен внутри

Что такое коммит на самом деле

Коммит — это не "сохранение файлов". Это снимок (snapshot) всего проекта в определённый момент времени + метаданные.

Каждый коммит содержит:

  • Tree — ссылка на структуру директорий и файлов
  • Parent — ссылка на предыдущий коммит (или несколько, при merge)
  • Author — кто написал код
  • Committer — кто сделал коммит (обычно тот же человек)
  • Message — описание изменений
  • SHA-1 хеш — уникальный идентификатор коммита (40 символов)
# Посмотреть детали коммита git cat-file -p HEAD
tree 8f94139338f9404f26296befa88755fc2598c289
parent 7d1b31e74ae3c7b6e5b8f7a3c4d5e6f7a8b9c0d1
author Иван Петров <ivan@example.com> 1703001234 +0300
committer Иван Петров <ivan@example.com> 1703001234 +0300

Добавить обработку флага --help

Что внутри папки .git

Когда вы делаете git init, создаётся скрытая папка .git. Это и есть репозиторий — всё остальное называется "рабочая директория".

.git/
├── HEAD              # Указатель на текущую ветку
├── config            # Локальные настройки репозитория
├── index             # Индекс (staging area) в бинарном формате
├── objects/          # Все данные: коммиты, файлы, деревья
│   ├── pack/         # Сжатые объекты (для экономии места)
│   └── info/
├── refs/             # Ссылки на коммиты
│   ├── heads/        # Локальные ветки
│   └── remotes/      # Удалённые ветки
└── hooks/            # Скрипты, запускаемые при событиях

objects/ — самая важная папка. Git хранит всё как объекты четырёх типов:

ТипЧто хранит
blobСодержимое файла (без имени!)
treeСтруктура директории: имена файлов + ссылки на blob'ы
commitМетаданные коммита + ссылка на tree
tagИменованная ссылка на коммит
# Посмотреть тип объекта по хешу git cat-file -t 8f94139 # Посмотреть содержимое объекта git cat-file -p 8f94139

Как Git отслеживает изменения

Git не хранит diff'ы между версиями файлов. Он хранит полные снимки, но умно экономит место:

  1. Дедупликация по содержимому. Если два файла идентичны (даже с разными именами) — хранится один blob. Хеш вычисляется от содержимого, поэтому одинаковые файлы = одинаковый хеш.

  2. Pack-файлы. Периодически Git сжимает объекты в pack-файлы, используя дельта-компрессию. Похожие файлы хранятся как "базовый файл + изменения".

Когда вы делаете git status, Git:

  1. Читает индекс (.git/index) — это "подготовленное" состояние
  2. Сравнивает индекс с последним коммитом — находит "staged" изменения
  3. Сравнивает рабочую директорию с индексом — находит "unstaged" изменения
  4. Проверяет, какие файлы не отслеживаются
# Посмотреть, что в индексе git ls-files --stage

Основные команды

Посмотреть статус:

git status

Показывает, какие файлы изменены, какие добавлены в индекс, какие не отслеживаются.

Добавить файлы в индекс:

git add main.go # один файл git add . # все файлы в текущей папке git add -A # все изменения в репозитории

Создать коммит:

git commit -m "Описание изменений"

Посмотреть историю:

git log # полная история git log --oneline # компактный вид

Типичный рабочий цикл

# 1. Проверить статус git status # 2. Посмотреть изменения git diff # 3. Добавить нужные файлы git add main.go README.md # 4. Закоммитить git commit -m "Добавить вывод справки по --help" # 5. Проверить, что всё сохранилось git log --oneline

Файл .gitignore

Не все файлы нужно хранить в репозитории. Скомпилированные бинарники, файлы IDE, секреты — всё это должно быть исключено.

Создайте файл .gitignore в корне проекта:

# Скомпилированные бинарники myapp *.exe # Файлы IDE .idea/ .vscode/ *.swp # Зависимости (обычно не коммитят) vendor/ # Секреты и локальные настройки .env *.local

Важно: .gitignore работает только для файлов, которые ещё не отслеживаются. Если файл уже был закоммичен, добавление в .gitignore не удалит его из истории.

Работа с GitHub

Создание репозитория на GitHub

  1. Зайдите на github.com и авторизуйтесь
  2. Нажмите New repository (или +New repository)
  3. Укажите имя репозитория (например, myapp)
  4. Не добавляйте README, .gitignore или лицензию, если у вас уже есть локальный проект
  5. Нажмите Create repository

GitHub покажет команды для подключения локального репозитория.

Подключение локального репозитория к GitHub

# Добавить удалённый репозиторий (выполняется один раз) git remote add origin https://github.com/{ваш юзернейм в GitHub}/myapp.git # Отправить код на GitHub git push -u origin main

Если ваша ветка называется master, а не main:

git push -u origin master

Клонирование существующего репозитория

Чтобы скачать чужой (или свой) репозиторий с GitHub:

git clone https://github.com/{юзернейм автора}/{название репозитория}.git

Создаст папку project с полной историей репозитория.

Получение изменений с GitHub

Если кто-то (или вы с другого компьютера) добавил изменения на GitHub:

git pull

SSH vs HTTPS

При работе с GitHub можно использовать два протокола:

  • HTTPS — проще настроить, но просит логин/пароль (или токен) при каждом push
  • SSH — требует настройки ключей, но после этого работает без ввода пароля

Для начала HTTPS достаточно. Если надоест вводить пароль — настройте SSH-ключи по инструкции GitHub.

Шпаргалка по командам

КомандаЧто делает
git initСоздать репозиторий
git statusПоказать статус файлов
git add <файл>Добавить файл в индекс
git add .Добавить все файлы
git commit -m "msg"Создать коммит
git log --onelineИстория коммитов
git diffПоказать изменения
git remote add origin <url>Подключить удалённый репозиторий
git pushОтправить изменения на GitHub
git pullПолучить изменения с GitHub
git clone <url>Склонировать репозиторий

Частые ошибки

"fatal: not a git repository"

Вы не в папке с репозиторием. Либо перейдите в нужную папку, либо выполните git init.

Закоммитили лишний файл

Если файл уже в истории, добавление в .gitignore не поможет. Удалите из отслеживания:

git rm --cached filename git commit -m "Удалить filename из репозитория"

Конфликт при pull

Git не смог автоматически объединить изменения. Откройте файл с конфликтом, найдите маркеры <<<<<<<, =======, >>>>>>>, выберите нужную версию, удалите маркеры, закоммитьте.

Что дальше

Эта статья покрывает минимум для старта. Когда освоитесь, изучите:

  • Ветки (branches) — параллельная разработка фич
  • Merge и rebase — объединение веток
  • Pull requests — код-ревью на GitHub
  • git stash — временное сохранение незакоммиченных изменений

Полезные ресурсы

Следующий шаг после статьи

Закрепите тему во вводном проекте без регистрации, а затем переходите к курсам.

Продолжить изучение

Выбери следующую статью по маршруту или углубись в смежную тему.

Похожие статьи