|  |  | @ -0,0 +1,830 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | # Система контроля версий Git | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | # Цель работы | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 1. Знать понятия и компоненты систем контроля версий (СКВ), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     порядок и приемы работы с ними. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 2. Уметь участвовать в командной разработке, используя конкретную СКВ — Git, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     а также типовой web-интерфейс Gitea. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | # Выполнение работы и составление отчета | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Необходимо выполнить все действия без пропусков. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Читайте пункт задания до конца перед тем, как выполнять его. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Для удобства по тексту отмечены пункты, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | способ выполнения которых нужно придумать **самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Нужно читать и осмысливать текст, который печатается в ответ на команды. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Если допущена ошибка, нужно повторить команду правильно. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Отчет должен содержать все введенные команды, ответы системы, пояснения, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | что было сделано между пунктами (например, отредактирован файл), а также то, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | что требуется добавить в отчет по тексту задания. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Весь текст, который был в терминале, в отчете должен быть как текст, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | а не как скриншоты терминала. Скриншоты `gitk` и web UI не нужны. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Отчет нужно закоммитить в репозитарий, который создается в ходе ЛР, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | как текстовый файл `README.txt` (простой текст) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | или как `README.md` в формате Markdown. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Это лучше сделать одним последним коммитом после выполнения работы. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ## Вход в терминал и создание структуры каталогов | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Большая часть работы будет выполняться в терминале (командной строке). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Для Windows вместе с Git поставляется программа Git Bash: эмулятор терминала | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Linux.  Ее можно запустить из контекстного меню любого каталога пунктом | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | *Git Bash Here* или из меню «Пуск». | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Создайте на рабочем столе каталог `lab02` для данной ЛР | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | и запустите в нем Git Bash. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Внимание.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Даже если работа выполняется в компьютерном классе, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | создавайте каталог на рабочем столе, а не на сетевом диске, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | так как git не сможет нормально с ним работать. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | В терминале откроется *приглашение (prompt)* примерно такого вида: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | user@mpei-dc-win7 MINGW32 /c/Users/user/Desktop/lab02 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | $ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Здесь важен рабочий каталог `/c/Users/user/Desktop/lab02` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | и символ `$` — начало ввода команд. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотреть файлы в рабочем каталоге можно командой `ls`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | В каталоге `lab02` пусто, поэтому `ls` ничего не выведет. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | В ходе работы будем имитировать проект с двумя участниками: Алисой и Бобом. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Компьютеры Алисы и Боба имитируют папки `lab02/alice` и `lab02/bob`: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | mkdir alice | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | mkdir bob | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Переход между каталогами делается командой `cd`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Перейдем «на компьютер Алисы» — в каталог `alice`: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | cd alice | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Создайте здесь каталог `project` и перейдите в него. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Перейти на уровень выше можно командой `cd ..` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | (две точки в конце, после `cd` пробел). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Перейдите из каталога проекта вверх, затем вернитесь в каталог `project`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Все команды нужно заносить в отчет. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Текст в Git Bash копируется при выделении, ничего нажимать не нужно. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Скопированное можно вставить в любую другую программу *Ctrl+V,* как обычно. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Для вставки в сам Git Bash из буфера обмена | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | нажмите правую кнопку мыши или *Ctrl+Insert.* | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ## Инициализация репозитария и настройка Git | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Инициализируем репозитарий в текущем каталоге (`project`): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git init | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | К приглашению командной строки добавилось `(master)`: имя текущий ветви Git. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Ветвь `master` используется по умолчанию. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Git хранит свои данные в каталоге `.git` в той папке, где сделано `git init`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Ее можно увидеть командой `ls -A`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Заходить в `.git` и что-либо делать там не нужно. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Если удалить этот каталог, репозитарий будет безвозвратно утерян. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Git хранит три набора настроек: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * Системные — для всех пользователей компьютера. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * Пользовательские — для данного пользователя системы (`user` в примере). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     На практике чаще всего пользуются ими. Хранятся в профиле пользователя. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * Локальные — для отдельного репозитария, хранятся в нем же. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Используются, если нужно работать с проектами от разного имени | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     (примеры: личные и корпоративные проекты отдельно, Алиса и Боб в случае ЛР). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Локальные настройки перекрывают пользовательские. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Пользовательские настройки перекрывают системные. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Настройки Git сами не находятся под контролем версий, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | они специфичны для конкретного компьютера или конкретной копии репозитария. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Настроим репозитарий Алисы, чтобы коммиты были от ее имени: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git config user.name 'Alice (IvanovII)' | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git config user.email 'alice@example.com' | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** Укажите данные пользователя, как в примере. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Вместо `IvanovII` используйте свое имя и инициалы латиницей. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Используйте свой университетский адрес почты. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Git сам по себе не отправляет писем на этот адрес. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Кавычки должны быть парными. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Они могут быть одинарными (`'`) или двойными (`"`). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Если нарушить парность кавычек или нажать *Enter,* не закрыв кавычку, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ввод команды продолжится на следующей строке. В этом случае можно прервать | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | выполнение команды, нажав *Ctrl + C,* затем ввести команду правильно. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ## Создание коммитов | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Запустите CodeBlocks и создайте проект в репозитарии Алисы.  Убедитесь, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | что не создается ненужных подкаталогов: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | *Project title:* `project`\ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | *Folder to create project in:* `C:\Users\user\Desktop\lab02\alice`\ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | *Project filename:* `project.cbp`\ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | *Resulting filename:* `C:\Users\user\Desktop\lab02\alice\project\project.cbp` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Соберите проект. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | На этом этапе должна быть следующая структура файлов и каталогов: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` text | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | lab02 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ├── alice | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | │   └── project  <--------- текущий рабочий каталог | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | │       ├── .git <--------- создан командой "git init" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | │       ├── bin  <--------- создан CodeBlocks при сборке | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | │       ├── obj  <--------- (то же самое) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | │       ├── main.cpp    <-- код программы | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | │       └── project.cbp <-- файл проекта | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | └── bob | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Занесение файлов под контроль версий | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Вернувшись в Git Bash, просмотрим состояние рабочей копии: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git status | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **В отчете** нужно пояснить, что означает каждая строка вывода этой команды. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Добавим файл `main.cpp` в отслеживаемые (в индекс): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git add main.cpp | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | На Windows может отобразиться такое сообщение: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` text | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | warning: LF will be replaced by CRLF in main.cpp | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | The file will have its original line endings in your working directory | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Оно безвредно.  Смысл в том, что Git хранит файлы с немного измененном виде, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | чтобы обеспечивать удобную работу с репозитарием в любой операционной системе. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Еще раз просмотрите состояние рабочей копии и поясните в отчете изменения. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Выполним коммит с файлом `main.cpp` и коротким сообщением: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git commit -m 'code: заготовка программы' | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Составление сообщений к коммитам | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | На практике важно, чтобы описания коммитов были информативными: в будущем | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | по ним быстро читают историю проекта, ищут коммиты по ключевым словам. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Заголовок (первая строка) должен быть коротким (желательно до 50 символов) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | и описывать суть изменений, потому что только он показывается в списке | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | коммитов.  Часто в заголовок включают тему (к какой части проекта относится | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | коммит) или номер задачи в системе отслеживания ошибок: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * `code: заготовка программы` — изменен код (а не документация, например) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * `build: update CMake version` — коммит относится к сборке | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * `обрабатывает пустой массив | fixes #1234` — исправляет ошибку № 1234 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * `timer: учет високосных лет #4321` — доработка таймера по задаче № 4321 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Временным незаконченным коммитам иногда приписывают `WIP:` (work in progress). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Из заголовка должно быть ясно, что в целом сделано и зачем (почему, для чего). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Обычно нет смысла писать, какие именно файлы и функции были изменены, потому | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | что это можно просмотреть в самом коммите. После заголовка через пустую строку | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | может идти расширенное пояснение (тело), иногда очень длинное. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Как и для исходного кода, главный критерий — понятность и единообразие. Можно | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | писать на русском или английском, в совершенной форме или в повелительном | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | наклонении — но одинаково во всех коммитах. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Добавьте файл `project.cbp` в индекс и сделайте коммит с ним, тема — `build`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Сообщение после темы придумайте по смыслу изменений, например, для этого | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | коммита подошло бы «добавлен файл проекта» или «add project file». | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Создание коммитов с изменениями | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Заменим тело функции `main()` на ввод двух чисел: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` cpp | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | cout << "Enter A and B: "; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | int a, b; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | cin >> a >> b; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотрите состояние репозитария (`git status`).  В отчете поясните различия | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | между случаем, когда добавлялся новый файл, и когда изменился существующий. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Чтобы закоммитить изменения, есть три способа, описанных ниже. Обратите | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | внимание: Git «видит» состояние файлов на диске, поэтому после добавления | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | изменений нужно сохранять файл в CodeBlocks. Желательно также собирать | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | программу после изменений. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Способ 1.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Сначала выбрать файлы, изменения которых должны войти в коммит, затем сделать | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | коммит: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git add main.cpp | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git commit -m "..." | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Этот способ удобен, если изменения присутствуют не только в тех файлах, которые | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | коммитятся.  Например, если работа над кодом уже закончена, а документация еще | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | не дописана и коммитить ее не нужно. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Добавьте в программу вывод суммы `a` и `b`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Способ 2.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Добавить в индекс все изменения, затем сделать коммит: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git add -u | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git commit -m "..." | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Способ удобен, если измнено много файлов.  После `git add -u`, которая | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | добавляет в индекс измененные файлы, можно командой `git add <файл>` добавить | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | в индекс новые файлы. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Добавить в программу вывод разности `a` и `b`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Внимание.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Код доработок должен быть составлен в точности так: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` cpp | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | cout << "A + B = " << a + b << '\n' | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      << "A - B = " << a - b << '\n'; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Дальнейшие дополнения тоже должны продолжать одну большую инструкцию вывода, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | а не быть отдельными.  Это нужно для того, чтобы в последующих пунктах | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | можно было наблюдать некоторые примечательные ситуации. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Способ 3.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Добавить все изменения в индекс и сделать коммит в один шаг: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git commit -a -m "..." | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Способ полностью эквивалентен предыдущему и удобен, если коммит меняет | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | только существующие файлы. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ## Игнорирование файлов | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Можно заметить, что в выводе команды `git status` все время присутствуют | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | каталоги `bin/` и `obj/`.  Они содержат бинарные файлы (целевой `*.exe` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | и промежуточные), которые являются производными от исходного кода, уже | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | находящегося под контролем версий.  Является грубой ошибкой заносить | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | под контроль версий продукты сборки.  То же самое относится к файлам, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | в которых некоторые среды сохраняют, например, состояние редактора: открытые | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | файлы и расположение окон одного члена команды не нужны в общем хранилище. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Укажем Git игнорировать присутствие каталога `bin`.  Для этого создадим | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | в CodeBlocks новый файл *(File → New... → Empty)* и запишем в него строку: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` text | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | /bin | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Косая черта в начале означает путь от корня репозитария (каталога `project`), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | без нее игнорировался бы файл или каталог `bin` в любой подпапке.  Сохраним | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | файл в корне репозитарий под именем `.gitignore`, именно с точкой в начале. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Каждое правило игнорирования пишется на отдельной строке `.gitignore`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Выполнив `git status`, можно видеть, что каталог `bin` не отображается. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Занесите каталог `obj` в список игнорируемых и убедитесь, что это удалось. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Файл `.gitignore` может и обычно должен находиться под контролем версий. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Создайте коммит с `.gitignore`, тема — `git`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ## Просмотр истории | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Работа с журналом репозитария | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Журнал репозитария показывает команда `git log`.  У нее много опций, например: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * `git log --stat` показывает файлы, измененные в коммитах; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * `git log --oneline --decorate` показывает коммиты компактно; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * `git log --oneline --decorate --all --graph` делает то же для всех веток. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Среди прочего, команда показывает для каждого коммита его хэш, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | например, `d2e8af7ff9c4684d0deb60d3305474bcaf69ce5c`.  Некоторые версии | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | команды показывают хэш сокращенно — краткий вариант тоже будет восприниматься | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | командами Git, которые принимают хэш. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Если лог изменений длинный, `git log` показывает текст с прокруткой. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Чтобы выйти из этого режима, нажмите `q`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Попробуйте каждую из приведенных команд.  **В отчете** подробно опишите, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | что показывается `git log --stat` для последнего коммита. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Коммиты можно фильтровать по разным признакам: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * `git log -- main.cpp` показывает затрагивающие `main.cpp`; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | * `git log --grep "code:"` показывает коммиты с `code:` в сообщении. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Найдите сначала коммиты по теме `build`, затем коммиты, затрагивающие | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | `project.cbp`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Просмотр коммитов | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Содержимое отдельных коммитов просматривается командой `git show <refspec>`, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | где `<refspec>` может быть хэшем коммита, именем ветви или выражением, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | которое задает, на сколько от них отступить в истории. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотрим последний коммит тремя эквивалентными способами: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 1. `git show HEAD` (текущий) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 2. `git show master` (по имени ветви) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 3. `git show d2e8af` (по хэшу нужного коммита) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Для просмотра предыдущего коммита можно либо записать его хэш, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | либо указать, что от последнего нужно отступить на один коммит: `HEAD~1`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотрите предпоследний коммит **(в отчете** зафиксируйте результат единожды) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | тремя способами. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Просмотр изменений | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Внесем изменения в `main.cpp`: добавим печать произведения чисел, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | но не станем пока делать коммит. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотрим изменения в рабочей копии: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git diff | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **В отчете** необходимо пояснить все компоненты отображаемого патча. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Первый аргумент команды `git diff` включает показ изменений от указанного | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | коммита до последнего, включая изменения в рабочей копии: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git diff HEAD~2 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | С двумя аргументами команда показывает разницу между указанными коммитами, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | например, так можно исключить изменения в рабочей копии из вывода предыдущей | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | команды: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git diff HEAD~2 HEAD | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотрите изменения между самым первым коммитом и коммитом, добавляющим | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | вывод разности. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Использование GUI | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотр истории — одна из операций в СКВ, которую иногда удобнее выполнять | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | из графической среды.  Вместе с Git поставляется графическая оболочка gitk | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | (Git GUI), которую можно вызвать пунктом *Git GUI Here* в контекстном меню | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | папки проекта.  Эта оболочка очень примитивная, на практике пользуются | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | [более мощными](https://git-scm.com/downloads/guis) или встроенными в среду | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | разработки. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотр истории в gitk делается из меню *Repository → Visualize All Branch | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | History.*  Можно выбирать коммит для просмотра из списка; смотреть | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | как изменения *(Diff),* так и версии файлов *(Old version, New version);* | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | искать коммиты. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **В отчет** ничего заносить не нужно. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ## Откат изменений | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Закоммитьте изменения в рабочей копии (вывод произведения). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Предположим, необходимо отменить (откатить) этот коммит, то есть вернуться | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | к предыдущему.  Для этого воспользуемся командной `git reset`: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git reset --hard HEAD~1 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Здесь `HEAD~1` указывает на коммит, к которому нужно откатить состояние рабочей | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | копии, а ключ `--hard` означает, что нужно привести рабочую копию точно | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | к состоянию выбранного коммита. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | CodeBlocks (и другие среды) могут при этом показать предупреждение, что файл | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | на диске был изменен, и предложить загрузить его заново.  Следует согласиться. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Добавим над функцией `main()` комментарий: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` cpp | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | // you may type whatever you want | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Уберем изменения в `main.cpp` другим способом — откатив этот файл к состоянию | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | в последнем коммите (`HEAD`): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git checkout HEAD -- main.cpp | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Второй способ необходим, чтобы откатывать отдельные файлы.  Аргумент `HEAD` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | необязателен, но вместо него можно указать не последний, а любой другой | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | коммит.  Это полезно, если нужно восстановить состояние одного файла таким, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | какое оно было в известный момент. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ## Обмен кодом через удаленное хранилище | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Регистрация на сервере | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Зарегистрируйтесь на [Git УИТ](http://uit.mepi.ru/git) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | под именем вида `KozlyukDA` (своя фамилия и инициалы, как почта МЭИ). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Пароль придумайте самостоятельно. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Настройка SSH | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Отправлять изменения в удаленный репозитарий обычно могут не все. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Так, доступ на запись к репозитариям по умолчанию есть только | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | у создателя (пользователя, зарегистрированного на предыдущем шаге). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Загрузка комитов (доступ на чтение) из публичных репозитариев разрешена всем. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Сервер должен выяснить, что клиент, представившийся определенным пользователем, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | действительно им является (провести *аутентификацию*). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Клиент git взаимодействует с сервером по протоколу SSH (secure shell), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | который использует для аутентификации пары ключей: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | открытый (public, публичный) и закрытый (private, приватный) ключ. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Конкретный открытый ключ связан с конкретным закрытым. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Сначала открытый ключ загружается на сервер через web-интерфейс. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Затем любой клиент, который обладает соответствующим закрытым ключом, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | может доказать это серверу. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | У одного пользователя может быть несколько пар ключей, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | например, для рабочего и домашнего компьютера, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | тогда на сервер загружаются два открытых ключа. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Внимание.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Закрытый ключ является таким же секретом, как пароль пользователя. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Любой, кто получит закрытый ключ, сможет вносить на сервер изменения | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | от имени вашего пользователя. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Закрытый ключ нельзя давать никому, открытый ключ можно давать свободно. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Создать пару ключей: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ssh-keygen | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | По умолчанию закрытый ключ записывается в файл `/home/user/.ssh/id_rsa`, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | можно оставить это значение по умолчанию (нажать *Enter*). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Далее нужно ввести пароль, которым будет защищен ключ, и повторить его. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Пример вывода команды: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | `Generating public/private rsa key pair. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Enter file in which to save the key (/home/user/.ssh/id_rsa):` *(Enter)*\ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | `Enter passphrase (empty for no passphrase): ` *(ввод не отображается)*\ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | `Enter same passphrase again: ` *(ввод не отображается)*\ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | `Your identification has been saved in /home/user/.ssh/id_rsa | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Your public key has been saved in /home/user/.ssh/id_rsa.pub`\ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | *(Далее следуют уникальные для каждого ключа строки.)* | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Вводить пароль каждый раз, когда используется ключ, неудобно. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Используют программу-агент, которая работает в фоне и предоставляет ключи | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | другим программам, в том числе git. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Пароль требуется тогда вводить один раз — при загрузке ключа в агент. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Запустить агент: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | eval `ssh-agent -s` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Загрузить ключ (потребуется ввести пароль): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ssh-add | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | По умолчанию `ssh-add` загружает `~/.ssh/id_rsa`, для загрузки других ключей, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | если это нужно, можно передавать ей путь к файлу ключа явно. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Отобразить открытый ключ можно командой: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | cat ~/.ssh/id_rsa.pub | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Скопировать открытый ключ (текст) и добавить в список открытых ключей | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | своей учетной записи. Это делается в настройках (меню пользователя | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | в правом верхнем углу, пункт *Settings*), раздел *SSH and GPG keys,* | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | кнопка *New SSH key.* | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Если работа выполняется в компьютерном классе, закрытый ключ будет утерян | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | после выхода из учетной записи (или выключении компьютера). Проще всего | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | дома или на следующем занятии создать новый ключ и добавить его на сервер. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | На практике ключи не уничтожают (кроме случаев, когда их украли), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | а переносят как файлы, например, при переустановке системы. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Из проводника Windows файл закрытого ключа | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | виден как `C:\Users\User\.ssh\id_rsa`, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | если понадобится его скопировать. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Отправка проекта на сервер | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | [Создайте репозитарий](https://help.github.com/articles/create-a-repo/) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | под названием `cs-lab02`.  Вопреки рекомендациям по ссылке, не нужно добавлять | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | в репозитарий файл `README.md` или лицензию. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | После создания пустого репозитария будет показана страница с инструкциями, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | как настроить связь с удаленным хранилищем: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 1. В разделе *Quick setup* нужно выбрать вариант SSH. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 2. В разделе *…or push an existing repository from the command line* | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     даны команды, которые необходимо выполнить. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Обновите страницу и убедитесь, что файлы проекта видны в web-интерфейсе. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Любой файл можно просмотреть в бразуере. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | По ссылке *Commits* можно просматривать коммиты. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Получение проекта с сервера | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Предположим, к разработке проекта присоединяется Боб. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Откройте новый терминал Git Bash в каталоге `bob`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Клонируйте проект: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git clone <адрес> <каталог> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | На место `<адреса>` нужно подставить адрес, который использовался в команде | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | `git remote add` (его можно всегда отобразить командой `git remote -v`). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Каталог — название папки для проекта: используйте `project`, если не указывать, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | это было бы название репозитария (`cs-lab02`). Угловых скобок в команде быть | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | не должно! | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Перейдите в каталог проекта «на машине Боба» (здесь и далее это означает | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | работу во втором терминале и над файлами в `bob/project`): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | cd project | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | «На машине Боба» настройте Git (`git config`) аналогично тому, как это | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | делалось для Алисы в начале лабораторной работы. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ## Совместная работа над проектом без конфликтов правок | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | «На машине Боба» добавьте в программу печать произведения чисел и сделайте | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | коммит.  Просмотрите последний коммит и убедитесь, что он сделан от имени | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Боба. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Отправьте коммит на сервер. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git push | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Примечание.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Поскольку работа от лица Алисы и Боба ведется одним локальным пользователем, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | используется один и тот же ключ SSH, поэтому Бобу не требуется отдельной | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | учетной записи на сервере и отдельного ключа SSH. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | На практике у каждого разработчика, разумеется, своя учетная запись и ключ. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Обновите страницу в web-интерфейсе и убедитесь, что коммит попал в удаленный | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | репозитарий.  Обратите внимание, что авторство коммитов записано в самих | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | коммитах, оно не зависит от пользователя системы. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | «На машине Алисы» (то есть в первом терминале, в каталоге `alice/project`) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | выполните загрузку изменений: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git fetch | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Убедитесь, что в рабочей копии изменений еще не произошло. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотрите историю всех веток: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git log --oneline --decorate --all --graph | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Как можно видеть, ветка `master` отстает на один коммит от ветки | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | `origin/master` (версии ветки `master` из удаленного репозитария под названием | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | `origin`, то есть на сервере). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Продвиньте ветку `master` к скачанной версии: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git pull --ff-only | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Убедитесь, что рабочая копия проекта «у Алисы» соответствует версии «у Боба». | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Команда `git pull` автоматически делает `git fetch`, поэтому можно было бы | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | применять только ее, но важно понимать, что получение изменений в Git | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | двухфазное: загрузка новой части истории и синхронизация положения веток. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | «От имени Алисы» добавьте в программу печать деления, сделайте коммит, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | отправьте его на сервер и получите новую версию «на машине Боба». | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Иначе говоря, повторите шаги выше, поменяв местами роли Алисы и Боба. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ## Разрешение конфликтов правок при совместной работе | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Предположим, Алиса решает добавить в программу печать максимума из чисел, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | а Боб — минимума. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Внимание.**  Код вывода в программе перед выполнением дальнейшего должен | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | иметь следующий вид: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` cpp | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | cout << "A + B = " << a + b << '\n' | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      << "A - B = " << a - b << '\n' | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      << "A * B = " << a * b << '\n' | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      << "A / B = " << a / b << '\n'; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | В противном случае код нужно привести в соответствие отдельным коммитом | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | и синхронизировать состояние «у Алисы» и «у Боба». | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | «На машине Алисы» дополните программу печатью максимума, сделайте коммит | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | и отправьте его на сервер. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | «На машине Боба» дополните программу печатью минимума, сделайте коммит | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | и попытайтесь отправить его на сервер.  Как можно видеть, удаленный | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | репозитарий не принимает изменений: коммит Боба основан не на последнем | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | существующем коммите. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | «От лица Боба» загрузите коммиты из удаленного хранилища и отобразите | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | историю всех веток — результат нужно представить **в отчете.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Можно видеть, что ветка `master` раздвоилась.  Бобу нужно переместить свой | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | коммит поверх коммита Алисы, то есть поверх `origin/master`: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git rebase origin/master | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Однако эта команда завершается с ошибкой, сообщающей о конфликте в `main.cpp`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотрите состояние хранилища и поясните **в отчете.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | «На машине Боба» в CodeBlocks место конфликта будет отмечено прямо в коде. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Необходимо **самостоятельно:** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 1. Удалить метки конфликта: `<<<< ...`, `... >>>>` и `=====`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 2. Отредактировать код так, чтобы он включал и правки Алисы, и правки Боба. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 3. Убедиться, что программа компилируется и работает. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | После того, как конфликт разрешен, нужно добавить файл в индекс и продолжить | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | прерванную операцию `rebase`: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git add main.cpp | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git rebase --continue | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Убедитесь, что история хранилища теперь имеет желаемый вид (зафиксировав | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | это **в отчете)** и отправьте изменения на сервер. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ## Использование веток | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Предположим, пока Боб синхронизировал изменения, Алиса решила изменить | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | тип чисел с целых на действительные.  Предполагая, что это займет время, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Алиса ведет работу в отдельной ветке.  На момент начала работы репозитарий | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Алисы *не* синхронизирован с сервером, то есть последний коммит добавляет | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | печать максимума.  Все действия ведутся «на машине Алисы». | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Создайте ветку `double`: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git branch double | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Переключитесь на нее: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git checkout double | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Примечание.**  Создание ветки и переключение на нее можно делать одной | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | командой: `git checkout -b double`.  Этой команде можно передать | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | аргумент-ссылку на коммит, где создать ветку. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Можно заметить, что текущая ветка в приглашении терминала изменилась. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Замените тип переменных `a` и `b` на `double` и сделайте коммит. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Переключитесь на ветку `master`: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git checkout master | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | **Самостоятельно.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Синхронизируйте ветку `master` «на машине Алисы» с сервером. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотрите историю всех веток и занесите результат **в отчет.** | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Слейте ветку `double` в `master`: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | git merge double | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | В результате слияния образуется специальный новый коммит (merge commit), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | к которому Git предлагает написать сообщение в редакторе.  Строки, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | начинающиеся с октоторпа («решетки», `#`), в сообщение не войдут. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Отправьте изменения на сервер. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Просмотрите и занесите **в отчет** историю всех веток репозитария. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ### Редактор Vim | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Vim — продвинутый текстовый редактор.  Он не является частью Git, но популярен | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | в системах семейства \*nix, поэтому предлагается по умолчанию.  Не обязательно | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | его использовать, но нужно знать минимум для обращения с ним. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | После запуска Vim находится в так называемом *нормальном режиме.* | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Чтобы начать вводить текст, нужно перейти *в режим вставки,* | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | нажав `i` (одну клавишу). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | В режиме вставки можно набирать текст обычным образом. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Вернуться в нормальный режим можно нажатием *Escape.* | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Находясь в нормальном режиме, можно сохранить сообщение и выйти из Vim | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | нажатием `ZZ` (две заглавные Z, то есть *Shift+Z* два раза). | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Если вместо *Shift+Z* нажать *Ctrl+Z,* Vim будет приостановлен, а коммит | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | останется незавершенным.  В этом случае нужно вернуться в Vim командой `fg` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | в терминале. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Чтобы писать длинные сообщения, но не использовать Vim, можно указать | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | другой редактор (например, примитивный `nano`): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` sh | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | EDITOR=nano git merge double | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ``` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | # Формат защиты | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Защита состоит из ответов на теоретические вопросы по лекции | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | и выполнения задания, рассчитанного на 10 минут. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | Пример задания: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 1. Создать новый репозитарий. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 2. Закоммитить файл `task.txt` с цифрами от 0 до 9 на отдельных строках. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 3. Удалить строки с цифрами от 5 до 8, закоммитить. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 4. Просмотреть предпоследний коммит. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 5. Создать ветку `task` от предыдущего коммита. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 6. Переключиться на ветку `task`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 7. Добавить в начало файла строки с буквами `a`, `b`, `c`, закоммитить. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 8. Переключиться на ветку `master`. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 9. Добавить в начало файла строки с буквами `d`, `e`, `f`, закоммитить. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 10. Слить ветку `task` в `master`, разрешив конфликт так, чтобы буквы шли | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     по порядку. |