https://training.github.com/downloads/ru/github-git-cheat-sheet/
Настройка информации о пользователе для всех локальных репозиториев
git config --global user.name "[имя]"
Устанавливает имя, которое будет отображаться в поле автора у выполняемых вами коммитов
git config --global user.email "[адрес электронной почты]"
Устанавливает адрес электронной почты, который будет отображаться в информации о выполняемых вами коммитах
Создание нового репозитория или получение его по существующему URL-адресу
git init [название проекта]
Создаёт новый локальный репозиторий с заданным именем
$ git clone [url-адрес]
Скачивает репозиторий вместе со всей его историей изменений
Перемещение и удаление версий файлов репозитория
git rm [файл]
Удаляет конкретный файл из рабочей директории и индексирует его удаление
git rm --cached [файл]
Убирает конкретный файл из контроля версий, но физически оставляет его на своём месте
git mv [оригинальный файл] [новое имя]
Перемещает и переименовывает указанный файл, сразу индексируя его для последующего коммита
Исключение временных и вторичных файлов и директорий.
Для исключения файлов из системы гит (чтобы она не проверяла в них на предмет изменений) надо добавить следующие строчки в файл .gitignore
(в корневом каталоге).
_.log
build/
temp-_
Git будет игнорировать файлы и директории, перечисленные в файле .gitignore с помощью wildcard синтаксиса
git ls-files --others --ignored --exclude-standard
Список всех игнорируемых файлов в текущем проекте
Сохранение и восстановление незавершённых изменений
git stash
Временно сохраняет все незафиксированные изменения отслеживаемых файлов
git stash pop
Восстанавливает состояние ранее сохранённых версий файлов
git stash list
Выводит список всех временных сохранений
git stash drop
Сбрасывает последние временно сохранённыe изменения
Просмотр изменений и создание коммитов (фиксация изменений)
git status
Перечисляет все новые или изменённые файлы, которые нуждаются в фиксации
git diff
Показывает различия по внесённым изменениям в ещё не проиндексированных файлах
git add [файл]
Индексирует указанный файл для последующего коммита
git diff --staged
Показывает различия между проиндексированной и последней зафиксированной версиями файлов
git reset [файл]
Отменяет индексацию указанного файла, при этом сохраняет его содержимое
git commit -m "[сообщение с описанием]"
Фиксирует проиндексированные изменения и сохраняет их в историю версий
Именованные серии коммитов и соединение результатов работы
git branch
Список именованных веток коммитов с указанием выбранной ветки
git branch [имя ветки]
Создаёт новую ветку
bash
git switch -c [имя ветки]
Переключается на выбранную ветку и обновляет рабочую директорию до её состояния
```bash
git merge [имя ветки]
Вносит изменения указанной ветки в текущую ветку
git branch -d [имя ветки]
Удаляет выбранную ветку
Просмотр и изучение истории изменений файлов проекта
git log
История коммитов для текущей ветки
git log --follow [файл]
История изменений конкретного файла, включая его переименование
git diff [первая ветка]...[вторая ветка]
Показывает разницу между содержанием коммитов двух веток
git show [коммит]
Выводит информацию и показывает изменения в выбранном коммите
Удаление ошибок и корректировка созданной истории
$ git reset [коммит]
Отменяет все коммиты после заданного, оставляя все изменения в рабочей директории
$ git reset --hard [коммит]
Сбрасывает всю историю вместе с состоянием рабочей директории до указанного коммита.
Регистрация удалённого репозитория и обмен изменениями
git fetch [удалённый репозиторий]
Скачивает всю историю из удалённого репозитория
git merge [удалённый репозиторий]/[ветка]
Вносит изменения из ветки удалённого репозитория в текущую ветку локального репозитория
git push [удалённый репозиторий] [ветка]
Загружает все изменения локальной ветки в удалённый репозиторий
git pull
Загружает историю из удалённого репозитория и объединяет её с локальной. pull = fetch + merge
https://github.com/rolling-scopes-school/docs/blob/master/docs/git-convention.md
- Названия коммитов должны быть согласно гайдлайну
- Тип коммита должен быть только в нижнием регистре (
feat
,fix
,refactor
,docs
и т.д.) - Должен использоваться present tense ("add feature" not "added feature")
- Должен использоваться imperative mood ("move cursor to..." not "moves cursor to...")
init:
- используется для начала проекта/таска. Примеры:
init: start youtube-task
init: start mentor-dashboard task
feat:
- это реализованная новая функциональность из технического задания (добавил поддержку зумирования, добавил footer, добавил карточку продукта). Примеры:
feat: add basic page layout
feat: implement search box
feat: implement request to youtube API
feat: implement swipe for horizontal list
feat: add additional navigation button
feat: add banner
feat: add social links
feat: add physical security section
feat: add real social icons
fix:
- исправил ошибку в ранее реализованной функциональности. Примеры:
fix: implement correct loading data from youtube
fix: change layout for video items to fix bugs
fix: relayout header for firefox
fix: adjust social links for mobile
refactor:
- новой функциональности не добавлял / поведения не менял. Файлы в другие места положил, удалил, добавил. Изменил форматирование кода (white-space, formatting, missing semi-colons, etc). Улучшил алгоритм, без изменения функциональности. Примеры:
refactor: change structure of the project
refactor: rename vars for better readability
refactor: apply eslint
refactor: apply prettier
docs:
- используется при работе с документацией/readme проекта. Примеры:
docs: update readme with additional information
docs: update description of run() method
Можно ли ревертнуть отправленный (запушенный) в репозиторий коммит без снижения оценки?
Да, можно.
Структура папок
./hooks/
- события на которые можно настроить события (например прогон линтеров при ошибках)../info/
- может содержать файлexclude
, который является гиперлокальный амналогом.gitignore
./objects/
- сохраняются все почти все объекты, которые нужны для сохранения соcтояния кода. Коммиты, блобы и т.д../refs/
-heads/
- веткиtags/
- тегиremotes/
- ветки слежения, которые показывают в каком состоянии был удаленный репозиторий, когда за ним следили крайний раз
config
- настройкиdescription
HEAD
- указательHEAD
, который указаывает на место, с которого будет продолжена история
Blob = big binary object - большой бинарный объект. В блобы гит превращает файлы ск оторыми мы ряботает.
Tree - дерево объектов. Содержит ссылки либо на деревья объектов, либо на блобы. Отвечает за состояние файлов.
Данная команда показывает тип обхекта по его хэшу
git cat-file -t <hash>
Данная команда вывоидит содержимое объекта по его хэшу
git cat-file -p <hash>
Таким образом можно просмотреть тип и содержание каждого коммита. В дерево объектов будут храниться или деревья или блобы, блобы хранить в сжатом ввиде файл.
Это снимок состояния файлов с неокторой метаинформацией. Каждый коммит, кроме первого указывает на родителя Обычно состоит из 7 элементов:
- ссылка на родителя
- ссылка на дерево объектов, которые входят в состояние коммита
- собственный хэш (на основе дерева объектов)
- автор и комиттер
- метка времени
- сообщение
Логически ветка - последовательность коммитов. Но коммит ничего не знает в какой он ветке. Ветка реализуется как ссылка на последний коммит.
Ветки хранятся в папке ./refs/heads
каждая в виде отдельного файла. В этом файле записпн коммит на который ссылкается каждая ветка (последний).
Это удобные переменные, которые указывают на определенные коммиты. Гит использует хэши.
Основной указатель HEAD
указывает на то место, с которого будет продолжена история коммитов. HEAD в большинстве случаев и в нормальном состоянии указывает не на конкретный коммит, а на ветку, а веткка в свою очередь, есть указатель на последний коммит.
HEAD
показывает на то место, в котором мы сейчас находимся.
При смене указателя HEAD
на другой коммит (например смене ветки) указатель HEAD
переместится на тот коммит и рабочий код каталоге с гитом ихменится.
HEAD
хранится в файле ./git/HEAD
и в нем указана ссылка ref: на файл с хэшом каммита.
Тэги - это статичные указатели на определенный коммит. Их можно использовать для личных нужд, чтобы помечать определенные версии программы, ключевые моменты разработки. Они нужны для удобства, чтобы не запоминать хэш отдельного коммита. Тэги могут быть:
- легковесными - есть только название
- аннотированными - можно писать дополнительную информацию как у коммита
Место хранения кода с историей всех изменений. Может быть:
- локальный
- удаленный - может быть как gitub, gitlb, друго сервис, репозиторий коллеги или соседней папкой.
Файлы в гите могут находиться в двух глобальных состояниях: они могут быть отслеживаемые и могут быть неотслеживаемыми. Гит знает про существование неостжеиваемых файлов в рабочей директории, но изменения рабочий файлов никак не затрагивают внутреннего сотсояния гита. Отслеживаемые файлы могут получиться несколькими путями:
- были неотлежвиваемыми и добавлены в индекс пользователем - стенут отслеживаемыми при коммите
- были отслеживаемыми раньше и модифицированы
Отслеживаемые файлы огут находиться в трех состояниях:
- неизмнененные
- измененные
- staged - подготовленные к внесению ихменений в след коммите
- stash - заначка (при помещении заначку)
Index в гите - это черновик будущего коммита. По умолчанию гит не сохраняет все изменения, которые делает пользователь.
Гит работает с тремя областями или деревьями:
- Рабочая директория - песочница с текущими файлами
- Индекс - черновик коммита
- HEAD - указатель на историю коммитов
git checkout -b feature_1
- создать ветку с именем feature_1 и установить на нее указатель HEAD
git checkout -b feature_2 main
- создать ветку от указателя main. Можно также передать хэш коммита, вместо указателя.
git remote add origin <remote_rep_address>
- добавить удаленный репозиторий под именем origin
git --set-upstream origin main
- установить как ветку загрузки для удаленного репозитория main
git branch --all
- просмотреть все ветки, включая и из удаленных репозиториев
git push -u origin --all
- как git push --set-upstream origin --all
- установить все ветки как синхронихируемые с удаленным репозиторием и выгрузить их.
В файл config
добавятся аналогичные записи для этих настроек - связи с удаленными репозиториями и списки связей для локальных и ветвей и удаленного репозитория.
По умолчаниюю при клонировании репозитория, клонируетс одна ветка, а остальные остаются удаленном репозитории. Для просмотер списка веток можно восползовться командой git branch --all
. Для создания локальной версии ветки с удаленного репозитория надо выполнить команду git checkout <имя удаленной ветки>
.
git pull
= git fetch
+ git merge
* - глобальными настройками используется. Можно изменять флагами на rebase.
git fetch
- забирвет все изменения
Рекомендуется отдельноисползовать команду git fetch
чтобы заняться решением конфликтов когда будет время.
Сама структура веток предполагает объединение в будущем.
Гит предлагает две стратегии объединения.
- Merge - слияние.
- выбирает последний коммит в каждой сливаемой ветке и создает на их основе merge-commit, который будет содаржать объединенное состояние. Возможно надо будет решать конфликты. После рзрашения создасться коммит и на него передвинется указатель ветвки в которой мы нахоились. Почти всегда при merge создается один дополнительный коммит. Особый случай merge - fast forward. - если во влиаемой ветке на было изменений с момента форка их нее и все коммиты из ветки просто переносятся в другую ветку. Таким образом нового коммита не возникает. Сожно отменить и гит будет создавать фиктивный коммит Сохраняет историю коммитов. Идеально подходит для публичных репо, где важна соанность истории.
- Rebase
ребеиз из двх веток.
- количество коммитов отличается при rebase и при merge. В случае merge он такое же, что и было до marge. История коммитов исзменяется. Нету лшних коммитов слияния.
- чаще синзронизируйтесь с репозиторием с которым работаете - перенос конфликтов на более ранний уровень
- не трогайте чужой код - лучше обсудите с коллегами, а потом решайте кто в какие ветки внесет в изменения
- лучше делайте селкие коммиты - проще перемещаться между ниими и в случае rebase они будут требовать меньше внимания
- разделяйте задачи так, чтобы они не качались обзего кода
git merge <имя ветки>
- слить текущую ветку с целевой и передвинуть указатель на новый коммит слияния.
git merge --abort
- прервать процесс слияния
Конфликты при merge
и при rebase
чаще всего отличаются.
Rebase
- итеративная операция. Каждый коммит, который мы переносим при rebase
, может создать потенциальные конфликты.
В процессе ребейза может создаться несколько конфликтов на каждой итерации. Надо их разрешить (в файлах), добавить файл с разрешенным конфликтом в индекс комнадой git add
и перейтина следующую итерацию комнадой git rebase --continue
.
Бывают ситуации, когда нельзя коммитить, но надо переключиться на следующую заачу. Тогда на помощь приходит Stash
. Stash - "заначка".
git stash
При выполнении этой команды
- все изменения помещяются в состояние stash,
- индекс приводится к сотсоянию последнего коммита (как при
git reset
)- очищается - все изменения из рабочей директории передйут в специальный коммит, на который указывает указатель
stash
, - рабочая дректория откатится к состоянию при последнем коммите
После выполнения внеплановой задачи можно при помози команды
git stash apply
перенести все изменения из stash в рабочую директорию, а stash очистится.
Лучшая драка - это та, которой удалось избежать.
Файлы, которые есть в игноре не отслеживаются гитом.
.gitigore
- глобальный.gitignore
- в репозитории./.git/info/excude
- на уровне текущего локального репозитория Если быть более точным, то кроме отслеживаемых и неотслеживаемых файлов есть еще и игнорируемый файлы. Игнорируемые файлы могут обаховаться если новый файл был создан и он попал под маску gitignore. Но уже закомичееные файлы не могут стать игнорируемыми! Поэтому любые добавления закомиченных файлов в гитигнор не распространаются на них. Надо удалить файл и
- Добавляем файлы в .gitignore
- Удаляем файл их кэша гита
git rm --cache file
- Коммитим изменения без файла
git add .gitingore
,git commit -m "new commit"
Таким образом файл уже не будет отслеживаемым и будет игнорироваться через gitignore.
- поменять пароли токены
- добавить в .gitignore
- очистить историю (не поможет, но будет не так стыдно (не факт))
Если это было в последем коммите репозитория, внести изменения в рабочую директорию и выполнить командуgit commit --amend
.
После изменения коммита при помощи команды git commit --amend
гит создаст нвый коммит, который будет видоизменным предыдущим коммитом, но уже без секретный файлов. И уже новый измененный коммит будет ссылатьс на ноду, куда ссылался неимененный коммит. Но надо помнить, что неправльный коммит не удалится из дерева коммитов гита, просто на него не будет ссылок. Поэтому надо задуматься над тем какие использовать инструмаенты для очистки дерева гита.
Интерактивный ребейз
git rebase -i <хэш коммита с которого перебазируемся>
Затем можно вбрать какие комиты оставить, какие удалить, поменять мествми. Например удалить коммит с паролем. Тогда перепишется история и коммит с паролем пропадет из истории.
Но пароль все еще можно достать из git! Он сохранен в коммите, в который можно получить доступ если знать его хэш. Ну или просто найти его в объектах.
Хэш можно узнать через git reflog
.
Есть несколько операция которые риводят к безвозвратным изменениям. Все остальные команды не удалют никакие объекты. И скорее всего эти именения можно вернуть. Если же изменения не были заккомичены, то их потерять легко
git pul -f
- изменения применяются к нашей рабочей директорииgit reset
(git reset --hard) - откат изменений к какому-то конкретному коммитуgit checkout -f
git switch -f
- переключение на другую ветку в результате чего состояние рабочей директории приводится в стостояние той ветки.git clean -f
- очищает рабочую директорию от всех неотслеживаемых файлов
Выполняйте команду git status
. Закомиттьте или засташьте.
Бывает что мы закоммитили, а потом передвинули указатель ветки и потеряли связь с прежним состоянием после очередного коммита. Коммит все ещё останется в гите, но мы не увидим его через команду git log
.
git reflog
- логи гитаgit fsch --full
Логи гита отдельно собираются для каждой ветки в папке ./git/logs/refs
. Если удалить папку логов ./git/logs
, то и команда git reflog
ничего не выдаст.
В таком случае можно использовать git fsck --full
- она проверить весь репозиторий с учтетом того, чтобы на все объекты были ссылки и выдаст список коммитов, на которые нет ссылок.
Чтобы отменить коммит можно воспользоватьс командой
git revert <хэш коммита>
после которой гит создаст патч к текущему коммиту, отменяющий изменения того коммита, который был указан. Например мы можем отменить какую-то отдельную фичу из отдельного коммита, в котором была обнаружена ощибка.
- откад до состояния в предыдущем коммите
git checkout -- <file>
git restore <file>
- откад состояния файла до конкретного коммита
git restore --source=<hash> <file>
git reset
git reset --soft
- отмена изменений только с помощью указатедя HEAD. Т.е. только передвинется указатель на указанный коммит. А в индексе и в рабочей директории файлы будут все ещё соотвествовать коммиту с которого мы откатывались.git reset
git reset --mixed
- удаляет данные из индекса до того состояния и передвигвает указатель HEADgit reset --hard
- изменяетс все три области (рабочую директорию, индекс и HEAD)
git
Инициализирует git
в текущей директории и создает директорию .git
с настройками и индексами git
'a.
git init
Добавляем все измененные файлы в git
.
Игнорирует содержимое файла .gitignore
git add --all
Добавляем файл к индексу.
git add <имя_файла>
.gitignore
- специальный файл, содержимое которого будет игнорироваться системой git
при проверки изменений.
Например
./venv/
.env
Первая строка говорит системе git
игнорировать директорию venv
в корне проекта, а вторая строка - игнорировать скрытый файл .env
.
Сказать дотнету добавить все файлы в гитигнор, которе не нужны(нужно для .NET, кто знает, те поймут, остальным не нужно=):
dotnet add gitignore
Фиксация изменений.
Открывается редактор по-умолчанию для написания комментария коммита:
git commit -a
Внесение изменений с указанием коментария и без открытия редактораq:
git commit -m "init: start project git-tutorial"
Показывает разницу между файлами
git diff [с чем сравнить]
Сравнить можно, например с каким-ть коммитом, унав его id из git log
.
+ стоят у того что добавляется
- стоят у того что убирается в текущей версии по сравнению с камитом
Позволяет вывести список всех комитов.
git log
Cписок камитов и отношения между вевями в виде графа:
git log --graph
Просмотреть все коммиты во всех ветках:
git log --oneline --all
Появилась в последних версиях git
Показывает всю историю и ветки, что происходила и когда ветка была главной.
Сочетая git reflog
и git diff ID
можно просмотреть разницу между камитами.
Показывает список веток
Создает новую ветку. Также можно сипользовать:
git checkout -b имя_ветки
Чтобы сразу создать новую ветвь и перейт в неё.
Удаляем ветку. Удаление происходит если ветка уже слита.
Насильное удаление ветви без проверки того, что она уже слита.
HEAD
- это символическое имя текущего выбранного коммита.
По-умаолчанию HEAD указывает на последний коммит из локального дерева.
Обычно HEAD
указывает на имя ветки, например master
или bugFix
. При коммите мы меняем статус ветки и это вижно через изменение HEAD
.
Отделение Detaching HEAD
означает присвоение HEAD
не ветке, а конкретному коммиту.
Позволяет переключиться на нужный коммит указав его hash
.
git checkout commit_hash
Или можно переключиться на ветвь разработки:
git checkout branch_name
При переходе на коммит, текущий указатель *HEAD
будет отделен от листа ветки. Чтобы его вернуть можно ввести команду перехода на ветку:
git checkout master
Можно использовать не только абсолютные ссылки в виде коммитов или названий веток, а переходить к их родительским элементам, с помощью относительных ссылок: ^
или ~<num>
.
Чтобы перейти в родительский элемент от ветки master
(на один коммит назад по дереву):
git checkout master^
Чтобы перейти на 2 элемента назад:
git checkout master^^
Или то же самое можно записать в виде относительной ссылки:
git checkout master~2
Вместо названий веток можно использовать идентификаторы коммитов.
При переходе по относительным ссылкам можно использовать указатель HEAD
, например, чтобы перейти на 2 уровеня назад:
git checkout HEAD^^
или
git checkout HEAD~2
git merge branch_name
Вливание в текущую ветку указанной ветви branch_name
.
При ребейзе git по сути копирует набор коммитов и переносит их в указанное место.
Преимущество rebase
в том, что с его помощью можно делать чистые линейные последовательности коммитов.
Например, если существеут ветка master
и bugFix
, и мы хотим сдвинуть наши изменения из ветки bugFix
прямо на вершину ветки master
, то находясь в ветку bugFix
можем набрать следующую команду:
git rebase master
Таким образом мы скопируем и перенесем коммиты из ветки bugFix
в ветку master
, как будто изменения делались последовательно, хотя на самом деле параллельно. В ветке master
сощдастся новый коммит.
Если делаем rebase master
при этом находясь в master^
или в другом потомке, то указатель просто сдвинется на ветку master
.
Чтобы связать локальный репозиторий с удаленным репозиторием используется команда git remote add
, например:
git remote add origin git@github.com:username/project.git
origin
- это название, которое мы даем этому удаленному репозиторию.
Затем переименовваем текущую ветку master
в main
, т.к. на гитхабе при создании репо главная ветка это main
:
git branch -M main
Затем отправляем командой git push
данные из ветки main в удаленный репозиторий origin
:
git push -u origin main
Далее можноотправлять изменения просто командой
git push
Данная команда загружает актуальную версию с удаленного репозитория в локальный.
git pull
pull
- это составная команда, она не только загрузит состояние с гитхаба, но и произведет merge
с текущим состоянием локального репозитория.
Чтобы отправить запрос на изменение в чужой репозиторий нужно:
- Создать форк
fork
чужого проекта на своем аккаунте. - Внести изменения
- Склонировать форк к себе в локальную среду командой
git clone https://github.com/my_nickname/forked_project
- Создать ветку с изменениями, напрмиер:
git branch fixes ``` или ```bash git checkout -b fixes
- Внести все изменения в эту ветку:
git add file git commit -m "fix: fix description"
- Запушить изменения в свой аккаунт:
git push
- Подтвердить создание
pull request
'a на github с изменениями.
Если вы не делаете форк, и пытаетесь загруить в оригинальный репозиторий, то система это не позволит. Надо сделать копию клон и потом отправить клон-копию себе. Создастся запрос на изменение в главную ветку в оригинал.
`git clone`` - клонирование, создание локальной копии удаленного репозитория.
fork - копия чужого реозитория
git pull
- стянуть все изменения из удаленного репозитория. Cоздает вопрос слияния веток, иногда проще клонировать весь блок в отдельную папку.
git pull
- выкачивает данные из репозитория и делает слияние с локальным репозиторием
Если не нужно слияние то луче использовать команду git clone
.
git push
- отправляет изменения в удаленный репозиторий
git push ssh_name
или git push https://...
git должен быть авторизован на внесение изменений в удаленный репозиторий, чтобы выполнить команду git push
git add
- добавляет файлу версионность в локальном репозитории
git checkout
- позволяет перемещаться между ветками и сохранениями
git diff
- разница между текущей и зафиксированной версией файла
git commit
- фиксация изменений в репозитории
git branch
- вывод всех веток на экран
git branch new_branch_name
- создание новой ветки
git merge branch_name
- слияние веток: в текущую branch_name
git merge lists
- в текущую ветку добавит информацию из lists
git reset --hard HEAD^
- сбросить мастер на 1 коммит назад (символ ^)
git push origin master --force
- запушить изменения в мастер, но т.к. мы переписываем история - поэтому --force