GIT¶
Git - распределенная система контроля версий, потому что в ней не требуется центральный сервер, у каждого разработчика локальная версия репозитория. В реальных проектах используют сервер для удобства обмена данными, сервер не выполняет никакой умной работы, это только центральный пункт обмена данными.
git-bash-prompt oh-my-zsh
Команды¶
Что куда перемещает — карта четырёх областей:
graph LR
W["Рабочая<br/>директория"] -->|git add| I["Индекс<br/>staging"]
I -->|git commit| L["Локальный<br/>репозиторий"]
L -->|git push| R["Remote"]
R -->|git fetch| L
L -->|"git switch"| W
I -->|"git restore"| W
Дальше команды по группам: заголовок — сама команда, таблица под ним — её флаги и формы.
Настройка¶
git config¶
Читает и пишет настройки. Уровень задаётся флагом, ближний перебивает дальний.
| Флаг | Область действия |
|---|---|
--system |
все пользователи машины |
--global |
текущий пользователь |
--local |
текущий репозиторий, по умолчанию |
--list |
показать, что в итоге собралось |
Репозиторий¶
git init¶
Создаёт пустой репозиторий в текущей директории.
git clone¶
git clone <url> — забирает удалённый репозиторий вместе со всей историей.
Состояние и различия¶
git status¶
Состояние рабочей директории и индекса: отслеживаемые и неотслеживаемые файлы, готовое к коммиту, состояние ветки, конфликты слияния.
| Флаг | Что делает |
|---|---|
-s, --short |
краткий формат |
-b, --branch |
ветка и её связь с удалённой |
-v, --verbose |
подробности, повторный флаг увеличивает детализацию |
--long |
полный формат, он же по умолчанию |
git diff¶
Показывает различия. Что с чем сравнивать, задаётся аргументом.
| Форма | Сравнивает |
|---|---|
git diff |
рабочую директорию с индексом |
git diff --staged |
индекс с последним коммитом, --cached — синоним |
git diff HEAD |
рабочую директорию с последним коммитом |
git diff <commit> |
рабочую директорию с указанным коммитом |
git diff <commit1> <commit2> |
два коммита |
git diff <branch1> <branch2> |
две ветки |
Индекс и коммиты¶
git add¶
git add <file> — переносит изменения из рабочей директории в индекс.
| Форма | Что добавляет |
|---|---|
git add . |
всё в текущей директории |
git add -A |
все изменения: добавления, удаления, перемещения |
git add -u |
только уже отслеживаемые файлы |
git commit¶
Фиксирует подготовленные изменения в истории.
| Флаг | Что делает |
|---|---|
-m "текст" |
сообщение без открытия редактора |
-am "текст" |
-a добавляет отслеживаемые файлы, заменяя git add . |
--amend |
переписать последний коммит: сообщение или забытые файлы |
--no-edit |
не открывать редактор для сообщения |
--date=now |
перезаписать дату |
--author="Name <email>" |
сменить автора |
--reset-author |
сбросить автора на текущего |
Ветки¶
git branch¶
Без аргументов показывает локальные ветки. С именем создаёт новую от текущего коммита, но не переключает на неё.
| Форма | Что делает |
|---|---|
git branch |
список локальных веток |
git branch <branch> |
создать ветку от текущего коммита |
git branch -d <branch> |
удалить, только если изменения куда-то слиты |
git branch -D <branch> |
удалить принудительно |
git switch и git checkout¶
Две равнозначные команды для переключения. switch появился позже и умеет только это, checkout
перегружен и делает ещё десяток вещей.
Слияние и перенос¶
git merge¶
git merge <branch> — вливает изменения указанной ветки в текущую.
git rebase¶
git rebase <branch> — переносит коммиты текущей ветки поверх указанной.
git rebase -i HEAD~3 — интерактивно по последним трём коммитам.
rebase переписывает историю
На ветке, которую уже забрал кто-то ещё, rebase и amend ломают чужие клоны: коммиты меняют
хэши. На общих ветках отменяй через git revert, историю переписывай только у себя.
git cherry-pick¶
git cherry-pick <commit> — переносит отдельный коммит из другой ветки в текущую.
| Форма | Что берёт |
|---|---|
git cherry-pick <branch>~2 |
предпоследний коммит ветки |
git cherry-pick abc1234..def5678 |
все коммиты диапазона, исключая первый |
История¶
git log¶
История коммитов.
| Флаг | Что делает |
|---|---|
--oneline |
по строке на коммит |
--graph |
ASCII-граф ветвлений |
--decorate |
показывает ветки и теги |
--pretty=format:"%h - %an, %ar : %s" |
свой формат вывода |
Читаемый граф целиком:
git log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)' --all
git show¶
git show <commit> — содержимое коммита.
| Форма | Что показывает |
|---|---|
git show abc123 |
по хэшу, хватает первых 6–7 символов |
git show HEAD~2 |
предпредпоследний коммит |
git show <branch> |
последний коммит ветки |
git show abc123..def456 |
сравнение двух коммитов |
git show 123abc:src/app.js |
файл в состоянии этого коммита |
git blame¶
git blame <file> — кто и когда последним менял каждую строку файла.
Отмена изменений¶
git revert¶
git revert <commit> — создаёт новый коммит, отменяющий указанный. Историю не переписывает,
поэтому безопасен на общих ветках.
git reset¶
git reset <commit> — перемещает текущую ветку на указанный коммит. В отличие от revert
переписывает историю: коммиты после указанного могут исчезнуть из ветки.
| Режим | HEAD | Индекс | Рабочие файлы |
|---|---|---|---|
--soft |
сброшен | сохранён | сохранены |
--mixed |
сброшен | сброшен | сохранены |
--hard |
сброшен | сброшен | сброшены |
git reset @~2 — снять последние два коммита.
Промахнулся — коммиты обычно ещё живы:
git restore¶
git restore <file> — отменяет незакоммиченные изменения в рабочих файлах, убирает файлы из
индекса, восстанавливает файлы из определённого коммита.
git clean¶
git clean -dxf — удаляет неотслеживаемые файлы из рабочей директории.
| Флаг | Что делает |
|---|---|
-n |
пробный запуск: показать, что будет удалено |
-f |
реально удалить, без флага команда не работает |
-d |
захватывать и неотслеживаемые директории |
-x |
удалять и игнорируемые файлы из .gitignore |
-X |
удалять только игнорируемые |
-i |
интерактивный режим |
reset --hard и clean -f ничего не спрашивают
--hard затирает незакоммиченные изменения, clean -f удаляет файлы мимо корзины. Перед
clean прогоняй -n: покажет список, ничего не тронув.
Удалённые репозитории¶
git remote¶
Управляет списком удалённых репозиториев.
| Форма | Что делает |
|---|---|
git remote |
список подключённых |
git remote -v |
то же самое с URL |
git remote add <name> <url> |
подключить новый |
git fetch¶
git fetch <remote> — забирает изменения с сервера, не трогая рабочую ветку.
git pull¶
git pull <remote> <branch> — fetch плюс слияние в текущую ветку.
git push¶
git push <remote> <branch> — отправляет коммиты на сервер.
git push -u <remote> <branch> — отправляет и связывает ветку с удалённой, дальше хватает
голого git push.
Сохранение временных изменений¶
git stash¶
Временно прячет незакоммиченные изменения, чтобы переключиться на другую ветку или выполнить другие операции, и возвращает их потом.
| Команда | Что делает |
|---|---|
git stash push -m "..." |
сохранить с описанием |
git stash list |
список сохранённого |
git stash pop |
вернуть последнее и удалить из stash |
git stash apply <stash> |
вернуть конкретное, оставив в stash |
git stash drop stash@{1} |
удалить конкретное |
git stash clear |
удалить всё |
Дополнительные¶
git submodule¶
| Команда | Что делает |
|---|---|
git submodule add <url> |
подключить внешний репозиторий подмодулем |
git submodule update --init --recursive |
подтянуть подмодули после клонирования |
git reflog¶
История всех перемещений HEAD, включая «удалённые» коммиты. Главный способ откатить неудачный
reset.
git bisect¶
Бинарный поиск коммита, который сломал.
git gc¶
Очистка репозитория: упаковать объекты, убрать старые.
git fsck¶
Проверка целостности репозитория.
git help¶
git help <команда> — справка по команде.
Области GIT¶
- Working directory
Файлы, которые лежат в файловой системе
- Index (в .git/index)
Содержит изменения, которые будут включены в следующий коммит.
Контролирует, какие изменения попадут в следующий коммит
- Repository (в .git) - база данных всех версий проекта
Содержит полную историю коммитов, веток, тегов
.git¶
.github¶
.gitattribute¶
Сброс кэша¶
Если .gitignore не применяется - значит есть файлы которые git уже отслеживает.
Нужно удалить файлы из индекса
Как писать хорошие коммиты¶
Источники¶
В качестве основы используется Angular Git commit Message Convention - это наиболее авторитетный источник. Все остальные вариации конвенций по коммитам ссылаются на эту.
Также достаточно авторитетным источником является conventionalcommits.org
Шаблон коммита¶
Для оформления сообщения коммита следует использовать следующий шаблон:
<type>(<scope>): <description>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
Type, scope и description вместе составляют заголовок коммита (header).
- Type - тип коммита (рефакторинг, исправление багов, новая фича и т.п.)
- Scope - область действия (где были изменения). Это может быть отдельный файл, директория или затронутая часть проекта (rendering, routing и т.д.). Не обязательно для заполнения (но желательно).
- Description - описание сути коммита. Обычно отвечает на вопрос "что было изменено/добавлено/удалено?" Например: add comment section
- Blank line - пустая строка, ей отделяется тело коммита от заголовка, и тело от футера.
- Body - не обязательно для заполнения. Здесь обычно отвечают на вопрос "Зачем были изменения?" и "Почему сделаны именно такие изменения?" (почему не стоит делать по-другому).
- Footer - не обязательно для заполнения. Может содержать информацию о критических изменениях (breaking changes), а также является местом для указания задач из бэклога, GitHub issues, тикетов, и других проблем, которые этот коммит закрывает или с которыми он связан.
Пример коммита¶
chore: drop Node 6 from testing matrix
see the issue for details on the typos fixed
BREAKING CHANGE: dropping Node 6 which hits end of life in April
closes issue #12
Примеры заголовков коммитов¶
Плохо:
Changed render method in Block
Лучше:
refactor: Changed render method in Block
Хорошо:
refactor(Block.ts): update render method
Несколько коротких правил¶
- Коммиты пишутся на английском языке.
- Заголовок коммита пишется с маленькой буквы.
- Точка в конце не ставится.
- Длина заголовка не должна превышать 100 символов, а лучше 50. Подробности коммита выносятся в тело и футер.
- Description начинается с глагола. Глагол указывается в настоящем времени, например: add, update, improve, remove (не added, updates) и тд.
Как писать коммит при Pull Request¶
- Сообщение коммита при merge PR формируется по такому же принципу как описано выше.
- В конец заголовка коммита включается номер PR в скобочках после основного сообщения. Например:
refactor(Block.ts): update render method (#67) - Все сообщения коммитов из сливаемой ветки вносятся в тело коммита.
docs(readme.md): add documentation about project (#3)
* docs(workFlow.md): fix name of developing branch
* chore(package.json): add commitlint to devDependencies
Some extra notes.
Тип коммита¶
- feat - используется при добавлении новой функциональности.
- fix - исправление багов.
- refactor - изменения кода, которые не исправляет баги и не добавляют функционал.
- chore - изменение конфигов, системы сборки, обновление зависимостей и т.д.
- test - всё, что связано с тестированием.
- style - исправление опечаток, изменение форматирования кода (переносы, отступы, точки с запятой и т.п.) без изменения смысла кода.
- docs - изменения только в документации.
Эти типы расширяют вышеописанные, но их использовать не обязательно:
- perf - изменения кода, повышающие производительность.
- build - изменения, влияющие на систему сборки или внешние зависимости (webpack, npm).
- ci - изменения в файлах конфигурации.
BREAKING CHANGE (критические изменения)¶
BREAKING CHANGE: указывается в футере и автоматически добавляется в конец заголовка. Критические изменения - это изменения, нарушающие обратную совместимость. Может быть частью коммита любого типа.
Должен начинаться с фразы BREAKING CHANGE:, за которой следует краткое изложение критического изменения, пустая
строка и подробное описание критического изменения.
Как правильно создавать ветки и вести репозиторий¶
- Git Flow
- GitLab Flow
- GitРги Flow
- Trunk-Based Development
- Forking Workflow
- Centralized Workflow