Git в глубину
Git — это распределенная система контроля версий, предназначенная для облегчения совместной работы над проектами разработки программного обеспечения. Это позволяет нескольким разработчикам одновременно работать над одной и той же кодовой базой, при этом отслеживая изменения в коде и позволяя команде при необходимости вернуться к предыдущим версиям. Git использует файловую систему с адресацией по содержимому для хранения данных, что позволяет точно и эффективно отслеживать изменения в файлах и каталогах. Git использует три основных типа объектов для хранения данных: большой двоичный объект, дерево и фиксация. Объекты Blob представляют файлы, объекты дерева представляют каталоги, а объекты фиксации представляют моментальные снимки репозитория в определенные моменты времени. Git также использует указатели для отслеживания коммитов в репозитории, например HEAD
, теги и ветки. Понимая, как Git хранит данные и использует указатели, разработчики могут эффективно использовать Git для управления своей кодовой базой и совместной работы над одним проектом.
Git похож на хранилище пар "ключ-значение" => ключ -> значение.
Ключ — sha-1 — криптографическое 40-значное шестнадцатеричное число. Эти идентификаторы коммитов — sha-1. Также известна как система адресации контента. Из содержимого также мы можем получить ключ
Как git хранит данные?
Git хранит данные в трех основных типах объектов: blob, tree и commit. Объект blob представляет файл, хранящийся как двоичный объект, и соответствует определенной версии файла. Объект дерева представляет каталог и содержит ссылки на большие двоичные объекты и другие деревья, а также содержит список записей, представляющих файлы или подкаталоги. Объект фиксации представляет собой снимок репозитория в определенный момент времени и содержит метаданные, такие как автор, дата и сообщение фиксации, а также ссылку на объект дерева, представляющий корневой каталог репозитория в этот момент времени. . Коммиты также содержат ссылку на родительский объект коммита, создавая цепочку коммитов, представляющую полную историю репозитория. Git использует эти объекты для отслеживания изменений в файлах в репозитории, обеспечивая эффективное и точное отслеживание изменений, а также предоставляя полную и удобную историю репозитория.
Git хранит данные в большом двоичном объекте с его метаданными и разделителем. Нам также нужно что-то еще, например, для хранения структуры папок. Нам нужны деревья, они используют указатели и указывают на большие двоичные объекты, а также могут указывать на другие деревья, а также хранить метаданные.
Почему мы не можем хранить пустые каталоги git?
Когда мы говорим о Git, одним из его ограничений является то, что он не может хранить пустые каталоги. Это связано с тем, что промежуточная область в Git отслеживает только файлы, а не каталоги. В Git каталоги называются деревьями и используются для хранения структуры папок репозитория. Когда вы добавляете новый файл в репозиторий, Git создает новый объект большого двоичного объекта, представляющий этот файл. Если вы добавите новый каталог в репозиторий, Git создаст новый объект дерева, представляющий этот каталог. Объект дерева содержит список записей, где каждая запись представляет файл или подкаталог в каталоге.
Однако если вы попытаетесь добавить в репозиторий пустой каталог, Git не распознает его как каталог, поскольку в нем нет файлов. Вместо этого Git просто проигнорирует пустой каталог. Это связано с тем, что Git отслеживает изменения только в файлах, а не в каталогах.
Для хранения структуры папок репозитория Git использует деревья, которые могут указывать на большие двоичные объекты и другие деревья и хранить метаданные. Деревья похожи на каталоги в файловой системе, но имеют некоторые важные отличия. В Git деревья — это объекты с адресацией по содержимому, что означает, что каждое дерево имеет уникальный хэш SHA-1, вычисляемый на основе содержимого дерева. Это позволяет Git эффективно хранить и извлекать деревья даже в больших репозиториях.
В целом, хотя Git не может хранить пустые каталоги, он использует деревья для представления структуры папок репозитория и эффективного отслеживания изменений в файлах и каталогах. Понимание того, как Git хранит данные в деревьях и больших двоичных объектах, является важной частью работы с Git и его эффективного использования в качестве системы контроля версий.
Каталоги Git имеют ограничение в промежуточной области. Он отслеживает только файлы, а не каталоги.
Деревья указывают на другие деревья и капли и являются ориентированными графами. Из-за sha-1 идентичный контент в git сохраняется только один раз.
Поскольку sha-s соответствуют git-дереву, он указывает только на один большой двоичный объект.
Поскольку файлы изменяются лишь незначительно, когда мы добавляем метод, поэтому git применяет некоторые дополнительные эффективные методы, которые помогают использовать git быстрее. Git использует пак-файлы, дельты и их сжатие. дельты - это различия между файлами.
Что такое коммиты?
Коммит в Git — это моментальный снимок состояния репозитория в определенный момент времени. Он содержит ссылку на объект дерева, представляющий корневой каталог репозитория на данный момент времени, а также метаданные, такие как автор, дата и сообщение фиксации. Каждый коммит также имеет уникальный хэш SHA-1, который рассчитывается на основе содержимого коммита, включая метаданные.
Когда вы вносите изменения в файлы в репозитории и фиксируете эти изменения, Git создает новый объект фиксации, представляющий новый снимок репозитория. Новый объект фиксации указывает на объект дерева, представляющий новый корневой каталог репозитория, а также указывает на предыдущий объект фиксации в качестве своего родителя. Это создает цепочку коммитов, которая представляет полную историю репозитория.
Одной из важных особенностей коммитов Git является то, что они неизменяемы. После того, как коммит сделан, его нельзя изменить. Это связано с тем, что хэш SHA-1 коммита уникален для его содержимого, включая метаданные. Если в содержимое коммита будут внесены какие-либо изменения, даже если это просто изменение сообщения коммита, хэш SHA-1 будет другим, и коммит будет считаться совершенно новым и другим коммитом.
Еще одной важной особенностью коммитов Git является то, что они могут иметь несколько родителей. Это известно как фиксация слияния, и это происходит, когда две или более ветвей объединяются вместе. Коммит слияния имеет два или более родительских коммита, каждый из которых представляет последний коммит в другой ветке.
Коммиты — неотъемлемая часть системы контроля версий Git, они позволяют разработчикам отслеживать изменения в репозитории с течением времени и сотрудничать с другими над одной кодовой базой. Используя коммиты, разработчики могут легко откатывать изменения, сравнивать разные версии кода и изолировать ошибки или проблемы, появившиеся в конкретных коммитах.
Коммиты указывают на дерево. Также содержат метаданные => автор, дата, сообщение, родительский коммит. Ша-1 это мешанина из всех этих вещей
Коммит — это моментальный снимок кода файлового репозитория в конкретный момент времени.
Почему мы не можем изменить коммит git
Мы не можем изменить коммит Git, потому что любое изменение, внесенное в коммит, изменит его хэш SHA-1, который рассчитывается на основе содержимого коммита, включая метаданные, такие как автор, дата и сообщение коммита. Поскольку хэш SHA-1 уникален для каждой фиксации, любое изменение, внесенное в фиксацию, приведет к другому хэшу SHA-1, и фиксация будет считаться совершенно новой и другой фиксацией. Это вызовет проблемы с отслеживанием и контролем версий, поэтому Git не позволяет вносить изменения в коммиты после их внесения.
Указатель на коммит
Git использует три основных типа указателей для отслеживания коммитов:
HEAD
: это указатель на текущую ветку, над которой вы работаете. Он указывает на последнюю фиксацию в этой ветке.Tags
: Тег — это простой указатель на конкретную фиксацию. Он используется для обозначения важных моментов в истории репозитория, таких как выпуск или серьезное изменение. Теги являются неизменяемыми и не могут быть перемещены или обновлены после их создания.Branches
: Ветка — это указатель на конкретную фиксацию. Используется для создания отдельной линии разработки от основной ветки. Когда вы создаете новую ветку, Git создает новый указатель на ту же фиксацию, на которую указывает текущая ветка. Когда вы вносите изменения в новую ветку, указатель перемещается, указывая на последнюю фиксацию в этой ветке.
Git позволяет переключаться между ветвями, изменяя указатель, на который указывает HEAD
. Когда вы переключаете ветки, Git обновляет файлы в вашем рабочем каталоге, чтобы они соответствовали последней фиксации в новой ветке.
В целом, указатели — это фундаментальная концепция Git, которая позволяет вам отслеживать коммиты в вашем репозитории и с легкостью переключаться между различными направлениями разработки.
Например, мы фиксируем сначала. Мастер укажет на коммит ша. Текущая голова будет указывать на текущую основную ветку.
Объекты Git: дерево, коммит и большой двоичный объект
Git — это распределенная система управления версиями, в которой для хранения данных используется файловая система с адресацией по содержимому. Git хранит данные в трех основных типах объектов: дереве, фиксации и большом двоичном объекте.
капля
Объект blob в Git представляет собой файл, который хранится как двоичный объект. Каждый объект большого двоичного объекта соответствует определенной версии файла. Содержимое объекта большого двоичного объекта адресуется уникальным хэшем SHA-1, который представляет собой шестнадцатеричную строку из 40 символов. Хэш SHA-1 рассчитывается на основе содержимого файла, поэтому, если содержимое файла изменится, хеш SHA-1 также изменится.
Дерево
Объект дерева в Git представляет каталог и содержит ссылки на большие двоичные объекты и другие деревья. Каждый объект дерева соответствует определенной версии каталога. Объект дерева содержит список записей, где каждая запись представляет файл или подкаталог. Каждая запись в объекте дерева содержит хэш SHA-1 большого двоичного объекта или другого объекта дерева, а также имя файла или каталога.
Совершить
Объект фиксации в Git представляет собой снимок репозитория в определенный момент времени. Объект фиксации содержит метаданные моментального снимка, такие как автор, дата и сообщение фиксации, а также ссылку на объект дерева, представляющий корневой каталог репозитория в данный момент времени. Объект фиксации также содержит ссылку на родительский объект фиксации, то есть фиксацию, которая произошла непосредственно перед текущей фиксацией.
Когда вы вносите изменения в файлы в репозитории и фиксируете эти изменения, Git создает новый объект фиксации, который содержит новый снимок репозитория. Новый объект фиксации указывает на объект дерева, представляющий новый корневой каталог репозитория, а также указывает на предыдущий объект фиксации в качестве своего родителя.
Как Git использует эти объекты
Git использует эти три объекта для отслеживания изменений в файлах в репозитории. Когда вы изменяете файл и фиксируете изменения, Git создает новый объект большого двоичного объекта, представляющий новую версию файла. Если вы создаете новый файл или удаляете существующий файл, Git соответственно создает или удаляет объект большого двоичного объекта.
Git также использует древовидные объекты для представления структуры каталогов репозитория. Когда вы добавляете новый файл или каталог в репозиторий, Git создает новый объект дерева, представляющий новую версию структуры каталогов. Новый объект дерева содержит ссылки на существующие объекты большого двоичного объекта и дерева, а также новые объекты большого двоичного объекта и дерева, представляющие новые файлы и каталоги.
Наконец, Git использует объекты коммитов для представления истории репозитория. Каждый объект фиксации указывает на предыдущий объект фиксации, создавая цепочку коммитов, представляющую полную историю репозитория. Сохраняя всю историю репозитория в виде серии объектов коммитов, Git позволяет легко перемещаться по истории репозитория и при необходимости отменять изменения.
В целом, использование этих трех объектов в Git позволяет эффективно и точно отслеживать изменения в файлах в репозитории, а также предоставляет полную и удобную историю репозитория.
Три области, где живет код
- Не в стадии подготовки ⇒ неотслеживаемые файлы
- Промежуточная область ⇒ файлы для фиксации
- Репозиторий ⇒ файлы, о которых знает git
Взгляд поближе ⇒ плацдарм
- чистая промежуточная область не пуста
- базовая промежуточная область имеет ту же фиксацию
Удаление файлов не означает, что мы их удаляем, мы просто заменяем ими копии текущего файла.
Git Тайник
Git stash — это мощная функция, которая позволяет вам временно сохранять незафиксированные изменения и переключаться на другую ветку или применять патч без выполнения незавершенной работы. Вот некоторые ключевые команды, связанные с Git stash, и их функции:
git stash save "message"
: эта команда сохраняет ваши незафиксированные изменения в новый тайник с необязательным сообщением с описанием изменений.git stash list
: Эта команда отображает список созданных вами тайников, показывая их индекс тайника, сообщение и ветку, из которой они были спрятаны.git stash apply stash@{n}
: Применение тайника позволяет восстановить изменения из определенного тайника обратно в ваш рабочий каталог, не удаляя его из списка тайников. Вы можете указать тайник по его индексу (например, тайник@{2}).git stash pop
: Эта команда аналогичнаgit stash apply
, но также удаляет примененный тайник из списка тайников. Он применяет изменения и автоматически восстанавливает состояние ветки до создания тайника.
Используя эти команды, вы можете удобно управлять своими незафиксированными изменениями и восстанавливать их, когда это необходимо. Например, представьте, что вы работаете над функциональной веткой, но вам нужно быстро переключиться на другую ветку, чтобы исправить срочную ошибку. Вместо фиксации незавершенных изменений вы можете спрятать их с помощью git stash save
и переключиться на ветку исправления ошибок. Как только ошибка будет устранена, вы можете вернуться в свою ветку функций и использовать git stash apply
или git stash pop
, чтобы без проблем повторно применить сохраненные изменения.
Эффективно используя Git stash, вы можете уверенно переключаться между ветвями, поддерживать порядок в кодовой базе и избегать незавершенной работы. Он предоставляет гибкое и эффективное решение для обработки временных изменений, не загромождая историю коммитов.
Ссылки, коммиты и ветки
Теги в Git
Теги в Git — это простые указатели на конкретный коммит. Они используются для обозначения важных моментов в истории репозитория, таких как выпуск или серьезное изменение. Теги являются неизменяемыми и не могут быть перемещены или обновлены после их создания. В Git есть два типа тегов: облегченные теги и аннотированные теги.
Облегченный тег — это просто указатель на конкретную фиксацию. Он создается с помощью команды git tag
, за которой следует имя тега и коммит, на который он должен указывать. Например, чтобы создать упрощенный тег с именем «v1.0», указывающий на текущую фиксацию, вы должны использовать следующую команду:
git tag v1.0
С другой стороны, аннотированный тег — это объект в Git, который содержит имя тегировщика, адрес электронной почты, дату и сообщение. Он также включает указатель на конкретную фиксацию. Аннотированные теги создаются с помощью команды git tag
с параметром -a
, за которым следует имя тега и коммит, на который он должен указывать. Например, чтобы создать аннотированный тег с именем «v1.0», который указывает на текущую фиксацию, вы должны использовать следующую команду:
git tag -a v1.0 -m "Version 1.0"
Аннотированные теги рекомендуются для создания тегов выпуска, поскольку они предоставляют больше информации о теге и коммите, на который он указывает. Они также могут быть подписаны ключом GPG для дополнительной безопасности.
Теги можно перечислить с помощью команды git tag
, а конкретный тег можно извлечь с помощью команды git checkout
, за которой следует имя тега. Например, чтобы проверить тег «v1.0», вы должны использовать следующую команду:
git checkout v1.0
Теги также можно отправить в удаленные репозитории с помощью команды git push
с параметром --tags
. Например, чтобы отправить все теги в удаленный репозиторий, вы должны использовать следующую команду:
git push --tags
Теги — это важная функция Git, которая позволяет разработчикам отмечать важные моменты в истории репозитория и легко ссылаться на них в будущем.
Указатель ветки перемещается вместе с последней добавленной фиксацией, но теги остаются с текущей фиксацией.
Headless/Detached Head и висячие коммиты
- Когда вы указываете HEAD на определенный коммит, он теперь находится в отсоединенном состоянии.
- Если вы фиксируете новые изменения в HEAD, когда он находится в отсоединенном состоянии, вам нужно что-то делать с этими коммитами, иначе они будут потеряны.
- Вы можете создать новую ветку, которая указывает на последнюю фиксацию в отсоединенном состоянии.
- Почему последний коммит → потому что коммиты тоже ссылаются на своих родителей.
- Если вы этого не сделаете, они станут висячими коммитами, т.е. отправятся на сборку мусора.
Заключительные части
В заключение, понимание внутренней работы Git дает разработчикам более глубокое понимание его эффективности, гибкости и мощности. Углубившись в его внутреннюю работу, мы раскрыли тонкости объектной модели Git, его механизма хранения и основных операций, которые делают возможным контроль версий.
Вооружившись этими знаниями, разработчики могут принимать более обоснованные решения при использовании Git, более эффективно устранять неполадки и максимально использовать его возможности. Независимо от того, являетесь ли вы новичком или опытным пользователем Git, изучение внутренней работы Git открывает новое измерение понимания и дает вам возможность стать более опытным специалистом по управлению версиями.
Итак, в следующий раз, когда вы будете коммитить, ветвить или помечать, найдите минутку, чтобы оценить запутанный танец, происходящий за кулисами — замысловатый танец, который поддерживает Git и обеспечивает совместную работу, управление версиями и беспрепятственное управление кодовыми базами. Изучите внутреннюю работу Git и откройте для себя более глубокий уровень мастерства в своем путешествии по разработке программного обеспечения. Удачного кодирования!