Git. За час.

(22:26:07) Серёджа будем использовать git .

(22:26:11) В. это что такое?

(22:26:48) Серёджа https://ru.wikipedia.org/wiki/Git

(22:27:08) Серёджа это система контроля версий

(22:28:01) В. а есть какая-нибудь ломанная её копию, чтобы посмотреть чего она из себя представляет?

(22:28:13) Серёджа это же опенсорс

(22:28:22) Серёджа там должна быть ссылка чо скачивать

(22:28:50) Серёджа для винды: https://git-scm.com/download/win

(22:29:01) Серёджа на линукс проще поставить через пакетный менеджер.

(22:33:37) Серёджа на Мак я ставлю через brew . Хотя как-то и без него, наверное, можно.

(22:33:48) В. блин. я тут пока врубаюсь че мне качать)

(22:33:56) Серёджа В общем, установка — это отдельная тема. Мы эту часть чата потом сочиним.

(22:37:04) Серёджа Она к тому же отличается на разных осях, так что, пока как-нибудь сама давай.

Скриншот установки Git на Alpine LinuxУстановка Git на Alpine Linux

(22:37:30) Серёджа Ещё хорошо бы покрыть тему доступа к сервису: пароли, ключи, ssh-config и прочее. Теперь вы понимаете, почему я с детьми начинал с SVN, он в сто раз проще ложится в неподготовленную голову. Ну ладно, продолжаем…

(22:38:26) В. качается

(22:41:30) В. ога скачала

(22:42:30) Серёджа ставь.

(22:42:37) В. ога

(22:42:40) В. щас. вернусь

(22:47:53) В. тут

(22:48:01) Серёджа ага.

(22:48:04) В. хм. а русификация к нему есть?

(22:48:33) Серёджа щас объясню всё, можно будет без русификации обойтись.

(22:48:38) В. давай

(22:48:39) Серёджа создай пустую папку: mkdir repo-service

(22:49:23) В. есть

(22:49:31) Серёджа Создай в ней «голый» репозиторий: git init --bare repo-service

(22:50:15) В. ога

(22:50:46) Серёджа получилось?

(22:51:01) В. да

(22:51:02) Серёджа значит. У нас получился репозиторий, который будет имитировать Гит-сервис из интернета, типа такой домашний ГитХаб.

(22:51:27) Серёджа теперь делаешь в другом месте другую папку: mkdir repo

(22:51:55) В. и?

(22:52:08) Серёджа клонируешь в него репо из сервиса: git clone repo-service repo

(22:52:55) В. и?

(22:53:34) Серёджа repo-service  — это путь до репозитория, который только что создала. Обычно это URL до репозитория на сервисе в сети.

(22:53:45) Серёджа Но у тебя сейчас это тупо подпапка в том же каталоге, где ты сейчас стоишь, поэтому относительный путь от твоего места — это тупо имя папки.

(22:54:09) В. ога. проканало

(22:54:21) Серёджа круто. Это ты сделала рабочую копию

(22:54:46) В. ога

(22:54:47) Серёджа Если ты напишешь: cat repo/.git/config , то увидишь раздел [remote "origin"] , где будет абсолютный путь в твоей файловой системе до  repo-service

Скриншот терминала с исполнением команд, упомянутых на момент создания репозиторияСкриншот терминала с исполнением команд, упомянутых момент создания репозитория

(22:55:01) Серёджа обычно путь до репозитория выглядит как-нибудь вроде: git@github.com:chromium/chromium.git или https://github.com/chromium/chromium.git

(22:55:15) Серёджа ну в смысле, когда он на серваке

(22:55:15) Серёджа Переходи в каталог репозитория cd repo и ещё немножко подготовки: нужно назвать гиту своё имя и почту, которые он будет подставлять в качестве автора кода.

(22:55:28) В. а дальше?

(22:55:31) Серёджа дальше. можно работать. создай там текстовый файл

(22:55:42) Серёджа и напиши чего-нибудь в несколько строчек

(22:57:40) В. ога. я уже файл запихала в первую папку.

(22:57:52) В. ну он типа сохранился в хранилище

(22:58:01) Серёджа сделала коммит?

(22:58:09) В. да

(22:58:12) Серёджа как?

(22:58:18) В. git add first.txt && git commit -m "my first commit"

(22:58:28) В. гы) что ещё можно с ним делать. ну запихаю я туда кучу файлов. и что?

(22:58:47) Серёджа напиши git status

(22:58:54) В. ога

(22:59:09) Серёджа видишь, в последней строчке nothing to commit, working tree clean ?

Скриншот терминала: настройки автора, первый коммит и проверка статусаСкриншот терминала: настройки автора, первый коммит и проверка статуса

(22:59:11) Серёджа да

(22:59:18) Серёджа отлично.

(23:00:05) В. значит файл закопировался в хранилище или как его обозвать не знаю?

(23:00:19) Серёджа в репозиторий. В его рабочую копию, которая как-бы на компе у программиста.

(23:00:39) Серёджа теперь измени файл

(23:00:49) Серёджа добавь пару строчек и измени какие-нибудь

(23:01:15) Серёджа напиши git status потом

(23:01:17) В. изменила.

(23:01:21) Серёджа видишь: modified: first.txt

(23:01:21) В. и?

(23:02:57) Серёджа git status показывает общее состояние. Теперь напиши git diff , увидишь что конкретно изменилось.

(23:03:03) Серёджа С минусиками — строчки, которые удалились, с плюсиками — которые добавились. Изменённые — как-бы удалились и добавились одновременно.

(23:03:15) В. ога вижу

Скриншот терминала: статус и просмотр измененийСкриншот терминала: статус и просмотр изменений

(23:03:20) Серёджа хорошо. закрывай.

(23:03:24) Серёджа делай коммит: git commit -am "some changes in my first file"

(23:03:30) Серёджа флаг -a означает, что ты коммитишь все изменённые файлы, которые уже были под контролем гита. Новые файлы тебе бы пришлось добавлять отдельной командой git add ...

(23:03:39) Серёджа Флаг -m означает, что ты тут же в команде пишешь комментарий к коммиту. Комментарий — полезная штука. Без -m он откроет в терминале дефолтный текстовый редактор и предложит написать комментарий к коммиту в нём.

(23:03:54) Серёджа Заметь. В репозиторий сохраняются только изменения.

(23:04:14) Серёджа то есть это ты не второй файл туда залила, а только сохранила информацию о том, как файл изменился.

(23:04:47) Серёджа точно так же и наоборот. Когда кто-то что-то изменил, а ты делаешь апдейт

(23:04:57) Серёджа то ты тоже выкачиваешь только изменения

(23:05:05) В. удобно. а что ещё оно умеет?

(23:05:16) Серёджа Теперь говори git log

(23:06:38) В. получилось.

Скриншот терминала: логСкриншот терминала: лог

(23:06:44) Серёджа Видишь длиные айдишники коммитов в логах? На них можно ссылаться в разных командах, причём айдишники можно сокращать, брать от них только начало.

(23:06:57) Серёджа Пиши:

(23:07:05) В. отличия показывает!

Скриншот терминала: изменения конкретного коммитаСкриншот терминала: изменения конкретного коммита

(23:07:10) Серёджа ты можешь выбрать любую ревизию и сапдейтиться до неё: git checkout 12920972

(23:06:31) В. круто — могу и старые файлы видеть!!!

(23:07:25) Серёджа т е. сказать git checkout <commitId> и у тебя будет версия как сто лет назад

(23:08:06) Серёджа Дальше. Бывает, что всякие проги создают в рабочей копии всякие левые файлы и папки, которым в репозитории не место.

(23:08:26) Серёджа например скомпилированый ехе файл коммитить незачем

(23:08:27) В. угу

(23:08:36) Серёджа создай какой-нибудь файл

(23:08:38) В. ога

(23:08:55) В. ога

(23:08:56) Серёджа пиши git status

(23:09:08) Серёджа видишь свой файл в списке Untracked files

(23:09:26) В. угу и?

(23:09:27) Серёджа создаёшь файл .gitignore и записываешь свой файл туда:

(23:09:39) В. угу

(23:09:48) Серёджа Теперь в  git status твой новый файл исчез, зато появился .gitignore . Его нужно добавить и закоммитить.

(23:09:39) В. ога. сделала саммит.

Скриншот терминала: игнорим файлСкриншот терминала: игнорим файл

(23:09:57) Серёджа Теперь, например, если это error.log

(23:09:58) Серёджа то можно в игнор добавить *.log или *.exe и т. п.

(23:10:06) В. ненужный файл туда не попал!

(23:10:19) В. ога. понятно

(23:10:21) Серёджа и все эти файлы не будут коммитится и не будут отображаться в  git status

(23:10:30) В. понятно

(23:10:36) Серёджа теперь. Ты что-то понаписала, но ещё не закоммитила и хочешь откатить.

(23:10:40) В. угу

(23:10:42) В. и?

(23:10:43) Серёджа делаешь git checkout -- . это откатит все изменения, которые были под контролем гита.

(23:10:56) Серёджа git clean -f убирает все незатрэканные файлы из рабочей копии. Чтобы убедиться, что ты не удалишь что-то нужное, сначала git clean -n выдаст список тех файлов, которые бы удалил флаг -f . tutorial

(23:11:27) В. работает!

(23:11:28) Серёджа дальше. Нужно запушить изменения: git push .

Скриншот терминала: гит пушСкриншот терминала: гит пуш

(23:11:29) Серёджа Создай себе где-нибудь ещё одну рабочую копию: git clone repo-service repo-2 . Ты увидишь в  repo-2 все те же файлы, что и в  repo

Скриншот терминала: клонируем в другую рабочую копиюКлонируем в другую рабочую копию

(23:12:30) Серёджа Это типа другой программист присоедининлся к проекту. Надо ему тоже имя и почту настроить:

(23:12:34) Серёджа Измени в новой папке файл и сделай коммит и пуш.

Скриншот терминала: другой чел пушитДругой чел пушит

(23:12:39) Серёджа В старой сделай git pull

Скриншот терминала: стягиваем чужие измененияСтягиваем изменения другого чела к себе

(23:12:45) В. да и в новую рабочую папку обновила по репозиторию

(23:13:42) В. да и в старой рабочей папке апдейтилась и увидела изменения что сделала в новой рабочей папке

(23:13:47) В. а что ещё можно?

(23:13:53) Серёджа А в первой папке измени файл в том же месте, где в той, только по другому.

(23:13:58) Серёджа чтобы конфликт возник

(23:14:03) В. ога

(23:14:09) В. а если я его переименую?

(23:14:16) Серёджа не. ща

(23:14:25) В. изменила и че делать?

(23:14:34) В. я их переименовала)

(23:14:34) Серёджа теперь апдейться

(23:14:43) Серёджа ну. давай поочереди

(23:15:22) Серёджа заметь. Что переименовывать лучше не стандартной командой, а командами гита: git mv .

(23:15:44) Серёджа Потому что тогда гит сразу трэкает, что это лишь изменённый файл. В репозиторий сохраняется только информация о переименовании. Впрочем, он это сам по содержимому понимает. Если один файл удалить, а другой такой же добавить и всё это засунуть в гит: git add ... то он поймёт, что это было лишь переименование.

(23:15:50) Серёджа Неважно. Давай, изменяем один и тот же файл в обоих копиях. Другой чел коммитит и пушит. Ты тоже коммитишь и пушишь.

(23:16:04) В. ога возник конфликт

(23:16:09) Серёджа Это ещё не конфликт, просто ты не можешь пушить, пока не спуллишь, даже если бы изменения не были конфликтными.

Скриншот терминала: не можем запушить, пока не спуллимНе можем запушить, пока не спуллим

(23:16:10) Серёджа пулль!

(23:16:11) В. да, вижу конфликт

Скриншот терминала: пулл с конфликтомПулл с конфликтом

(23:16:13) Серёджа И ещё git status . Видишь, что статус не пишет «nothing to commit», у тебя получилось предкоммитное состояние с изменениями и конфликтный файл помечен «both modified», что он изменён одновременно и у тебя, и в том коде, который пришёл из пулла.

Скриншот терминала: статус в конфликтеСтатус в конфликте

(23:16:15) В. понятно

(23:16:17) Серёджа Открывай конфликтный файл в текстовом редакторе.

(23:16:26) В. и?

(23:16:29) Серёджа У тебя появился кусок:

(23:16:38) Серёджа Сверху версия одних изменений, снизу — других.

Скриншот терминала: смотрим конфликтный файл в текстовом редактореСмотрим конфликтный файл в текстовом редакторе

Заметь, что каждый из вас правил по четыре строчки, но конфликтные только две, потому что нижние две у вас совпадают и не образуют конфликта.

(23:16:39) В. типа умный

(23:16:44) Серёджа типа да. В файле нужно убрать мусорные обозначения а из двух кусков текста выбрать или скомпоновать, тот текст, который в итоге нужен.

Скриншот терминала: поправили конфликт в текстовом редактореПоправили конфликт в текстовом редакторе

(23:16:49) Серёджа потом сохраняешь файл, делаешь ему git add . Так с каждым конфликтным файлом. Потом коммит, пуш.

Скриншот терминала: коммит решённого конфликтаКоммит решённого конфликта

(23:16:55) Серёджа У вас теперь в дереве коммитов развилочка. Пишешь git log --graph . Видишь, вы вдвоём сделали по коммиту от общего предка, а потом слили свои изменения ещё одним коммитом. По дороге пришлось зарешать конфликт.

Скриншот терминала: граф коммитовГраф коммитов

(23:17:05) Серёджа Если конфликтов нет, то гит сам сливает развилку в один коммит. Новый коммит на слиянии тоже образуется, но автоматически. Впрочем, это поведение регулируется разными флагами гитовских команд.

(23:18:30) Серёджа Также есть правило. Перед пушем всегда делать пулл. Но он и не даст запушить, если не всё спуллено.

(23:18:35) Серёджа Кроме того принятно пуллиться каждый день перед работой. Ну и вообще, регулярно и почаще.

(23:18:49) Серёджа Это помогает избежать неприятностей

(23:25:26) Серёджа Обычно конфликты не возникают.

(23:25:41) Серёджа Если изменения в разных частях файла, то он их нормально сам разруливает.

(23:32:12) Серёджа дальше про переименования.

(23:32:37) Серёджа Если ты просто файл переименуешь, то он подумает, что файл потерялся и появился новый без контроля версий.

(23:32:43) Серёджа старый он восстановит при апдейте

(23:32:58) Серёджа Поэтому удалять, переименовывать надо командами git

(23:33:40) Серёджа Чем хорошо. Ты можешь переименовать огромную преогромную папку. А в репозиторий запишется только одна строчка, что такая-то папка была переименована. (Думаю, что с копиями то же самое, но это не точно)

(23:33:50) В. ога получается

(23:34:43) Серёджа Ну в принципе всё. В любой непонятной ситуации делай git status и в понятной тоже.

(23:34:49) Серёджа Ещё неплохо бы покрыть следующие темы:

  • Установка на разные операционные системы, но про это и так есть дофига инструкций в инете.
  • Доступ к сервису: пароли и ключи, и настройка локального хранилича кренделей для разных операционных систем.
  • Работа с ветками
  • Best practices

(23:34:49) Серёджа Почитай ещё статейку в википедии и  документацию .

(23:35:23) В. прикольно в общем.

(23:40:22) В. а вообще спасибо — прямо просвятил. да ещё и удалённо по аське.