- Система контроля версий (Version Control System) — программное обеспечение, помогает управлять состоянием исходного кода на протяжение всей разработки.
- система, которая записывает ваши изменения в файл и позже позволяет откатиться к более ранней версии проекта. Также помогает команде эффективно работать надо одними и теми же файлами и синхронизировать свои изменения.
- бывают
распределенные
ицентрализованные
(репозиторий хранится на сервере, вносить правки можно только в него, чреез спец. клиента). GIT - распределенный
- GIT (Global Information Tracker) — разработан Линусом Торвальдсом для управления разработкой ядра Linux.
- Принцип хранения в GIT — Git хранит полные копии файлов, только заменяя неизмененные файлы на ссылки (многие другие системы хранят только список изменения)
- Т.е. Git является небольшой файловой системой.
- Преимущества подхода — при восстановлении данных, работе с комитами и т.д.
- Недостатки подхода — требует больше места.
- Repository — место, где Git хранит метаданные и базу данных объектов вашего проекта.
- Git хранит все изменения в скрытой папке
.git
, которая есть в каждом проекте, находящемся под контролем VCS.
- Git хранит все изменения в скрытой папке
- Working Directory — извлечённая из базы копия определённой версии проекта.
- Staging Area (index) — файл c информацией о том, что должно войти в следующий коммит.
- Хранится в репозитории Git
- когда я выполняю
git add .
— я добавляю данные в index/Staging Area
- Tree — объект (бинарный файл), который представляет директорию.
- Хранит ссылки к блобам и деревьям, также указывается SHA1 хэшом.
- Commit — содержит текущее состояние репозитория.
- Как и дерево или блоб, коммит хранится в виде SHA1 хэша.
- Можно понимать коммит, как узел в связном листе.
- Каждый коммит имеет указатель на своего предка-коммита.
- Коммит может имет несколько указателей на несколько предков - это значит, что он был создан слиянием веток.
- Branch — используется для создания новой ветки разработки.
- Tag — обозначает значимое имя с указанной версией в репозитории.
- Теги очень похожи на ветки, но отличие в том, что они неизменяемы. Если сделать тег для коммита, то даже если создать новый коммит от данного, то он не обновится.
- HEAD - указатель/ссылка, обычно указывает на последний комит в текущей ветке.
- Когда вы делаете комит, то HEAD перемещается на него.
- HEAD можно переместить на любой другой объект кроме комита.
ORIG_HEAD
- предыдущее состояние HEAD.- git reset - передвигает HEAD в указанное состояние
detached HEAD
— состояние открепленного указателя HEAD.- Может возникнуть при
git checkout
, если переключиться на коммит. - При стандартном процессе разработки указатель HEAD обычно указывает на главную ветку main или другую локальную ветку. Но при переключении на предыдущий коммит HEAD указывает уже не на ветку, а непосредственно на сам коммит. Такая ситуация называется состоянием «открепленного указателя HEAD». Переход к старой версии файла не перемещает указатель HEAD. Он остается в той же ветке и в том же коммите, что позволяет избежать открепления указателя HEAD. После этого можно выполнить коммит старой версии файла в новый снимок состояния, как и в случае других изменений. Соответственно, такое использование команды git checkout применительно к файлу позволяет откатиться к прежней версии отдельного файла.
- Переход к отдельному коммиту переведет репозиторий в состояние открепленного указателя HEAD. Работа при этом перестает принадлежать какой-либо из веток. При открепленном указателе HEAD все новые коммиты будут оставаться без родителя, пока вы не вернете ветки в положенное состояние. «Сборщик мусора» в Git удаляет коммиты без родителя. Этот сервис работает с определенными интервалами и удаляет такие коммиты без возможности восстановления. Чтобы такие коммиты не были удалены «сборщиком мусора», перед их выполнением нужно убедиться, что мы работаем в ветке.
- Сообщение «detached HEAD» предупреждает о том, что вся текущая работа «откреплена» от остальной части вашего проекта. Если вы начнете разрабатывать функцию, находясь в состоянии открепленного указателя HEAD, у вас не будет ветки, которая позволила бы вам вернуться к этой функции. Когда вы неизбежно переключитесь на другую ветку (например, чтобы слить код своей функции), вы уже никак не сможете сослаться на свою функцию:
- Может возникнуть при
-
git merge
— соединяет две или более истории в одну.- объединяет две или более «историй разработки». Сохраняет историю в первозданном виде
-
git rebase
— переносит локальные комиты в указанное положение в дереве.- повторно применяет коммиты поверх другой базовой ветки. Перезаписывает историю
-
git cherry-pick
— переносит изменения, представленные в указанных комитах.- Если ведется сложная история разработки, с несколькими длинными ветками разработками, может возникнуть необходимость в применении изменений, внесенных отдельным коммитом одной ветки, к дереву другой (активной в настоящий момент).
-
git reset
— передвигает HEAD в указанное состояние- позволяет откатить проект до определенной точки.
- в зависимости от параметра прокидывает нас в истории проекта с соответствующими состояниями индекса.
- можно использовать с тремя параметрами:
git reset --soft <commit>
- Содержимое вашего индекса, а также рабочей директории, остается неизменным.
- мы изменим ссылку указателя HEAD на указанный коммит и все изменения, которые были до этого внесены, окажутся в индексе.
git reset --mixed <commit>
- мы изменим ссылку указателя HEAD, но все предыдущие изменения в индекс не попадут, а будут отслеживаться как не занесенные в индекс.
- Дает возможность внести в индекс только те изменения, которые нам необходимы, что довольно удобно!
git reset --hard <commit>
- мы изменим ссылку указателя HEAD, но все предыдущие изменения не попадут ни в индекс, ни в зону отслеживаемых файлов.
- Мы полностью сотрем все изменения, которые вносили ранее.
-
git init
— создание пустого репозитория или переинициализация существующего. -
git clone
— операция клонирования репозитория. -
git add
— операция индексирования файла (сообщаю Git какие изменения надо внести в историю).- Пока я не сделал
git add
— файл считается «неотслеживаемым». Изменения в нём не попадут в следюущий коммит
- Пока я не сделал
-
git commit
— записывает изменения в репозиторий (в историю проекта). -
git status
— операция вывода статуса текущего working tree.- Показывает какие файлы в проекте отслеживаются Git и какие изменения будут включены в следующий коммит
-
git branch
— выводит, создает или удаляет ветки. -
git checkout
— переключается между элементами или откатывает изменения в файлах в рабочей директории.- подразумевают переключение между различными версиями целевого объекта (файл, коммит или ветка)
- откатывает изменения в файле.
- переходит на указанный объект, например ветку
- По сути дела просто обновляет указатель HEAD, чтобы он ссылался на указанную ветку или коммит.
detached HEAD
— состояние открепленного указателя HEAD.- Может возникнуть при
git checkout
, если переключиться на коммит. - При стандартном процессе разработки указатель HEAD обычно указывает на главную ветку main или другую локальную ветку. Но при переключении на предыдущий коммит HEAD указывает уже не на ветку, а непосредственно на сам коммит. Такая ситуация называется состоянием «открепленного указателя HEAD». Переход к старой версии файла не перемещает указатель HEAD. Он остается в той же ветке и в том же коммите, что позволяет избежать открепления указателя HEAD. После этого можно выполнить коммит старой версии файла в новый снимок состояния, как и в случае других изменений. Соответственно, такое использование команды git checkout применительно к файлу позволяет откатиться к прежней версии отдельного файла.
- Переход к отдельному коммиту переведет репозиторий в состояние открепленного указателя HEAD. Работа при этом перестает принадлежать какой-либо из веток. При открепленном указателе HEAD все новые коммиты будут оставаться без родителя, пока вы не вернете ветки в положенное состояние. «Сборщик мусора» в Git удаляет коммиты без родителя. Этот сервис работает с определенными интервалами и удаляет такие коммиты без возможности восстановления. Чтобы такие коммиты не были удалены «сборщиком мусора», перед их выполнением нужно убедиться, что мы работаем в ветке.
- Сообщение «detached HEAD» предупреждает о том, что вся текущая работа «откреплена» от остальной части вашего проекта. Если вы начнете разрабатывать функцию, находясь в состоянии открепленного указателя HEAD, у вас не будет ветки, которая позволила бы вам вернуться к этой функции. Когда вы неизбежно переключитесь на другую ветку (например, чтобы слить код своей функции), вы уже никак не сможете сослаться на свою функцию.
- Всегда ведите разработку на ветке, а не на открепленном указателе HEAD. Это гарантия того, что у вас всегда будет ссылка на ваши новые коммиты. Вместе с тем при просмотре предыдущего коммита состояние указателя HEAD не имеет значения: он может быть как откреплен, так и нет.
- Может возникнуть при
-
git stash
— прячет, достает, очищает изменения в рабочей директории. Что-то вроде «буфера обмена» -
git fetch
— загружает историю из указанного репозитория. Обновит данные только по текущему бранчу. -
git pull
— загружает историю из указанного репозитория и сливает ее с локальной историей. Только для одного бранча. То же самое чтоgit fetch
+git merge
-
git push
— загружает историю в удаленный репозиторий. -
git remote
— управляет набором отслеживаемых репозиториев. -
git remote update
— обновляет данные из удалённого репозитория по всем локальным бранчам. -
git reflog
— управляет reflog информацией.- Выводит упорядоченный список коммитов, на которые указывал HEAD. Отображает историю всех ваших перемещений по проекту.
- Хранит свою информацию на вашей машине отдельно от коммитов, поэтому при удалении чего-либо в истории, в сможете это найти в git reflog.
- Если вы вдруг случайно удалили часть истории или откатились назад, вы сможете проинспектировать момент утраты нужной вам информации и откатиться обратно.
-
git revert
— отменяет существующие комиты. -
git clean
— удаляет неиндексированные файлы из рабочей директории. -
Ссылки
-
git checkout
—- перехожу на нужный коммит (
git checkout a1e8fb5
) - создаю от него новую ветку с этими данными, работаю в ней (
git checkout -b new_branch_without_some_commit
) - Теперь репозиторий находится на новой временной шкале, где коммита 872fa7e не существует. На этом этапе мы можем продолжить работу в новой ветке, где коммита 872fa7e не существует и его можно считать «отмененным».
- К сожалению, если вам нужна предыдущая ветка (возможно, это главная ветка main), такая стратегия не подходит.
- перехожу на нужный коммит (
-
git revert
— Git создаст новый коммит с операцией, обратной последнему коммиту.- В текущую историю ветки будет добавлен новый коммит
- В отличие от нашей предыдущей стратегии переключения с помощью команды checkout, мы можем продолжить работать с этой же веткой, поэтому данная стратегия является удовлетворительной. Это идеальный способ отмены при работе в открытых общих репозиториях, однако если у вас есть требование вести минимальную «очищенную» историю Git, эта стратегия может не подойти.
-
git reset
—- Если мы выполним команду
git reset --hard a1e8fb5
, история коммитов будет сброшена до указанного коммита. - Этот метод отмены изменений оставляет историю максимально чистой.
- Отлично подходит для локальных изменений, но при работе в общем удаленном репозитории создает сложности.
- Если у нас есть общий удаленный репозиторий, в котором с помощью команды push опубликован коммит 872fa7e, и мы попытаемся выполнить команду git push для ветки, в которой с помощью команды reset была сброшена история, система Git обнаружит это и выдаст ошибку. Git будет считать, что публикуемая ветка не была обновлена, поскольку в ней отсутствуют коммиты. В таких случаях лучше использовать отмену с помощью команды git revert.
- Если мы выполним команду
-
git commit --amend
— внести правки в последний коммит -
Ссылки
-
git remote update
- Обновляет данные из удалённого репозитория по всем локальным бранчам.
- При этом локальные бранчи никак не обновляются и не меняютс
-
git fetch
(получать)- Обновляет данные только по текущему бранчу.
- Не вмержит новые изменения, если таковые были в репозитории, в локальный бранч. Локальный бранч не изменит свою историю!
-
git pull
- Обновляет данные по локальному бранчу + вмержит изменения из репозитория (если они есть).
- Равносильно выполнению
git fetch
+git merge
-
Ссылки
Merge (слияние)
- объединяет две или более историй разработки
- Сохраняет историю в первозданном виде
- на графике истории репозитория будет видна другая ветка — история нелинейная
Rebase (перебазирование)
- повторно применяет коммиты поверх другой базовой ветки.
- Перезаписывает историю
- графике истории выглядит одной линией
Способ объединить изменения, сделанные в одной ветке, с другой веткой.
Альтернатива merge
.
Последовательно берет все коммиты из выбранной ветки и заново применяет их к новой ветке.
Результат:
- Переприменяя коммиты, Git создает новые коммиты. Даже если они содержат те же изменения, то рассматриваются Git как новые и независимые коммиты.
- Git rebase переприменяет коммиты и не удаляет старые. После выполнения rebase ваши старые коммиты продолжат храниться в .git.
Отличие от merge
rebase
- повторно применяет коммиты поверх другой базовой ветки. Перезаписывает историюmerge
- объединяет две или более «историй разработки». Сохраняет историю в первозданном виде
Ссылки
-
Берём серию коммитов и «уплотняем», сжимаем ее.
-
Серию из N коммитов преобразуем в один коммит.
-
Так легче отслеживать историю Git.
-
Повзоляет превратить большое число малозначимых коммитов в небольшое число значимых.
-
Часто используют при объединении ветвей
- Многие советуют всегда сжимать коммиты и выполнять перебазирование с родительской ветвью (например, master или develop).
- В таком случае история главной ветки будет содержать только значимые коммиты, без ненужной детализации.
-
Ссылки
- Central Workflow
- Репозиторий содержит только одну главную ветку master. Все изменения комитятся в нее.
- Репозиторий может быть локальным, без удаленных копий или храниться удаленно, где он может быть клонирован или запушен.
- Developer Branch Workflow
- У каждого разработчика есть своя личная ветка или несколько, в которые он пушит. Все его изменения, опубликованные в удаленном репозитории будут в этой ветке.
- Вся работа может быть выполнена на разных ветках, но потом должна будет слита(merged) в одну главную ветвь.
- Feature Branch Workflow
- В своей простейшей форме репозиторий мог бы иметь основную ветку со стабильным, доступным кодом и другими ветками для разных фич (или багов, или улучшений), которые можно бы было интегрировать в главную ветку.
- То есть репозиторий будет иметь второстепенную основную ветку (dev) которая будет хранить тестируемый стабильный код для отправки пользователям, когда он будет слит с master.
- В этом случае ветка с фичами будет слита с dev, а не с master.
- Issue Branch Workflow
- Очень похожа на предыдущую модель с одним лишь различием. Ветки создаются из заданий в проектном трекере. Ветки могут иметь одинаковые названия id заданий. И здесь только одна ветка на задание и одно задание на ветку.
- Forking Workflow
- Благодаря этой модели, дополнения проекта осуществляются путем создания разветвления его репозитория. Все изменения фиксируются в любой ветке репозитория, а затем возвращаются в исходное хранилище с pull запросом. Разработчики будут иметь доступ только к чтению в удаленном репозитории.
- Patch Workflow
- Используя этот подход, разработчики добавляют изменения в репозиторий вместе с патчем - файлом, который содержит все изменения в репозитории. Этот патч применяется кем-то, кто может напрямую писать в репозиторий, например maintainer/owner.
- Git Flow
- Есть две фиксированные ветви, «стабильный»
master
и «развивающийся»develop
. - ветка отпочковывается от develop, если это внесение функционала или подготовка к выпуску новой версии,
- ветка отпочковывается прямо от master, если это исправление ошибки.
- После окончания работ тематическая ветвь вливается в её родителя, а в ряде случаев — и в master.
- Есть две фиксированные ветви, «стабильный»
- GitHub Flow
- То же, что и Git Flow, но фиксированная ветка всего одна — master; всё остальное принадлежит тематическим ветвям.
- Тематические ветви создаются в форках — клонированных копиях репозитория. Центральный репозиторий тематических веток не содержит. В том числе и после слияния, так как метки веток при этом снимаются и их головы становятся анонимными.
- GitLab Flow
- Как и в GitHub Flow, фиксированная ветка всего одна — master; всё остальное принадлежит тематическим ветвям. Однако, если в том случае релизы размещались в коммитах master-a, то здесь для каждого релиза создаётся своя, отдельная ветка. Причём никакого слияния этих веток с родителем не производится. Если ветка отпочковалась, значит она будет жить своей жизнью, получая исправления ошибок в виде отдельных коммитов (возможно, портированных из головы мастера с учётом накопившейся разницы в функционале между ветками).
Ссылки
-
Оригинальная статья Vincent Driessen с описанием модели GitFlow (перевод на русский)
-
atlassian.com - Магистральная разработка (Trunk based development)
- Я использую nano
Ссылки
- Ссылки
- smartiqa.ru — Курс «Работа с Git» (6 уроков, 2021)
- GIT Book (ru)
- Pro Git (ru)
- Хабр - Git. Коротко о главном
- Hexlet - Что такое Git и для чего он нужен
- GIT за полчаса
- Конспект по GIT
- Wikipedia - GIT
- GeekBrains - Git. Базовый курс (бесплатный)
- GeekBrains - Git. Базовый курс (бесплатный, YouTube)
- Хабр - Поддержание аккуратной истории в Git с помощью интерактивного rebase
- Как сжимать коммиты в Git с помощью git squash
- Habr - Git Wizardry (краткое введение в Git)
- atlassian.com - Изучите Git с помощью Bitbucket Cloud
- atlassian.com - Рабочий процесс Gitflow Workflow
- atlassian.com - Магистральная разработка (Trunk based development)
- Чёрт побери, Git!?!
*[Legmo, 2019-2023](https://github.com/Legmo/notes/)*