Git: введение и основы работы через терминал. Часть 1
09 июля 2024

Git: введение и основы работы через терминал. Часть 2

Структурируем знания по Git: разбираем, как гит работает изнутри, учимся работать с гит через консоль + некоторые рекомендации по работе с ним. Вы можете посмотреть полную видеозапись лекции внизу страницы.

Андрей Гладков
Ведущий инженер-разработчик ПО

Более 9 лет опыта в разработке.


Повышение квалификации:

  • «Создание web-интерфейсов(HTML/CSS)», (сертификат "Htmlacademy");
  • «JavaScript/DOM/элементы» (сертификат "learn.javascript.ru")
  • «Комплексное обучение JS developer» (сертификат "Loftschool");
  • «PHP. Архитектура сложных веб-сервисов» (сертификат "Htmlacademy").

Инструментарий:

  • HTML5, CSS;
  • Webpack, Git;
  • JavaScript(React.Redux,Mobx,Next,Apollo graphql);
  • Angular(TypeScript,RxJS,MUI);
  • Leaflet,OpenLayers;
  • NodeJs(Express,Koa,NestJs);
  • Postgresql, Mongo.
Цели курса:

  • получить хорошие эмоции и узнать что-то новое =)
  • структурировать знание по git;
  • понять как git работает изнутри;
  • научиться работать с git через консоль;
  • узнать о рекомендация при работах с git.

«Git: введение и основы работы через терминал. Часть 1»


Конфигурация — УРОВНИ
git config --system (общесистемные настройки)
/etc/gitconfig | C:\Program Files\git\etc\gitconfig
git config --global (конкретный пользователь)
C:/Users/<NAME>/.gitconfig
git config --local (на уровне проекта) 
<project>/.git/config
.gitignore – отслеживание игнорируемых файлы
<project>/.gitignore

Конфигурация
git config --global - глобальные настройки – для пользователя
user.name <…>
user.email <…>
core.editor ‘code -w’- вызов текстового редактора гитом
 git config –list - получение списка всех настроек
удаление настроек
git config --global --unset user.name
git config –remove-section user
git config –help – помощь
git config --global core.editor= <…>
‘code -w’
git config –global (–e  | -edit)

Псевдонимы - alias
(сокращенные варианты команд)
git config		
alias.c config  - сокр. запитьс ‘git c’ для ‘git config’
alias.cg ‘config --global’
alias.printGit "!echo 'print'; echo ‘GIT‘ "
alias.author '!git cg user.name;git cg user.email'
https://github.com/GitAlias/gitalias


Операции добавления, удаления
 git status
 git add 
. / –A	
–f (--force) – минуя гит игнор
–p <f>
-s разделить на hunks
git rm -  удаление с добавлением в индекс
--r --cahed – удалит из индекса но оставит в рабочем каталоге
--f  удален из рабочей и из индекса
git clean - удаление неотслеживаемых файлов и директорий
–f файлы без этого не работает
-d файлы и директории
-x файлы которые игнорируется через .gitignore

Коммиты - commit
 git commit – добавление изменений в репозиторий
-m <message> - сообщение к коммиту
<f> быстрый коммит для одного файла или директории
-v - Просмотр изменения которые мы собираемся сохранить 
–amend –m <message> - Добавление забытых файлов
–a –m / -am <message> -Добавление файлов сразу в репозиторий(Работает только с файлами которые уже есть в индексе)
git log – история коммитов
--pretty=oneline (–oneline)
--pretty=fuller	
git show  - информация о коммите
<h = HEAD>
git show 8f7288c | code – 
откроет просмотр в редакторе

Коммиты – commit : Отмена
git reset - отменяет изменений 
<h = HEAD> Или @~(N=1)
<h = HEAD> <f> - Можно сбросить конкретный файл
--hard жестко не сохраняя изменения
--soft сохраняет данные от коммита с которого мы ушли до указанного c сохранением изменений в индексе
--mixed отличие от мягкого reset в том что изменения остались в директории но не проиндексированы
git revert – делает коммит на отмену изменений 
<h> - один коммит
<h1>... <h2>  - несколько коммитов последовательно от раннего к позднему

Объекты ГИТ - просмотр
.git/objects - место хранения всех файлов
git cat-file - просмотр содержимого или информации об объекте репозитория.
 -p <h> - тип объекта
 -t <h> - содержимое

Ветки – branch
Переключение - checkout
git branch – список веток
<b> - создание ветки
-v  - подробный список с коммитами на которые ссылается ветка
-a – список удаленных веток
–m <b> - переименовать текущую ветку
–d - удаление ветки (текущую ветку удалить нельзя) 
 git checkout
–b <b> - переключаться на новую ветку
<h>  - переключиться на конкретный коммит  (detached HEAD)	
.git/head 
5404 index.html -восстановит файл до указанного коммита
Несколько файлов\директорий
HEAD inedx.html - версия файла из текущего коммита	

Отложить - Stash
git stash - спец команда которая собирает незакоммиченные изменения, удаляет их из файлов, и в спец виде архивирует в гит
-u отложить не отслеживаемые файлы
-a - не отслеживаемые файлы+ игнорируемые
save <message>  - сохранить набор с сообщение
list – просмотр список наборов
pop – достать и удалить из списка
stash@{2} – конкретный набор
apply –достать не удаляя

ИСТОРИЯ HEAD - Reflog
cat .git\logs\HEAD
git reflog <b = HEAD>
reflog – это алиас к git log --oneline –g поэтому флаги сработают, 
reflog --date=iso - например добавим дату (что было неделю назад )
--date='relative'
git branch feature
HEAD@6 – Переместить можно путем создания ветки на коммите (или ссылки HEAD@N) (в windows это будет ‘HEAD@6 ‘)
HEAD@{“точная дата из рефлога”} с кавычками потому что пробелы
По умолчанию записи в рефлоги храниться не бесконечно 
git config –global
gc.reflogExpire -  время, в течение которого хранятся записи в журнале ссылок ветки
gc.reflogExpireUnreachable -  в течение которого хранятся недоступные записи в журнале ссылок ветки.
reflog локален – и сработает только на текущей машине

История - LOG
git log
-N (чилос записей)
--pretty=oneline(medium)  - форматирование (какие  свойства и в каком виде) выводить
--abbrev-commit  - короткие записи коммитов
--oneline  => --pretty=oneline –abbrev-commit
--no-decorate – без ссылок на ветки
--pretty=format:'%h %cd | %s%d [%an]’
%cr относительная дата
git log --help  и там найти  PRETTY FORMATS – обозначения
--pretty=format:'%C(green)%h %C(red)%cr | %s%d %C(cyan)[%an]' - Так же можно добавить цвета 
Можно сохранить в конфиг 
git config --global pretty.my format:'%C(yellow)%h %C(red)%cr %C(reset)| %s%d [%C(cyan)%an]‘
git log --pretty=my
-p --patch  - diff того что было сделано в коммите
--graph  - наглядную структуру веток
--stat – что было изменено	
feature ^master – коммиты ветки фичер после отхождения от мастер

ПРОСМОТР - SHOW , BLAME
git show – посмотреть изменения
<b>| <h> - что именно
--pretty=fuller – формат данных коммита
HEAD~[~~] /HEAD~1[3]/ @~1[3] – отсчитать назад
Рефлог для винды c ковычками
Такое действует не только для head Но и для другого любого идентификатора
feature~2
6587368~2
9b378c5:index.html – файл в конкретном коммите
9b378c5~2:index.html – файл 2 коммита назад от текущего
git blame  - кем были сделаны изменения
src/index.ts  -где
--date=short  - как выводить
-L 3,5  - какие строки	

Сравнение - Diff
 git diff - выводит только изменения не находящиеся в индексе
<b1> <b2>  - все изменения между ветками
 -U<N=3> сколько строк показывать рядом с изменениями
<b1> < b2> <f> - конкретные файлы
<b1>: <f1> < b2>: <f2> - разные файлы разных веток
–name-only <b1> < b2> - имена файлов
<b1> … < b2 >  - что именно изменилось в b2 с момента отхождения от b1 (ищет общего предка и показывает изменения от него)
<h1>..< h2 > | <h1> < h2 > - между коммитами
 HEAD - сравнение рабочей директории с HEAD (посмотреть что в общем понаделал)
 --staged / --cashed –содержимое индекса

СЛИЯНИЯ - merge
 git merge – слияние веток
<b> - ветка которую хотим загрузить
 git merge-base <b1> <b2> -коммит на котором ветки разделились
git checkout <--ours/--theirs/--merge> <f>
 git show :<1|2|3>:<f> - посмотреть номер стадии конфликта файла
1  - общий предок
2 – наши
3 – сливаемая версия
 git merge --abort  / git reset –merge – отменит изменения в индексе но не в рабочей директории(изменния которые не касаются слияния переживут слияние и его отмену)
git merge –continue | git commit  - завершить коммит
 .git/MERGE_HEAD – гит запоминает коммит с которым мы осуществляем слияние
 .git/ORIG_HEAD - перед мержим гит страхует нас записывая идентификатор нашего коммита
 git merge <b> --log – в описание добавится список всех сливаемых коммитов

СЛИЯНИЯ - merge : отмена
 git reset –hard HEAD~ - отмену коммита и он потом будет удален(так как недостижим) 
 git reset –hard <h> - вернуться к коммиту слияния(если помним)
 git reset –hard @{N} – переместиться на нужный коммит из reflog 

СЛИЯНИЯ - merge :
Семантические конфликты и проблемы перемотки
 Семантические конфликты - по смыслу а не по месту в файле
 git merge --no-ff <b> – заставляет гит всегда вместо перемотку  делать слияние

Проблема перемотки настолько стандартная что ее можно настроить в конфиге
 git config merge.ff false – отключает перемотку (fast-forward)
git config b.<b>.mergeoptions ‘--no-ff’

Создание коммита из ветки - merge --squash
 git merge --squash <b> – берет и  применяет все изменения из <b> к  текущему состоянию проекта	
git diff --cashed – просмотр изменений

Особенность - при конфликтах squash не создается .git/MERGED_HEAD 
 git merge --abort  - не сработает  так как один родитель
 git reset --merge/ git reset --hard  - отменит проиндексированные изменения

ПЕРЕМЕЩЕНИЕ КОММИТА - Cherry-pick
Команда берет изменения внесенные в коммите, то есть буквально разницу от коммита родителя и применяет их к другой ветке
git cherry-pick <h|b>
-x информацию откуда он был скопирован
<b1>..<b2>– все коммиты из b2 которых нет в b1 – последовательно один за другим
--abort – отменяет при конфликтах
--continue  - продолжить (невозможно при конфликтах)
--quit – остановиться там где мы сей час и сбросить запомненное состояние
--no-commit \ -n скопирует изменения но не будет коммитить и просто добавит в индекс

Переписывание истории – Rebase
копирует последовательно все коммиты как при cherry-pick
переносит ветку в последний коммит – тем самым предыдущие коммиты становятся недостижимыми и впоследствии будут удалены
git rebase 
<b> - откуда переносить изменения
--abort - если были конфликты и мы хотим прервать перебазирование
--quit – в отличие от abort не возвращает обратно HEAD
--skip - пропустить конфликтный коммит
--continue - продолжить коммит

Если хотим отменить rebase нет проблем , перед перебазированием создается запись в .git/ORIG_HEAD
git reset --hard ORIG_HEAD  - вернёт все как было

P.s. Но так же можно посмотреть reflog по ветке  - git reflog <b>

Сравнение подходов - Rebase и merge
rebase 
упрощает историю разработки - делает плоской
заменяет хешы коммитов что может привезти в команде к нежелательным результатам
могут использоваться куски кода которые будут переименованы или изменены в основной ветке(при перебазировании это не будет конфликтом) но коммит будет сломанный 
Битый коммит остается в истории и не дай Бог откатиться на него потом

 merge 
частое использование будет скапливать мусорные коммиты
полностью безопасна – она ничего старого не трогает и не изменяет она лишь добавляет новый коммит для слияния и конфликты\проблемы могут быть только в нем
P.S. Есть простое правило – если ветка публичная или с ней работает несколько человек то переписывание истории категорически запрещены!

Удаленный репозиторий
 git clone скачать репозиторий себе
 git branch - a удаленные ветки просмотр
 git remote add origin <url> связь удаленного репозитория с локальным
 origin - имя удаленного репозитория
 git remote -v - просмотр удаленных репозиториев
 git remote remove origin  - удаление удаленного репозитория

Загрузка\заливка данных
 Загрузка данных с репозиторий
git fetch  
Данная команда извлекает все новые объекты из удаленного репозитория и хранит их в локальном репозитории
git pull = git fetch + git merge
Обновить репозиторий но  и достать их в рабочую директорию
git push
позволяет отправлять локальную ветку на удаленный репозиторий. 
 Загрузка данных с изначально локального 
git push -u origin <b> - связать ветку с удаленным репозиторием
git branch --set-upstream-to <b>  - тоже самое
 git push origin --all добавить все ветки


Содержание:

00:00:00 - Вступление. Пустой проект. Конфигурация – уровни. Псевдонимы - alias (сокращенные варианты команд). Операции добавления, удаления. Коммиты. Отмена коммитов. Объекты ГИТ - просмотр.
00:43:00 - Ветки – branch. Переключение - checkout. отложить - Stash. ИСТОРИЯ HEAD - Reflog. История - LOG. ПРОСМОТР - SHOW, BLAME. Сравнение - Diff.
01:19:00 - СЛИЯНИЯ - merge. Отмена слияния.
01:39:10 - Семантические конфликты и проблемы перемотки. Создание коммита из ветки - merge --squash. ПЕРЕМЕЩЕНИЕ КОММИТА - Cherry-pick.
01:50:20 - Когда нужно выбрать не Merge, a Cherry-pick?
01:53:05 - Переписывание истории – Rebase. Сравнение подходов Rebase и merge. Удаленный репозиторий. Загрузка\заливка данных.
02:03:09 - ПРАКТИЧЕСКИЕ СОВЕТЫ по работе с GIT.
Вам также может быть интересно