Git — это мощный инструмент для управления версиями кода, который позволяет отслеживать изменения, сохранять их и при необходимости возвращаться к предыдущим версиям проекта. Он был разработан, чтобы упростить командную работу над проектами, сохраняя историю изменений и облегчая совместную работу.
Репозиторий — это основная единица хранения данных в Git. Он содержит все файлы проекта, историю изменений, метаданные и информацию об авторах. Репозиторий может быть локальным (на вашем компьютере) или удалённым (на сервере, например, на GitHub).
Коммит — это зафиксированное состояние проекта в определённый момент времени. Он содержит изменения, внесённые в файлы, и метаданные, такие как автор и дата. Коммиты создают историю изменений, позволяя вернуться к любой предыдущей версии проекта.
Ветка — это отдельная линия разработки, позволяющая работать над разными версиями проекта параллельно. Ветки используются для разработки новых функций, исправления ошибок и экспериментов. Основная ветка обычно называется main
или master
, а дополнительные ветки создаются для конкретных задач.
Каждый коммит в Git идентифицируется уникальным хешем, который создаётся на основе содержимого коммита. Этот хеш является уникальным идентификатором коммита и позволяет однозначно его идентифицировать.
Индекс — это промежуточная область, где фиксируются изменения перед созданием коммита. Он позволяет выбирать, какие изменения будут включены в следующий коммит, предоставляя контроль над процессом фиксации изменений.
HEAD — это специальный указатель, который указывает на текущий коммит в рабочей директории. Когда Вы переключаетесь между ветками или делаете коммит, HEAD
перемещается на новый коммит. В нормальном состоянии HEAD
указывает на ветку (например, main
или feature-branch
), но он также может указывать напрямую на коммит, когда Вы находитесь в состоянии "удаленного HEAD" (detached HEAD).
ORIG_HEAD — это специальный указатель, который сохраняет состояние HEAD
перед выполнением операций, таких как merge
или rebase
. Это позволяет Вам вернуться к предыдущему состоянию после выполнения изменений, которые могли изменить структуру веток или коммитов. Например, если Вы сделали мердж и затем решили отменить его, Вы можете использовать ORIG_HEAD
для возвращения к состоянию перед слиянием.
git config --global user.name "name" # задать имя пользователя
git config --global user.email "@email.com" # задать почту пользователя
git config --list # посмотреть все настройки
git config --global user.name # посмотреть имя пользователя
git config --global user.email # посмотреть почту пользователя
git config --global alias.<name> <command> # создать глобальный алиас
git config --global core.editor <IDE> # указать IDE по умолчанию
git init # инициализировать Git репозиторий
git clone <url> # клонировать указанный репозиторий
git remote -v # показать удаленные репозитории
git remote add origin <url> # добавить удаленный репозиторий
git remote set-url origin <url> # изменить удаленный репозиторий
git fetch <origin> # получить изменения с удаленного репозитория
git pull <origin> <branch> # получить и слить изменения с веткой origin
git push <origin> <branch> # отправить изменения в удаленный репозиторий
git add <file> # проиндексировать указанный файл
git add . # проиндексировать ВСЕ файлы в текущей директории
git add -A # проиндексировать ВСЕ изменения и удаление файлов
git add -p # запустить режим добавления изменений по частям
git add -i # запустить режим добавления файлов в индекс
git commit # создать коммит с проиндексированными изменениями
git commit -m "" # создать коммит с сообщением без вызова редактора
git commit -am "" # проиндексировать и сразу закоммитить файлы с сообщением
git commit -a -m "" # проиндексировать и сразу закоммитить файлы с сообщением
git commit --amend # внести изменения в последний коммит
git commit --amend -m "" # внести изменения в последний коммит с сообщением
git commit --amend --no-edit # внести изменения в последний коммит без сообщения
git checkout <commit> # переключиться на указанный коммит
git branch # увидеть список веток
git branch <branch> # создать новую ветку с именем <branch>
git branch -m <branch> # переименовать текущую ветку в <branch>
git branch -m <branch> <branch> # переименовать ветку <branch> в <branch>
git branch -d <branch> # удалить локальную ветку <branch>, если она была слита
git branch -D <branch> # удалить локальную ветку <branch> независимо от состояния
git branch -v # список веток с последними коммитами
git branch -vv # список веток с последними коммитами и отслеживаемыми ветками
git branch --merged # показать ветки, которые слиты с текущей веткой
git branch --no-merged # показать ветки, которые НЕ слиты с текущей веткой
git branch -f <branch> <commit> # переместить <branch> на <commit>
git branch -f <branch> <branch>~2 # переместить <branch> на 2 коммита назад
git checkout <branch> # переключиться на указанную ветку <branch>
git checkout -b <branch> # создать и переключиться на ветку <branch>
git checkout -b <branch> <commit> # создать ветку <branch> на основе <commit> и переключиться на неё
git push --set-upstream origin <branch> # выслать <branch> на удаленный репозиторий
git push origin --delete <branch> # удалить <branch> на удаленном репозитории
git merge-base <commit> <commit> # найти общий базовый коммит для двух веток
git merge <branch> # слить ветку <branch> в текущую
git merge --abort # прервать процесс слияния ветки
git merge --no-edit # слить ветку без редактора сообщения
git merge --no-commit # без автоматического создания коммита
git merge --squash # без слияния истории; как один коммит
git revert <commit> # создать коммит, отменяющий <commit>
git revert --no-commit <commit> # отменить <commit> без нового коммита
git revert --abort # отменить не законченную операцию revert
git rebase <branch> # rebase (перенос коммитов) текущей ветки на указанную
git rebase --abort # прервать rebase и вернуть ветку в исходное состояние
git rebase --continue # продолжить процесс rebase после разрешения конфликта
git rebase --skip # пропустить <commit> с конфликтом и продолжить rebase
git cherry-pick <commit> # скопировать изменения из <commit> в текущую ветку
git cherry-pick --edit <commit> # скопировать изменения из <commit> с изменением сообщения
git cherry-pick --no-commit <commit> # скопировать изменения из <commit> без создания <commit>
git cherry-pick --abort # отменить операцию cherry-pick, если она была прервана
git cherry-pick --continue # продолжить операцию cherry-pick после разрешения конфликта
git stash # временно сохранить изменения из файла
git stash list # посмотреть список сохраненных изменений
git stash apply # применить последнее сохраненное изменение
git stash drop # удалить последнее сохраненное изменение
git stash apply <stash> # применить конкретное сохраненное изменение
git stash branch <branch> # создать <branch> и применить изменения из стэша
git stash pop # применить и удалить последнее сохраненное изменение
git checkout -- <file> # отменить НЕПРОИНДЕКСИРОВАННЫЕ изменения в <file>
# Ниже ОБЯЗАТЕЛЬНО указать тот же файл, на котором Вы находитесь:
git checkout -f <file> # отменить НЕПРОИНДЕКСИРОВАННЫЕ изменения в <file>
# Делает то же, что и две команды выше (один из способов):
git checkout -f HEAD # отменить НЕПРОИНДЕКСИРОВАННЫЕ изменения в <file>
# Делает то же, что и три команды выше (один из способов):
git checkout -f # отменить НЕПРОИНДЕКСИРОВАННЫЕ изменения в <file>
git reset <file> # вытянуть из индекса <file> с сохранением изменений
git reset --soft HEAD^1 # откатить изменения с сохранением их в индексе
git reset --hard HEAD^1 # откатить изменения и удалить их из директории
git clean -f # удалить все неотслеживаемые файлы
git clean -fd # удалить все неотслеживаемые файлы и папки
mv <file> <file> # переименовать <file> и проиндексировать
Пример: mv old.txt new.txt
mv <directory> <directory> # переименовать <directory> и проиндексировать
Пример: mv olddir newdir
mv <file> <directory> # переместить <file> в указанную <directory>
Пример: mv dev.txt /home/user/docs/
mv <directory> <directory> # переместить <directory> в другую <directory>
Пример: mv project /home/user/test/
rm <file> # удалить отслеживаемый <file> и проиндексировать
rm -f <file> # удалить отслеживаемый <file> принудительно и проиндексировать
rm -i <file> # удалить отслеживаемый <file> с подтверждением и проиндексировать
rm -r <directory> # удалить <directory> и её содержимое и проиндексировать
rm -r -f <directory> # удалить <directory> и её содержимое принудительно и проиндексировать
rm -r -i <directory> # удалить <directory> и её содержимое с подтверждением и проиндексировать
git tag # посмотреть список тегов
git tag "" # создать тег с сообщением
git tag -d <tag> # удалить локальный <tag>
git tag -a "" -m "" # создать аннотированный тег
git show <tag> # показать информацию о <tag>
git push origin <tag> # отправить <tag> на удаленный репозиторий
git push origin --tags # отправить теги на удаленный репозиторий
git push --delete origin <tag> # удалить <tag> на удаленном репозитории
git status # узнать текущее состояние репозитория
git status --short # узнать краткое состояние репозитория
git log # история коммитов текущей ветки
git log --graph # история коммитов в виде графа с коммитами
git log --oneline # история коммитов в одну строку на коммит
git log --oneline --first-parent # история коммитов по 1-ой родительской ветке
git log -p <file> # история коммитов с изменениями для <file>
git log -p -5 <file> # последние 5 коммитов с изменениями для <file>
git log -p -20 # последние 20 коммитов с подробными изменениями
git log -2 # показать последние 2 коммита
git log -2 --stat # показать последние 2 коммита со статистикой изменений
git log --graph -10 # показать последние 10 коммитов в виде графа
git log --since=2.weeks # показать коммиты за последние 2 недели
git diff # показать изменения относительно последнего коммита
git diff --staged # показать изменения, добавленные в индекс
git diff --cached # показать изменения, добавленные в индекс
git diff <commit> # показать изменения относительно указанного коммита
git diff <commit> <commit> # показать изменения между двумя указанными коммитами
git diff <commit> <file> # показать изменения между коммитом и текущей версией
git reflog # показать историю перемещений HEAD
git shortlog # краткий журнал коммитов по авторам
git blame <file> # показать автора каждой строки файла
git show <commit> # показать изменения в указанном коммите
git log --grep="<message>" # показать коммиты с определённым сообщением
git log --author="<author>" # показать коммиты лишь от указанного автора
cd <path> # перейти в указанную папку
cd .. # перейти в папку, которая уровнем выше
dir # показать папки и файлы в текущей папке
del <file> # удалить указанный файл
mkdir <folder> # создать папку с именем <folder>
ren <old_name> <new_name> # переименовать <file> или <folder>
copy <source> <destination> # скопировать файлы из <source> в <destination>
move <source> <destination> # переместить файлы из <source> в <destination>
password.txt # игнорировать файл с названием password.txt
images/ # игнорировать содержимое папки и саму папку
*.html # игнорировать все файлы с расширением .html
temp* # игнорировать файлы и папки, начинающиеся с temp
.* # игнорировать скрытые файлы и папки (начинаются с .)
/* # (1..) ЭТО НАЧАЛО КОМАНДЫ НИЖЕ (ПИСАТЬ В 2 СТРОКИ)
!alert.js # (..2) игнорировать файлы в корне, КРОМЕ alert.js
Надо перейти на другую ветку и имеются незакомиченные изменения, а при вводе команды git checkout <branch>
высвечивается ошибка.
Для решения проблемы есть команда git checkout -f <branch>
. При указании флага -f
осуществится переход на указанную ветку. Если написанный незакомиченный код нам не нужен, прописываем команду с флагом -f
.
Бывают случаи, когда код нужен. Есть два варианта: либо git commit
(но недоделанный код сохранять не стоит), либо воспользоваться git stash
.
git checkout -f <branch> # переходим принудительно на <branch>
Мы находимся на ветке <branch-1>
, хотим добавить небольшое изменение и через время понимаем, что это незакомиченное изменение требует разработки в отдельной ветке.
Для решения проблемы можно сразу же создать, например, <branch-2>
, а вторым действием создать коммит в новой ветке. (Переносим незакомиченный код в новосозданную ветку)
git checkout -b <branch> # переходим на <branch>
git add . # индексируем все файлы
git commit -m "" # создаем новый коммит
Мы находимся на ветке <branch-1>
, хотим добавить небольшое изменение и через время понимаем, что это закомиченное изменение требует разработки в отдельной ветке.
Для решения проблемы можно создать новую ветку, например, <branch-2>
на текущем коммите, затем передвинуть <branch-1>
на несколько коммитов назад с помощью команды git branch <branch-1> <commit>
. (Нюанс ниже)
Здесь есть два варианта события:
Если мы пропишем git branch <branch-1> <commit>
, но ветка <branch-1>
уже существует, Git высветит ошибку. Для этого нужна команда с флагом -f
.
git branch <branch-2> # создаем <branch-2> обычным способом
git checkout <branch-2> # переходим на ветку <branch-2>
git branch -f <branch-1> <commit> # переносим принудительно ветку <branch-1> на <commit>
Если мы пропишем git branch <branch-1> <commit>
и ветка <branch-1>
не существовала до этого момента, Git создаст новую ветку самостоятельно и перенесет её.
git branch <branch-2> # создаем <branch-2> обычным способом
git branch <branch-1> <commit> # переносим ветку <branch-1> на <commit>
Только что было сделано слияние ветки <branch-1>
с <branch-2>
через метод "fast-forward", но мы передумали сливать и приняли решение вернуть всё назад.
В данный момент ветки <branch-1>
, <branch-2>
находятся на одном и том же коммите.
Для решения проблемы нам понадобится команда git branch -f <branch-1> <commit>
.
Если вдруг мы не знаем коммит, на котором до слияния была ветка <branch-1>
, нужно написать вместо <commit>
указатель ORIG_HEAD
. После команды merge
Git записывает старый коммит в файл директории .git/ORIG_HEAD
, поэтому можем прописать cat .git/ORIG_HEAD
для выяснения хеша коммита, который был изначально до команды merge
(слияния).
Теперь у нас есть 2 способа написать команду git branch -f <branch-1> <commit>
:
git branch -f <branch-1> d9e7d67
- через указание хеша коммитаgit branch -f <branch-1> ORIG_HEAD
- через указание ORIG_HEAD
Итак, для отмены слияния веток нам нужно прописать:
git branch -f <branch-1> ORIG_HEAD # переносим ветку <branch-1> на ORIG_HEAD
git checkout <branch-1> # переходим на ветку <branch-1>
Командой git checkout <branch-1>
проверили, что все отлично.
Если после отмены слияния нам захотелось перенести ветку обратно туда же, куда мы раньше её и сливали, тогда прописываем git checkout -B <branch-1> <branch-2>
.
У нас была ветка <branch-2>
, которая ответвлялась от <branch-1>
. Через команду git branch -D <branch-2>
мы её удалили. Как теперь вернуть ветку обратно?
Если команда выше была введена только что, то Git удалил ветку только визуально. В системе ветка и её коммиты еще некоторое время хранятся, и если оказалось, что ветка нам была нужна, то отменяем её удаление командой git branch <branch-2> <commit>
. Можно считать, что мы создали заново ветку, которую удалили.
В <commit>
важно указать "вершину" ветки (последний коммит ветки) до слияния.
git branch -D <branch-2> # принудительно удаляем <branch-2>
# В этот момент мы осознали, что ветка нужна и её надо восстановить
git branch <branch-2> <commit> # пересоздаем ветку, указав её вершину
Перед git push
стоит проверить проект на изменения с помощью команды git fetch origin
. Если Ваши коллеги не вносили никаких изменений, спокойно отправляем свои изменения на удаленный репозиторий.
Если после команды git fetch origin
увидели изменения, то Вы находитесь в состоянии, когда локальная ветка отстает от удаленной (например, origin/main
). Если отстает ветка main
, переходим на нее и прописываем git merge origin/main
.
Если Вы и Ваш коллега работаете над одной веткой, вместо git pull
лучше будет использовать команду с флагом git pull --rebase
. При выполнении этой команды Git сначала загружает изменения из удаленной ветки, а затем "переписывает" вашу локальную ветку, помещая ваши изменения поверх загрузки.
Этот совет может помочь сохранить более линейную историю коммитов в проекте.
Представим ситуацию: Вы прописали git pull --rebase
и Git уведомил Вас о том, что изменения не могут быть автоматически объединены. В этом случае необходимо предпринять дополнительные шаги.
- Отмена команды
--rebase
Чтобы выйти из состояния конфликта и отменить текущий процесс rebase
, введите команду git rebase --abort
. Эта команда вернет вашу ветку в состояние до начала rebase
.
- Попытка обычного
git pull
После отмены rebase
стоит попробовать выполнить обычный git pull
, который автоматически выполнит слияние. В этом случае конфликты тоже могут возникнуть, но процесс слияния может быть проще для разрешения.
Если же процесс git pull --rebase
произошел без каких-либо конфликтов, Вам повезло, изменения успешно интегрированы. Продолжайте работать над проектом.
Conventional Commits (Стандартизированные коммиты) — это соглашение о формате сообщений коммитов в системах контроля версий. Соглашение задает стандарты для структурирования сообщений коммитов таким образом, чтобы история изменений была более понятной и унифицированной.
<type>(<optional scope>): <description>
feat
– Новая функция
Используется для добавления новой функциональности в проект. Коммит может повлиять на версию проекта (например, повышение версии до minor).
Пример: feat(auth): добавлена поддержка двухфакторной аутентификации
fix
– Исправление ошибки
Применяется для исправления багов и ошибок в проекте. Коммит может вызвать повышение версии patch (например, v1.0.1).
Пример: fix(login): исправлена ошибка при вводе неправильного пароля
docs
– Документация
Коммит, касающийся изменений в документации, таких как README-файлы, комментарии в коде и другие документы, которые не влияют на исходный код.
Пример: docs(readme): обновлено описание установки проекта
style
– Стиль
Изменение, связанное со стилем кода, который не влияет на функциональность (например, исправление отступов, пробелов, форматирования, и т.д.).
Пример: style: исправлено форматирование кода в модуле
refactor
– Рефакторинг
Изменение структуры кода без изменения его поведения. Этот тип используется, когда необходимо улучшить внутреннюю архитектуру или логику кода без добавления новых функций или исправления багов.
Пример: refactor: переработана логика авторизации
perf
– Производительность
Оптимизация, улучшающая производительность кода. Изменение направлено на ускорение работы приложения.
Пример: perf: значительно ускорена загрузка страниц
test
– Тесты
Коммит, связанный с добавлением или обновлением тестов, таких как модульные тесты, интеграционные тесты и т.д.
Пример: test(auth): добавлены тесты для регистрации
chore
– Обслуживание
Вспомогательная задача, не влияющая на код приложения напрямую, такие как обновление зависимостей, конфигурационных файлов и другие задачи обслуживания проекта.
Пример: chore: обновлены зависимости проекта
build
– Сборка
Изменение, связанное с процессом сборки проекта, такие как изменения в файлах сборки, настройках сборки или инструментах сборки.
Пример: build: обновлена конфигурация Webpack
ci
– Непрерывная интеграция (CI)
Коммит, связанный с настройками систем непрерывной интеграции и доставки (CI/CD), такими как изменения в конфигурации Jenkins, GitHub Actions и других системах.
Пример: ci: настроен автоматический деплой на сервер
revert
– Откат изменений
Используется для отмены предыдущего коммита. Этот тип коммита делает обратные изменения к тому, что было сделано ранее.
Пример: revert: откат коммита с ошибкой в расчетах
release
– Релиз
Коммит, связанный с подготовкой к выпуску новой версии проекта, такие как обновление номера версии или генерация журнала изменений.
Пример: release: подготовка к выпуску версии 1.2.0
security
– Безопасность
Коммит, направленный на исправление уязвимостей в безопасности.
Пример: security: исправлена уязвимость в авторизации
add
– Добавление
Добавление нового элемента или компонента в проект. Может использоваться в качестве альтернативы feat
.
Пример: add: добавлена страница настроек пользователя
remove
– Удаление
Удаление функциональности или файлов из проекта.
Пример: remove: удален устаревший модуль авторизации
include
– Включение
Включение новых файлов или ресурсов в проект. Иногда используется вместо feat
.
Пример: include: добавлены файлы шрифтов в проект
Надеюсь, что данный справочник станет полезным ресурсом в вашем арсенале разработчика и облегчит взаимодействие с Git. Для быстрого получения доступа к репозиторию обязательно добавляйте его в ⭐!