📝 Python

Как Git хранит изменения 💾

0
Author
04e5cc8b-58ac-4bdc-bdee-661bbb
📅
Published
06.05.2026
⏱️
Reading time
3 min
👁️
Views
25
🌱
Level
Beginner

Вы когда-нибудь задумывались, как Git так быстро работает? Как он хранит всю историю проекта, но при этом занимает так мало места? Давайте заглянем под капот!

Магия Git: снимки, а не изменения

Большинство систем контроля версий хранят изменения (дельты):

Файл v1: "Hello"
Изменение 1: +5 символов " World"
Изменение 2: +1 символ "!"

Git работает по-другому. Он делает снимки (snapshots) всего проекта:

Коммит 1: полный снимок проекта
Коммит 2: полный снимок проекта (с изменениями)
Коммит 3: полный снимок проекта

Как это работает?

1. Хеширование (SHA-1)

Каждый файл Git превращает в уникальный хеш (контрольную сумму):

# Файл: hello.txt содержит "Hello World"
# Git вычисляет SHA-1 хеш:
557db03de997c86a4a028e1ebd3a1ceb225be238

Если файл не изменился — хеш тот же самый!
Если хоть один символ изменился — совершенно новый хеш.

2. Объекты Git

Git хранит 4 типа объектов:

1. Blob (Binary Large Object)
- Содержимое файла
- Просто данные, без имени файла

2. Tree (Дерево)
- Папка в файловой системе
- Список файлов (blob) и подпапок (tree)

3. Commit (Коммит)
- Снимок проекта в момент времени
- Ссылается на tree
- Ссылается на родительский commit
- Содержит автора, дату, сообщение

4. Tag (Метка)
- Именованная метка коммита
- Например, “v1.0.0”

Пример: как Git хранит коммит

Представим простой проект:

my-project/
├── README.md
└── src/
    └── main.py

Что создаёт Git:

BLOB для README.md
  hash: abc123...
  content: "# My Project\n..."

BLOB для main.py
  hash: def456...
  content: "print('Hello')"

TREE для src/
  hash: ghi789...
  main.py -> def456...

TREE для корня
  hash: jkl012...
  README.md -> abc123...
  src -> ghi789...

COMMIT
  hash: mno345...
  tree: jkl012...
  parent: предыдущий коммит
  author: "Вася <vasya@example.com>"
  date: "2026-04-10 15:00:00"
  message: "Добавил README"

Экономия места: дедупликация

Умная фишка: если файл не изменился между коммитами, Git НЕ создаёт новую копию!

Коммит 1:
  README.md -> blob abc123

Коммит 2 (изменил только main.py):
  README.md -> blob abc123 (ТОТ ЖЕ blob!)
  main.py -> blob xyz999 (новый blob)

Результат: огромная экономия места!

Сжатие и pack файлы

Со временем Git дополнительно сжимает объекты в pack files:

  • Похожие файлы компрессируются вместе
  • Старые версии файлов хранятся как дельты (изменения)
  • Это происходит автоматически

Преимущества подхода Git

✅ Скорость

Все операции локальные:
- Просмотр истории — мгновенно
- Переключение веток — секунды
- Сравнение версий — быстро

✅ Целостность

Каждый объект идентифицируется по хешу:
- Невозможно изменить прошлое незаметно
- Любая коррупция данных будет обнаружена
- История защищена криптографически

✅ Компактность

Благодаря дедупликации и сжатию:
- Множество версий файлов занимают мало места
- Можно хранить полную историю проекта

✅ Распределённость

Каждый клон — полная копия:
- Вся история проекта
- Все ветки
- Все теги

Где Git хранит данные?

Всё находится в папке .git/:

.git/
├── objects/      # Blob, tree, commit объекты
├── refs/         # Ссылки на ветки и теги
├── HEAD          # Текущая ветка
├── index         # Staging area
└── config        # Конфигурация

Практический пример

# Создаём файл
echo "Hello Git" > test.txt

# Добавляем в staging
git add test.txt

# Git создал blob объект!
# Можно посмотреть его содержимое:
git cat-file -p abc123...

# Делаем коммит
git commit -m "Add test"

# Git создал:
# - blob для test.txt
# - tree для корня
# - commit объект

Интересные факты

🔍 SHA-1 коллизии:
- Теоретически возможны
- На практике вероятность ничтожна
- Git переходит на SHA-256

📦 Размер .git папки:
- Обычно 10-30% от размера проекта
- У Linux kernel: ~3GB кода, ~1.5GB .git
- 20+ лет истории в 1.5GB!

🚀 Скорость:
- git log — мгновенно (локальная БД)
- svn log — секунды (запрос к серверу)

Выводы

Git умный потому что:

  1. ✅ Хранит снимки, а не дельты
  2. ✅ Использует хеширование для идентификации
  3. Дедуплицирует неизменённые файлы
  4. Сжимает данные автоматически
  5. ✅ Работает локально (быстро!)

Теперь вы понимаете почему Git такой быстрый и эффективный! 🚀

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

Модуль datetime: работа с датами и временем

datetime — стандартный модуль Python для работы с датами и временем. Входит в стандартную библиотеку,...

📅 08.05.2026 👁️ 30
📝

.env файлы и переменные окружения: секреты вне ко…

Представь что ты написал программу с API-ключом прямо в коде и залил её на GitHub....

📅 08.05.2026 👁️ 35
📝

Виртуальные окружения в Python: зачем и как

Когда начинаешь второй Python-проект и ставишь pip install requests — эта библиотека устанавливается глобально, для...

📅 08.05.2026 👁️ 31

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!