Основы 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) — инструмент, который:
-
Хранит историю изменений. Каждое сохранённое состояние проекта (коммит) остаётся в истории навсегда. Можно посмотреть, что было неделю назад, кто и зачем это изменил.
-
Позволяет откатываться. Сломали что-то? Одна команда — и проект в рабочем состоянии.
-
Объединяет работу нескольких людей. Два человека редактируют один файл — система поможет объединить изменения или покажет конфликты.
-
Создаёт параллельные версии (ветки). Хотите поэкспериментировать? Создайте ветку, экспериментируйте. Не получилось — удалите. Получилось — объедините с основной версией.
Что такое 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 разделяет файлы на три области:
- Рабочая директория — файлы, которые вы редактируете
- Индекс (staging area) — файлы, подготовленные к коммиту
- Репозиторий — сохранённая история изменений
Рабочая директория → 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'ы между версиями файлов. Он хранит полные снимки, но умно экономит место:
-
Дедупликация по содержимому. Если два файла идентичны (даже с разными именами) — хранится один blob. Хеш вычисляется от содержимого, поэтому одинаковые файлы = одинаковый хеш.
-
Pack-файлы. Периодически Git сжимает объекты в pack-файлы, используя дельта-компрессию. Похожие файлы хранятся как "базовый файл + изменения".
Когда вы делаете git status, Git:
- Читает индекс (
.git/index) — это "подготовленное" состояние - Сравнивает индекс с последним коммитом — находит "staged" изменения
- Сравнивает рабочую директорию с индексом — находит "unstaged" изменения
- Проверяет, какие файлы не отслеживаются
# Посмотреть, что в индексе 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
- Зайдите на github.com и авторизуйтесь
- Нажмите New repository (или + → New repository)
- Укажите имя репозитория (например,
myapp) - Не добавляйте README, .gitignore или лицензию, если у вас уже есть локальный проект
- Нажмите 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 — временное сохранение незакоммиченных изменений
Полезные ресурсы
- Git Book на русском — официальная книга, глубокое погружение
- GitHub: создание репозитория — пошаговая инструкция
- Интерактивный тренажёр — визуализация работы с ветками
- Чёрт побери, Git!?! — как исправить типичные ошибки