Я подготовил большой курс по Git для начинающих, который вам поможет начать работать с этой системой контроля версий.

Установка Git и работа в консоли

В большинстве компаний и на любых курсах по разработке необходимо работать в системе контроля версий Git. Часто, программист отправляет свои задания на проверку и получает обновления в этой истеме.

Рассмотрим как установить Git на Windows и Mac, а также познакомимся с консолью для работы с Гитом.

Для работы я буду использовать терминал Cmder. Для установки и начала работы с ним нам нужно скачать его с официального сайта.

Скачать Cmder

Есть два варианта для скачивания — Mini и Full. Нам нужна версия Full, т.к. только она содержит Git.

Скачанный архив нам нужно просто распаковать. Устанавливать программу не нужно.

Запускаем файл cmder.exe.

Данный терминал может запускать несколько оболочек:

  • cmd — стандартная консоль Windows
  • powershell — продвинутая оболочка Microsoft
  • bash — оболочка, которая запускается по умолчанию на серверах Linux

Мы будем использовать bash.

Для того, чтобы при запуске открывался именно bash — нам нужно настроить cmder.

Открываем Настройки (Setings).

Далее переходим в Startup. Далее видим настройку Specified named task и выбираем {bash::bash}.

Далее перезапускаем терминал cmder. На вкладке внизу окна видим надпись bash.exe — это то, что нам нужно.

Если у вас вместо текстов в консоли непонятные символы, как на скриншоте выше, то это говорит о том, что терминал не знает о русской версии Windows.

Чтобы исправить данную ситуацию мы должны в Настройках прописать две строчки.

Переходим в Настройки (Settings), во вкладку StartUpEnvironments.

И добавляем две строчки:

set LC_ALL=ru_RU.UTF-8
set LANG=ru_RU.UTF-8

Перезапускаем Cmder и видим, что никаких символов нет и у нас корректное отображение русского языка.

Как правило после запуска Cmder мы видим строчку, где указаны имя_ пользователя и после собачки (@) имя_компьютера. После может быть указано имя названия пакета программ и после чего идет значок — тильда (~).

Тильда означает домашнюю папку, что-то вроде: C:\пользователи(users)\имя_пользователя.

На следующей строке мы видим знак доллара (стрелку или что-то подобное) и мигающий курсор. Всё это называется командной строкой. Аналогия чата с компьютером.

Чтобы понять где мы находимся мы будем постоянно пользоваться командой pwd.

pwd

Работа в терминале подразумевает нахождение в какой-либо папке. После запуска вы попадаете в домашнюю директорию.

Настройки Cmder позволяют поменять домашний каталог.

Смена папки производится командой cd.

cd Downloads

Чтобы вернуться в папку в которой мы только что были мы вводим: cd —.

cd -

Чтобы вернуться в домашнюю папку мы можем использовать команду:

cd ~

Чтобы переходить по папкам нет необходимости писать команды с переходом в каждую вложенную папку, можно писать, например, так:

cd Downloads/cmder

Чтобы вернуться в папку на уровень выше, мы должны написать:

cd ..

Если мы были в папке Downloads/cmder, то после этой команды мы окажемся в папке Downloads.

Команду можно использовать и таким образом:

cd ../../

Тогда мы попадем в папку c:\users\.

Чтобы посмотреть содержимое папки в которой мы находимся, мы используем команду ls (от английского — list):

ls

Если мы хотим посмотреть список файлов не в той папке в которой мы сейчас, то используем команду, например (для рабочего стола):

ls ~/Desktop

Чтобы было удобнее смотреть список файлов мы можем добавить флаг «-1» и тогда список файлов выведется в столбик:

ls -1

Если вы хотите открыть в проводнике Windows папку в которой вы сейчас находитесь, то используйте команду:

start .

Эта команда позволяет открывать не только папки, но и файлы. Если вы введете команду start с названием файла, например, index.js, то файл откроется в IDE, которая у вас задана по умолчанию для данного типа файлов.

Справка. Очень удобно в терминале cmder использовать клавишу TAB для быстрого набора имен директорий и файлов в этих директориях.

К примеру, если вы хотите перейти в папку Downloads, то после того, как вы набрали cd ~/D вы можете нажать TAB и терминал подскажет или вставит слово Download автоматически.

Таким образом нет необходимости писать постоянно названия папок и файлов.

Давайте посмотрим как установить Git на Mac, если вы не используете компьютер с Windows.

На Mac-ах уже установлен терминал и нам просто нужно установить Git. Для этого переходим на сайт: git-scm.com. И далее находим справа ниже кнопку: Download for Mac.

После скачивания файлов запускаем установщик. Компьютер может показать предупреждение, что «Программа не может быть открыта, т.к. её автор является неустановленным разработчиком«.

Идем в Настройки и далее в Системные настройки. Выбираем Защита и безопасность и видим внизу кнопку Подтвердить вход. Жмем её.

Теперь установщик откроется и мы проходим все шаги установки Git.

Далее запускаем терминал в котором мы будем работать с Git.

Все команды терминала на Mac работают также как и в терминале для Windows.

Создание репозитория для проекта

Рассмотрим как фиксировать и отслеживать изменения в проекте через систему контроля версий Git.

Для начала создаем папку проекта. Потом переходим в неё и проверяем какие файлы она содержит.

cd ~/Desktop/Projects/Keksholidays/
ls -1

Выглядит это примерно так:

На этом этапе мы можем начать использовать Git.

Сперва мы должны указать для Git имя и e-mail автора. Git записывает их в каждом изменении.

Все команды системы контроля начинаются со слова git. Используем следующую команду:

git config --global user.name "<your_name>"

Флаг --global сообщает git, что настройка будет применена для всех проектов, user.name — имя настройки.

В кавычках мы меняем <your_name> на имя автора.

Повторяем операцию для почты автора:

git config --global user.email "you@email"

И также в кавычках указываем почтовый адрес автора. Это нужно настроить один раз.

Теперь мы можем проверить все настройки, и что они сохранились, следующей командой:

git config --list

В терминале вы увидите примерно следующие строки:

user.name=michael
user.email=michael@gmail.com

Все настройки сохранены в файле .gitconfig и его содержимое мы можем посмотреть командой:

cat ~/.gitconfig

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

Теперь git настроен и можно сделать из нашего проекта репозиторий и начать отслеживать изменения.

Для этого мы инициализируем git командой:

git init

Мы увидим в ответ сообщение о том, что пустой репозиторий инициализирован:

Чтобы убедиться в том, что инициализация прошла успешно мы используем команду, которая покажет все файлы в каталоге, включая скрытые файлы:

ls -1 -a
// также можно писать команду короче ls -1a

Флаг -1 показывает файлы в столбик, а флаг -a показывает скрытые файлы.

Появилась папка .git. Она делает из простого проекта репозиторий. Её удалять нельзя, особенно, если вы еще не разбираетесь хорошо в том, что для чего нужно и как это работает. В этой папке хранится вся история изменений.

Дальше мы переходим к тем методам, которые будем использовать в каждом проекте. Изначально нам нужно понять какое у нас состояние репозитория. Делаем это командой:

git status

И мы увидим следующее:

Эта команда показывает состояние репозитория и мы видим, что у нас выводится фраза «On branch master«. Git сообщает нам, что мы находимся в ветке master. Про ветки и ветвления мы будем говорить в следующих разделах курса, а пока будем работать в этой главной ветке.

Также вы можете увидеть фразу «initial commit«, которая означает, что мы в самом начале и еще пока ничего не зафиксировали.

Далее мы видим «Untracked files«, где приводится список файлов, которые мы пока не отслеживаем. Изменения этих файлов пока не сохранены и не зафиксированы.

Мы видим, что файлы на данном этапе выделаны красным цветом и не отслеживаемы. Изначально у нас два типа файлов — tracked и untracked, т.е. отслеживаемые и не отслеживаемые. Первые файлы находятся под контролем версий и они были в последнем слепке состояния, а вторые — нет.

Сохранение состояния называется — коммитом (коммит, commit, фиксация). Сленговое выражение закоммитить означает зафиксировать изменения. Если у вас несколько коммитов, то вы можете вернуться к любому из них или посмотреть состояние этого коммита и что было в нем.

Нам нужно сообщить Гиту что именно мы хотим сохранить. На последнем скриншоте выше сам git нам подсказывает что нужно сделать — «git add» to track.

Добавим один файл командой:

git add index.html

И посмотрим статус Гита:

git status

В итоге видим такую картину:

Видим, что файл carousel.html стал зеленым и попал в изменения, для которых можно делать коммит, т.е. он проиндексирован. Мы можем проиндексировать все файлы командой:

git add .

В команде выше точка означает текущую папку. Если мы ставим точку, то git проиндексирует всю папку.

Справка. В терминале Cmder можно очистить окно командой clear.

Убедимся, что все файлы проиндексированы:

И вот теперь мы можем сделать наш первый коммит. Используем для этого комманду:

git commit -m "first setup of the project"

Флаг -m образуется от слова message (рус. — сообщение). Наше сообщение коротко описывает что было сделано в проекте до этого коммита.

Далее проверяем состояние командой:

git status

В терминале мы увидим следующие сообщения:

Нам нечего коммитить и текущее состояние у нас сохранено.

Далее мы можем менять файлы. При этом можем использовать те редакторы, которые нам удобнее всего, например Vim.

Справка. Удалить файл в терминале можно командой rm — от англ. remove, а если вы хотите удалить каталог со всеми подкаталогами и файлами в нем, используйте опцию -R.

Давайте откроем файл стилей в Vim:

$ vim style.css

Если вы не внесли никаких изменений и решили выйти из Vim, то нужно нажать последовательно Esc, затем : (двоеточие) и после написать q!.

Если вы внесли изменения и хотите их сохранить, то последовательно нажимаем Esc, потом : и после пишем: conf q. Жмем Enter. И теперь можем проверить, что изменилось:

$ git status

Видим, что файл был изменен — modified и выделен красным:

Чтобы узнать что было изменено в файле мы используем команду:

$ git diff

Здесь diff происходит от англ. слова difference (рус. — разница).

Здесь мы видим информацию в каком файле произошли изменения и какие строки были удалены (выделено красным) и добавлены (выделены зеленым).

Если изменения были в двух файлах, то терминал выведет их друг за другом.

Теперь мы можем сохраниться. Сначала индексируем измененные файлы:

$ git add carousel.html
// можно использовать также команду: git add .

Проверяем изменения командой git status и снова сделаем коммит:

$ git commit -m "Changed title"

Стоит ли делать коммиты чаще? Всё зависит от вас, но лучше всего делать коммиты тогда, когда изменения обрели какую-то законченную форму.

История коммитов нам покажет команда:

$ git log

Мы увидим два коммита для моего примера:

Здесь мы видим идентификатор для каждого коммита. Этот идентификатор еще называют словом хеш. Если коммитов много, то листаем в терминале коммиты стрелками. Закрыть лог можно клавишей q.

Копируем хеш коммита и вводим команду, чтобы посмотреть конкретный коммит:

$ git show 38a77c799f59acaa120cc4e984c8474fade5b633

Мы увидим те изменения, которые были сделаны и сохранены.

Также жмем q для выхода.

Создание веток и ветвления

В этом уроке мы поговорим про создание веток и ветвления в системе контроля версий Git.

Ветки, по своей сути, это две разных истории одного проекта. Ветвления и ветки являются самыми важными элементами Git.

Благодаря им вы всегда можете вернуться назад и отменить ошибки, сможете параллельно в команде работать над одним проектом. Каждый член команды сможет работать в своей ветке.

Давайте посмотрим наш лог коммитов:

$ git log --oneline

В предыдущих уроках мы использовали команду log без опций или с опцией -1, например. Здесь же мы добавили параметр --oneline. Он выводит коммит в одну строку, а не в пять, как при обычной комманде.

Давайте посмотрим один из коммитов:

$ git cat-file -p c39a182

Параметр -p мы добавили для удобства чтения. Коммит хранит информацию о том, кто и когда его сохрани, а также хеш родительского коммита.

При этом самый первый коммит не будет содержать родительского коммита.

Теперь нам снова понадобится команда checkout. Мы ее уже использовали в предыдущих уроках. Изначально команда checkout возвращает состояние файла до последнего коммита.

Если мы хотим перейти к какому-то коммиту на более ранних стадиях разработки, то вводим команду:

$ git checkout <commit_hash>

Где вместо <commit_hash> вводим имя нужного нам коммита, который мы посмотрели командой log.

Если после этой команды мы решим посмотреть историю через команду log, то увидим историю только до этого коммита, на который мы переключились.

Здесь важно понимать, что все коммиты никуда не исчезли на данном этапе, просто сама история показывается до последнего коммита.

Теперь можно вернуться к последнему коммиту через команду:

$ git checkout <commit_hash>

Но что если мы забыли или потеряли хеш последнего коммита? Это не страшно. В Git есть кодовое слово указатель master. Этот указатель приписывается последнему самому новому коммиту.

При этом мы можем задавать указатели любому коммиту. Вводим команду:

$ git checkout -b <commit_name> <commit_hash>

В терминале мы увидим:

Теперь, если мы посмотрим стату Git:

$ git status

То увидим, что нам консоль вывела следующее:

Ключевая фраза здесь в примере — On branch yellow-design. Нам это говорит о том, что мы теперь находимся на коммите yellow-design.

Проверяем командой:

$ git log --oneline --all

В консоли увидим следующее:

Здесь можно наблюдать и master и HEAD -> yellow-design. Слово HEAD указывает текущее положение и слово HEAD всегда в искусственном положении.

Что будет если изменить какие то файлы и закоммитить? Давайте изменим файл, проиндексируем его и создадим коммит.

Смотрим лог:

Куда-то делись другие коммиты, которые были после yellow-design. Здесь нам нужно использовать команду log с определенными опциями, чтобы увидеть всю картину целиком:

$ git log --online --all --graph

Мы выводим весь лог коммитов в одну строчку (--oneline), все коммиты (--all) и в виде наглядного графика (--graph).

Видим на скриншоте, что история коммитов раздвоилась, т.е. в проекте у нас теперь две ветки после коммита с хешем bc00f9f.

Наглядно это выглядит так:

Веткой называют всю историю коммитов, приводящих в текущую точку. Для master это такая ветка:

Для ветки yellow-design из нашего примера ветка такая:

Командой checkout можно перемещаться в любой коммит используя хеш или указатель ветки.

Выполнив команду git checkout master мы перейдем у точку с указателем master.

Можно создавать сколько угодно веток и коммитов. В итоге можем получить что-то вроде такого:

Но Git был бы не столь эффективен, если бы не было возможности объединять ветки. Давайте посмотрим на наше состояние проекта у которого две ветки:

Нам нужно теперь объединить коммиты из отдельных веток, но нам, также, нужно не потерять все изменения.

Нам понадобится для этого процедура мёрдж (англ. — merge или слияние). После слияния у нас будет один новый коммит, у которого будет два родителя.

Как мы видим — у нас два указателя и в новый коммит переместится указатель той ветки в которой мы находились.

Убедимся командой git status, что мы находимся в ветке master. И после этого мы должны влить ветку yellow-design в ветку master.

$ git merge yellow-design -m "your message"

В терминале выведется:

Теперь смотрим лог:

Мы можем создать новую ветку не указав хеш из текущего коммита:

$ git checkout -b <commit_name>

После этой команды мы можем переключаться между master и новым указателем (<commit_name>). Если мы сделаем новый коммит, то сдвинется указатель той ветки в которой мы находимся.

Вернуться в ветку master можно командой:

$ git checkout master

Обычно при командной разработке ветку master считают основной, даже если в проекте много других веток.

Отправка первого локального проекта на GitHub

Одна из полезных привычек, которые я в себе последнее время воспитываю — это привычка работать с проектами и использовать Git даже в тех случаях, если проект создан локально и нужен, например, для обучения. Потому как мало ли что может вырасти в будущем даже из небольшого учебного проекта.

Рассмотрим отправку (push) своего первого проекта с локального компьютера в GitHub репозиторий.

Убедитесь, что git отслеживает ваш проект

1. Используя свой терминал (командную строку), зайдите в папку, где хранятся файлы вашего проекта: cd /path/to/my/codebase.

Я использую Cmder и очень доволен данным терминалом. Также, если вы используете для разработки на PHP Open Server, то в нем есть встроенная консоль.

Важно понимать, что в Cmder есть две версии для скачивания и Git есть только в версии Full.

Вы не можете сделать это, просто открыв папку как обычно, вы должны сделать это с помощью командной строки / терминала.

2. Проверьте, инициализирован ли git командой git status.

Вы можете получить такое сообщение об ошибке:

$ git
fatal: Not a git repository (or any of the parent directories): .git

Это означает, что папка, в которой вы находитесь, не отслеживается git. В этом случае инициализируйте git внутри папки вашего проекта, набрав команду

$ git init

Если вы получили другое сообщение об ошибке, то внимательно на него посмотрите. Как правило, дополнительные ошибки появляется либо когда git не установлен на вашем компьютере, либо когда вы уже находитесь в папке или подпапке, где инициализируется git.

Если всё нормально, то далее выполните процесс добавления и «фиксации» вашего проекта — команды git add и git commit. Но об этом будем говорить дальше.

Напоминаю, что проверить настройки Git и пользователя в Cmder можно командой:

$ cat ~/.gitconfig

Тильда — это адрес вашего домашнего каталога.

Проверяем пользователя git локального компьютера

После инициализации Git нельзя удалять папку .git.

Создайте удаленный репозиторий на Github

  1. Войдите в свою учетную запись Github.
  2. В правом верхнем углу любой страницы Github вы должны увидеть значок «+». Нажмите на это, затем выберите ‘New Repository’ (рус. — Новый репозиторий).
  3. Дайте вашему хранилищу имя — в идеале то же имя, что и у вашего локального проекта. Если я создаю приложение для путешествий, его папка будет называться «travel-app» на моем компьютере, а «travel-app» будет также именем репозитория Github.
  4. Нажмите ‘Create Repository’ (рус. — Создать репозиторий). Следующий экран, который вы увидите, будет важен, поэтому не закрывайте его.

Подключите локальную папку проекта к вашему пустому хранилищу на Github

Сейчас на сайте github вы видите страницу у которой в заголовке написано: «Quick setup — if you’ve done this kind of thing before«.

Скопируйте ссылку в поле формы (input) прямо под заголовком, она должна выглядеть примерно так:

https://github.com/mindplace/test-repo.git

Это веб-адрес (ссылка), который будет использовать ваша локальная папка для отправки содержимого в удаленную папку на Github.

1. Вернитесь к своему проекту в терминале / командной строке.

2. В вашем терминале / командной строке введите:

$ git remote add origin [скопированная ссылка]

Наш пример:

$ git remote add origin https://github.com/mindplace/test-repo.git

3. Отправьте (сделайте пуш, push) вашей ветки в Github:

$ git push origin master

4. Вернитесь к экрану репозитория на Github, который вы только что оставили, и обновите его. Название «Quick setup — if you’ve done this kind of thing before«. Название должно исчезнуть, и вы должны увидеть свои файлы в репозитории.

Важное замечание. При создании репозитория на GitHub лучше не ставить галочку в пункт где спрашивается про создание файлы README.md, иначе могут возникнуть проблемы при отправки локальных файлов в репозиторий.

Что лучше сделать перед отправкой локальных файлов

Перед отправкой локальных файлов в удаленный репозиторий лучше всего проиндексировать все файлы нашего нового проекта.

После команды git init мы можем командой git status увидеть, что не все файлы находятся в индексе.

Чтобы проиндексировать все файлы текущей папки мы вводим команду:

$ git add .

Точка означает текущую папку.

После того как все файлы проиндексированы мы должны закоммитить наши действия, т.е. зафиксировать:

$ git commit -m "Начало проекта"

Я бы посоветовал делать комментарий не на русском как в примере выше, а на английском. Это будет хорошей привычкой. Т.е. вместо «начало проекта» хорошо бы написать «start project».

Далее командой git status мы проверяем, что всё сделали правильно и видим такой экран:

Перечислю еще несколько полезных команд для работы с Гитом ниже.

$ git log

Показывает историю коммитов.

$ git show a67105fe991a8318asfsdfsd3453sdffsdf

Команда выше показывает через хеш коммита какие изменения были произведены.

Работа с двух компьютеров

Рассмотрим в этом уроке как получить проект из GitHub на локальную машину и как работать с проектом на двух компьютерах, например, из дома и с работы.

Клонирование — получение всего репозитория. На гитхабе раньше была кнопка Clone or Download. Но затем этот блок изменили и теперь есть кнопка Code при нажатии на которую появляются инструменты клонирования и скачивания.

Самое популярное решение — клонирование репозитория по протоколу SSH (см. скриншот). Но также можно выбрать HTTPS протокол или просто скачать ZIP-архив.

Раньше при использовании HTTPS и каждой отправке изменения или получении репозитория нужно было вводить пароль от Гитхаба. При использовании SSH мы один раз генерируем ключи на каждом компьютере и добавляем их в Гитхаб.

При этом мы уже знаем, что приватный SSH ключ мы можем защитить паролем, что улучшает безопасность использования данного метода.

Даже если кто-то украдет ваш ключ, вы просто удалите его из Гитхаба в Настройках (Settings) и зададите новый.

Но бывает так, что SSH не работает по каким-либо причинам — настройка сети в организации или по другой причине. Тогда у нас остается вариант работы только с HTTPS.

Мы выбираем SSH. Копируем на github адрес и вставляем в терминал:

$ git clone <ssh_key>

Вот так проходит процесс клонирования:

Теперь посмотрим лог:

$ git log --oneline

Мы увидим все коммиты:

Также мы видим, что находимся в ветке master. Кроме того есть еще два дополнительных указателя — origin/master и origin/HEAD.

Указатель origin — это имя удаленного репозитория и так принято его называть в мире разработчиков. Мы можем проверить это таким образом:

$ git remote -v

В гитхабе HEAD всегда будет указывать на master, если вы не измените этого сами в настройках репозитория на самом Гитхабе.

Теперь, если после клонирования мы сделаем новый коммит, то он не появится на Гитхабе, а будет только на локальной машине. Поэтому для отправки изменений в удаленный репозиторий есть команда push (рус. толкать или отправить), а для получения pull (рус. — тянуть).

Отправляем новые изменения следующей командой:

$ git push origin master

Этот процесс займет немного времени и терминал выведет:

Если мы создаем ветки и коммиты локально, что они не появляются на Гитхабе автоматически. Если мы создаем ветку comments, то команда отправки на Гитхаб всех изменений будет выглядеть так:

$ git push origin comments

И мы увидим отчет в терминале, что изменения отправлены:

При этом мы теперь на самом GitHub сможем выбрать нужную нам ветку:

При этом важно понимать, что для разных веток состояние репозитория будет отличаться, если в ветках сделаны разные изменения.

Если мы сделали ошибку в названии ветки, но хотим это исправить, то нам нужно сделать пуш в правильную ветку вот такой командой:

$ git push origin cmments:comments

Таким образом можно отправить любую локальную ветку в удаленную ветку даже если у них разные имена. При этом старая ветка на GitHub останется.

Чтобы удалить старую ветку, которая нам теперь не нужна, мы используем команду:

$ git push origin :cmments

Т.е. мы, условно, пушим «ничего» в старую ветку в удаленный репозиторий. Но теперь на удаленном репозитории старой ветки нет, а локально она есть со старым названием. Нам нужно использовать на локальной машине в терминале такую команду:

$ git branch -m comments

Команда branch может переименовывать, создавать и удалять ветки.

Справка. Команда git checkout -b branch-name создаст ветку с указанным именем и автоматически переключится на неё. Для переключения на существующую ветку выполните команду git checkout. Для переключения, например, на ветку testing используем команду $ git checkout testing. В результате указатель HEAD переместится на ветку testing.

Чтобы нам наглядно посмотреть ветки в CMDER мы используем команду:

$ git log --oneline --graph --all

Допустим, вы сделали коммиты на рабочем компьютере и теперь хотите поработать дома. Нам нужно получить эти коммиты на домашний компьютер.

Если нам нужно получить изменения ветки master, значит нам нужно быть в ветке master. Для этого убеждаемся, что мы находимся в ветке master:

$ git status

И далее вводим команду:

$ git pull origin master

Что делать, если кроме ветки master нам нужна ветка, которая создана в удаленном репозитории и про которую локальный Git ничего не знает?

Для этого мы используем команду fetch (рус. -получить, принести):

$ git fetch origin

Эта команда позволит забрать изменения из удаленной ветки:

Схематично это выглядит так:

Указатели origin/master и origin/comments (из примера) нельзя удалить или переименовать.

Теперь для примера мы создадим ветку comments, которая будет указывать на тот же коммит, что и origin/comments:

$ git checkout -b comments origin/comments

Если вы внесли изменения в файлы и сделали новые коммиты на домашнем компьютере, то нам нужно отправить их в GitHub, чтобы иметь возможность работать с новыми изменениями с рабочего компа.

Для ветки comments мы можем написать следующую команду:

$ git push origin comments

Но что, если мы хотим всё время пушить comments в comments на GitHub, а локальный master в удаленный master? У нас есть возможность связать локальную ветку с удаленной:

$ git branch --set-upstream-to=origin/comments

В примере выше вместо origin/comments вы можете указать имя удаленной ветки с которой вы хотите связать текущую.

Теперь находясь в этой ветке нет необходимости писать названия веток для команды git push или git pull.

Чтобы посмотреть какие локальные ветки связаны с удаленными мы используем:

$ git branch -vv

Терминал нам покажет какие ветки с какими связаны:

Видно, что comments связана с веткой origin/comments и отмечена звездочкой — мы в ней находимся, а master связан с origin/master.

Теперь мы просто можем писать в терминале:

$ git push

Т.е. мы не вводили имена веток.

Отправляем код на GitHub и настраиваем SSH-ключи

Рассмотрим как нам отправить код проекта на GitHub и настроить SSH-ключи для работы с системой контроля версий.

Большинство компаний используют разные сайты — GitHub, GitLab, BitBucket и др. Но мы будем использовать GitHub.

Переходим на сайт github.com и регистрируемся, если вы этого еще не сделали.

Вводим имя пользователя (Username), почту (Email) и пароль (Password). После чего Giyhub спросит про тариф. Выбираем бесплатный. Вы увидите фразу: Unlimited public repositories for free. Это то, что нам нужно.

В конце рассказываем про опыт и всё, регистрация завершена. Этот шаг можно пропустить.

Теперь мы можем опубликовать первый проект. Нажимаем Start a project.

И вводим имя нашего первого проекта и репозиотория:

Далее выбираем тип репозитория — Публичный (public) или Приватный (private). Приватный репозиторий — платная услуга. Публичный репозиторий будет доступен всем в Интернете.

Дальше нас GitHub спросит про создание файла README для проекта. Мы не будем ставить галочку, т.к. у нас уже есть локальный проект с историей.

Теперь жмем Create Repository (создать репозиторий).

Репозиторий создан и мы сразу видим, что Github подсказывает что нам делать далее. У нас сразу есть возможность выбрать протокол — HTTPS или SSH. Мы выбираем SSH.

Т.к. у нас уже есть репозиторий локально, то нам нужно обращать внимание на команды в этом блоке: …or push an existing repository from the command line. Мы будем использовать команды из него.

Т.е. мы используем в Cmder команду:

$ git remote add origin https://github.com/sergeiermilov/uzabila-carousel.git

В удаленный репозиторий можно отправлять файлы и получать их из него.

Сама команда git remote add — добавляет удаленный репозиторий, а origin — общее признанное имя. Проверим, что репозиторий добавился:

$ git remote -v

Посмотрим что покажет терминал:

Git показал нам две origin строчки — fetch и push. Fetch — это мы можем забирать изменения, а Push — отправлять изменения.

Дальше GitHub нам рекомендовал команду:

$ git push -u origin main
// или git push -u origin master

Если вы увидели ошибку:

error: src refspec master does not match any.  
error: failed to push some refs to 'ssh://xxxxx.com/project.git'

То это, скорее всего, означает, что имя ветки не совпало с указанным в команде. Например в коде выше я ввел:

$ git push -u origin main

Хотя моя ветка называлась master.

Далее мы получаем ошибку:

Permission denied (publickey).
Fatal: Could not read from remote repository.

GitHub не может нас узнать, т.к. мы авторизованы в браузере, но не в консоли. Мы добавили репозиторий с протоколом SSH — протоколом безопасного соединения между компьютерами. Его используют не только на GitHub, так, через SSH системные администраторы управляют серверами.

Чтобы авторизоваться в GitHub по SSH нам нужно сгенерировать SSH-ключи — публичный и приватный. Приватный ключ нужно держать в секрете.

В домашней папке создаем папку .ssh и перейдем в нее:

$ mkdir ~/.ssh
$ cd ~/.ssh

Теперь генерируем пару ключей командой:

$ ssh-keygen -t rsa -b 4096 -C "<your_email>"

Пару ключей для Github мы генерируем только один раз.

Теперь нас спросят про название ключа, где пишем свое имя, т.к. лучше не использовать стандартное, которое предлагает терминал. После этого нас попросят указать пароль. Здесь мы можем оставить пароль пустым и нажать Enter. И теперь еще раз Enter для подтверждения пароля.

Теперь в папке .ssh будут два файла — один без расширения — приватный ключ, а второй с расширением .pub — публичный ключ.

Публичный ключ мы должны загрузить на Github и для этого мы переходим на сайт github.com и далее переходим в Настройки (Settings). В настройках выбираем пункт: SSH and GPG keys.

Жмем New SSH key.

Вводим название (title) и далее нам нужно в поле ключ (key) вставить содержимое ключа, которое мы скопируем из консоли после использования команды cat, и здесь используем публичный ключ. В названии я использую имя компьютера на котором работаю, но можно вводить что угодно.

Выделяем ключ (весь текст от слова ssh-… вместе с email), копируем его в Github и далее жмем Add SSH key:

Теперь нужно проверить, что github нас узнает (указываем приватный ключ):

$ ssh -T -i ~/.ssh/<file_name_private_key> git@github.com

Github с нами поздоровается:

Проверка связи с сайтом без приватного ключа приведет к ошибке:

$ ssh -T git@github.com
// Ошибка: Permission denied (publickey)

Чтобы при соединении с GitHub всегда использовался нужный ключ мы должны в настройках SSH указать этот ключ. Настройки SSH хранятся в папке .ssh и в файле config локального домашнего пользователя. Добавляем информацию об использовании для хоста github.com определенный ключ:

Host github.com
	IdentityFile ~/.ssh/<key_file_name>

Обратите внимание на отступ во второй строке и что используется приватный ключ:

Теперь заново пробуем соединиться с гитхабом:

$ ssh -T git@github.com

Теперь всё получилось:

Теперь мы можем вернуться в репозиторий и отправить изменения на GitHub:

$ git push -u origin master

Если перейти на Гитхаб и посмотреть репозиторий, то мы увидим все файлы, которые были отправлены из локального репозитория.

Откатываем изменения

Рассмотрим в этом уроке что делать, если что-то пошло не так и как «откатить» сделанные изменения в сервисе контроля версий Git.

По традиции текущее состояние мы узнаем командой:

$ git status

Если мы видим, что какой-то файл находится в статусе modified и отмечен красным цветом, то нам нужно посмотреть какие изменения были сделаны в файле или файлах:

$ git diff

Откатить изменения можно командой:

$ git checkout <file_name>

И теперь если мы проверим статус гита, то не увидим никаких предупреждений о модифицированном файле.

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

К примеру, если мы удалим файл, то проверка статуса Git покажет, что файл отмечен словом deleted. Восстановить его можно этой же командой:

$ git checkout <file_name>

Команда checkout возвращает состояние файла до последнего коммита, но вернуть состояние до checkout мы уже не сможем. Всё что вы не коммитили — потеряется, поэтому сбрасываете только те изменения, которые вам не нужны.

Мы можем также вернуть состояние файла до какого-либо коммита. Для этого нам нужно знать хеш коммита, который мы можем посмотреть после использования команды:

$ git log

Копируем хеш нужного нам коммита и вводим команду в консоли:

$ git checkout <commit_hash> <file_name>

Заменяем <commit_hash> на хеш коммита, а <file_name> на имя нужного файла, состояние которого мы хотим вернуть.

После чего мы смотрим статус и видим, что наш файл изменен и уже проиндексирован.

Нам нужно посмотреть изменения в этом файле. Мы используем знакомую нам команду diff, но с использованием дополнительного флага —staged:

$ git diff --staged

Команда diff нам показывала не проиндексированные изменения, а добавление флага нам позволяет смотреть проиндексированные изменения. Индекс часто называют «staged area».

Теперь мы можем делать коммит знакомой нам командой:

$ git commit -m "your message here"

Теперь допустим ситуацию, когда вы подготовили изменения к коммиту и добавили их в индекс, но решили, что один из файлов не нужен в индексе. Как удалить его из индекса?

К примеру, у нас есть два файла в статусе modifiedindex.html и main.css, и при этом мы не хотим включать index.html в коммит. Тогда мы используем следующую команду:

$ git reset HEAD index.html

После проверим статус и увидим следующее:

Статус нам показывает, что изменения в main.css проиндексированы, а в index.html не проиндексированы. И если мы сделаем коммит, то в него попадут только изменения в main.css.

На скриншоте команда status показывает, что изменения файла index.html не проиндексированы.

Теперь мы можем проиндексировать этот файл и сделать коммит. Так делать удобно, когда мы хотим сделать коммиты для разных целей, как в данном случае, когда мы сможем выбирать с чем работать потом — со стилями или с основным файлом.

Вводим далее:

$ git add index.html
$ git commit -m "made changes in index file"

Не забываем проверить статус и посмотреть лог. Также мы можем посмотреть изменения в конкретном коммите через команду show и хеш коммита:

$ git show <commit_hash>

Что если при создании коммита мы сделали ошибку в сообшении (подписи)? Возможно ли исправить ошибку?

Если мы увидели, что в последнем коммите есть ошибка в сообщении, то для начала мы используем команду:

$ git log -1

Флаг -1 говорит терминалу показать только последний коммит, а флаг -2 показывает два коммита, -3 — три и т.д.

Чтобы исправить сообщение коммита мы используем команду:

$ git commit --amend -m "correct message"

Параметр amend позволяет изменить последний коммит.

Кроме изменения в сообщения изменяется также и хеш коммита, что говорит нам о том, что по-сути мы создали новый коммит.

Также есть возможность удалить из коммита лишний файл. Для этого мы используем команду:

$ git rm <file_name>

Если после этой команды мы посмотрим гит статус, то увидим, что файл будет помечен как deleted (рус. — удаленный). Теперь мы применяем команду:

$ git commit --amend --no-edit

В данном случае опять хеш коммита изменится.

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

$ git rm --cached <file_name>

Теперь мы увидим следующее:

Видим, что файл test.css одновременно в статусе deleted и untracked (рус. — не отслеживается). Используем команду:

$ git commit --amend --no-edit

Теперь файл не находится в коммите, но не удален из папки.

Если вам нужно посмотреть информацию про разные команды гита, то вы можете использовать команду help:

$ git help checkout

Команда выше покажет справку по команде checkout, что с ней можно делать и какие флаги (опции) с ней можно использовать. Листать справку можно стрелками с клавиатуры вверх и вниз.

Конфликты и ошибки

Рассмотрим возможности разрешения конфликтов при работе в системой контроля версий Git.

Чаще всего конфликты возникают при слиянии веток. Например, когда один и тот же файл проекта менялся по разному в разных ветках. В одной ветке вы в файле удалили строчку, а в ветке master вы изменили эту же строчку в этом же файле.

При слиянии этих двух веток возникнет конфликт, т.к. Git не способен за вас решить какие из всех изменений более правильные и не будет сливать ветки автоматически. Git предложит вам разрешить конфликт.

Давайте попробуем слить две ветки из нашего примера командой:

$ git merge <commit_name>

Получим следующее сообщение:

Где видно, что Git предупреждает о конфликте: Merge conflict in index.html. Также на скриншоте видно, что в файлом css/button.css всё прошло хорошо и слияние было успешным.

Проверяем всё командой:

$ git status

При этом Гит нам подсказывает что можно сделать:

Он рекомендует исправить конфликты и закоммитить результат: fix conflicts and run «git commit».

Мы видим для файла index.html статус both modified. Это значит, что он изменен в обоих ветках.

Открываем файл в редакторе.

$ vim index.html

Вот как будет выглядеть файл в редакторе Vim:

В файле появились какие-то непонятные символы — стрелки, равно и указатели HEAD и search-page (выделено на скриншоте серым цветом). Так выглядит типичный конфликт.

Код между угловыми скобками и до равно — это код в файле в ветке в которой мы находимся. А после равно и до вторых угловых скобок — код в ветке, которую мы хотим слить с основной.

Нам нужно выбрать один из вариантов или оставить оба варианта и удалить все эти разделители. После этого мы сохраняем файл и делаем коммит.

$ git add index.html
$ git commit -m "merged search-page to master"

Далее посмотрим что у нас получилось:

$ git log --oneline --graph -6

Получаем такой лог:

Мёрдж прошел успешно, что мы видим в логе там где HEAD.

Если есть конфликт в ситуации когда в одной ветке файл удален, а в другой изменен, то этот конфликт разрешается таким же образом.

Например, у нас такая ситуация и git status показывает следующее:

Здесь у нас странный статус: deleted by us (рус. — удален нами). Текущая ветка по мнению Гит — мы (us), а ветку, которую мы вливаем, — они (they).

В итоге, для разрешения конфликта нам нужно либо удалить файл, либо сохранить.

Если мы оставляем файл, то используем команду:

$ git add <file_name>

Если мы хотим удалить файл из индекса, то используем известную нам команду rm:

$ git rm <file_name>

После этого делаем коммит и дальше проверяем лог командой:

$ git log --oneline --graph -5

Конфликт разрешен. Всё хорошо. Решать конфликты не сложно.

Код в чужой репозиторий или помогаем другу

Рассмотрим как нам присылать код в чужой репозиторий и как мы можем помогать другим в сервисе контроля версий Git.

Мы не можем просто так клонировать чужой проект, внести изменения и запушить их в чужой репозиторий, т.к. изменения могут попасть в проект только с согласия автора.

Для начала нам нужно «форкнуть» (от слова «форк» — fork) проект к себе в Гитхаб. И тогда, в свою копию, можно будет пушить изменения.

Форк — это копия репозитория, которым вы управляете. Форки позволяют вносить изменения в проект, не затрагивая исходный репозиторий. Вы можете получать обновления из исходного репозитория или отправлять изменения в него с помощью pull requests (пулл реквесты или, дословно, — запросы на вытягивание).

Открываем в GitHub нужный нам проект, репозиторий. И находим кнопку Fork.

Теперь у нас в Гитхабе есть полная копия данного проекта со всеми коммитами и ветками. Также теперь можно клонировать любой репозиторий, но пуш можно делать будет только в свой проект, а не в проект с которого сделан форк.

Сначала мы клонируем репозиторий командой:

$ git clone git@github.com:sergeiermilov/markdown-doc.git

После чего проверяем, так называемые ремоуты:

$ git remote -v

Получаем примерно такой ответ:

Теперь мы можем спокойно работать над проектом. После того как мы закончим работу и внесем нужные изменение мы сможем сформировать запрос на вливание или pull request.

Сначала мы делаем пуш (пример):

$ git push -u origin share-icons

Флаг -u обозначает upstream, устанавливает связь между локальной веткой и удаленной.

Дальше мы переходим в GutHub и видим, что гитхаб видит наш пуш и предлагает сделать pull request. Мы жмем зеленую кнопку Compare & Pull Request.

Дальше мы должны заполнить форму — что было сделано и зачем — заголовок и описание. Ниже в этом же окне мы можем посмотреть разницу между ветками, так называемый diff или дифф (от слова — difference — разница).

Жмем кнопку Create Pull Request:

Теперь можно сказать, что пулл риквест открыт. Автор изначального репозитория, с которого мы делали форк, сможет посмотреть изменения и принять их или отклонить.

Открытые pull request всегда показывают актуальную разницу между ветками.

Важно понимать, что форк на Github не синхронизирован с оригиналом автоматически. Но что если в оригинальном репозитории производились какие-либо изменения?

Нужно к себе добавить ремоуты (от англ. — remote). Мы должны зайти в оригинальный репозиторий и скопировать SSH-адрес.

Теперь мы можем ввести локально такую команду:

$ git remote add <rep_name> <ssh_address>

Где <rep_name> — имя репозитория (вы назначаете сами), а <ssh_address> — скопированный SSH-адрес.

Далее переключаемся в master:

$ git checkout master

И забираем изменения:

$ git pull <rep_name> master

Теперь можно это всё отправить в свой Гитхаб:

$ git push origin master

Бывают ситуации, когда появляется конфликт между изменениями pull request и изменениями в оригинальном репозитории. Это происходит если автор оригинального репозитория внес какие-то изменения в ветку master. Сообщение о конфликте мы увидим на странице пулл риквеста.

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

Конфликт можно решить у себя. Для этого мы должны влить изменения мастера автора к себе и внести изменения у себя локально. После этого, если мы сделаем push, то конфликт должен исчезнуть и можно будет сделать pull request.

Коротко весь процесс выглядит так: Fork -> Внесение изменений -> Pull Request. При этом на Гитхабе можно форкнуть любой публичный репозиторий.

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

С этим своим репозиторием мы можем теперь спокойно работать и вносить в него изменения.

Далее нам нужно его (форк) клонировать на свою локальную машину.

Схематично во время обучения в HTMLAcademy процесс выглядел так:

Или так немного нагляднее:

Т.е. мы сделали форк и дальше клонируем репозиторий на локальный компьютер:

Далее мы создаем отдельную ветку:

В этой ветке мы вносим нужные нам изменения, далее индексируем изменения и делаем коммит.

Дальше, мы делаем пуш, т.е. отправляем изменения на Гитхаб:

После чего GitHub предложит сделать pull request.

Что делаем дальше, если дается новое задание? Возвращаемся в Git и переключаемся на ветку master.

Дальше нужно установить связь (ремоут) не только с личным репозиторием, но и с репозиторием от которого делали форк.

Как видим на скриншоте — у нас есть ремоут только с личным репозиторием.

Добавим основной репозиторий:

Эту команду мы уже использовали выше:

$ git remote add <rep_name> <ssh_address>

Как видим, у нас теперь есть дополнительные ремоуты:

Теперь обновляемся и делаем pull изменений:

Делаем pull из основного репозитория. И теперь сможем работать и вносить изменения на локальной машине.

Проверка SSH-соединения с GitHub

После того, как вы настроили свой SSH-ключ и добавили его в свою учетную запись GitHub, вы можете проверить свое соединение.

Перед проверкой SSH-соединения вы можете сделать:

  1. Проверку существующих ключей SSH
  2. Создать новый ключ SSH и добавить его в ssh-agent
  3. Добавить новый SSH-ключ в вашу учетную запись GitHub

Проверка существующих ключей SSH

Перед тем, как сгенерировать SSH-ключ, вы можете проверить, есть ли у вас существующие SSH-ключи.

Примечание. Ключи DSA (SSH-DSS) больше не поддерживаются. Существующие ключи будут продолжать работать, но вы не сможете добавлять новые ключи DSA в свою учетную запись GitHub.

1. Откройте Терминал (Terminal).

1. Откройте Git Bash.

1. Откройте Терминал (Terminal)

2. Введите ls -al ~/.ssh, чтобы узнать, есть ли существующие ключи SSH:

$ ls -al ~/.ssh
# Lists the files in your .ssh directory, if they exist

Проверьте список каталогов, чтобы увидеть, есть ли у вас уже публичный SSH ключ. По умолчанию, имена файлов публичных ключей являются одними из следующих:

  • id_rsa.pub
  • id_ecdsa.pub
  • id_ed25519.pub

Если у вас нет существующей пары публичных и приватных ключей, или вы не хотите использовать любую доступную пару для подключения к GitHub, сгенерируйте новый SSH-ключ.

Если вы видите существующую пару публичных и приватных ключей (например, id_rsa.pub и id_rsa), которые вы хотите использовать для подключения к GitHub, вы можете добавить SSH-ключ в ssh-agent.

Подсказка. Если вы получили ошибку, что ~/.ssh не существует, не волнуйтесь! Мы создадим его, когда сгенерируем новый SSH-ключ.

Создание нового ключа SSH и добавление его в ssh-agent

После того, как вы проверили существующие SSH ключи, вы можете сгенерировать новый SSH ключ для аутентификации, затем добавить его в ssh-agent.

Если у вас еще нет SSH ключа, вы должны сгенерировать новый SSH ключ. Если вы не уверены, есть ли у вас уже SSH-ключ, проверьте существующие ключи.

Если вы не хотите вводить вашу ключевую фразу каждый раз, когда вы используете SSH-ключ, вы можете добавить ваш ключ к SSH-агенту, который управляет вашими SSH-ключами и запоминает вашу ключевую фразу.

1. Откройте Терминал (Terminal).

1. Откройте Git Bash.

1. Откройте Терминал (Terminal)

2. Вставьте текст ниже, подставив свой адрес электронной почты на GitHub.

$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"

Это создает новый ключ ssh, используя указанный адрес электронной почты в качестве метки.

> Generating public/private rsa key pair.

Когда появится запрос «Ввести файл, в котором нужно сохранить ключ», нажмите Enter. При этом принимается расположение файла по умолчанию.

> Enter a file in which to save the key (/c/Users/you/.ssh/id_rsa):[Press enter]

В приглашении введите защищенную ключевую фразу. Дополнительную информацию мы осветим в следующей статье по Git — «Работа с ключевыми фразами SSH».

> Enter passphrase (empty for no passphrase): [Type a passphrase]
> Enter same passphrase again: [Type passphrase again]

Добавление вашего SSH-ключа в ssh-agent

Перед добавлением нового SSH-ключа в ssh-agent для управления вашими ключами, вы должны были проверить существующие SSH-ключи и сгенерировать новый SSH-ключ.

Если у вас установлен GitHub Desktop (для рабочего стола), то вы можете использовать его для клонирования репозиториев и не работать с SSH-ключами.

Убедитесь, что ssh-agent запущен. Или вы можете запустить его вручную:

# start the ssh-agent in the background
$ eval $(ssh-agent -s)
> Agent pid 59566

Добавьте ваш приватный ключ SSH к ssh-agent. Если вы создали ключ с другим именем, или если вы добавляете существующий ключ с другим именем, замените id_rsa в команде на имя файла с вашим приватным ключом.

$ ssh-add ~/.ssh/id_rsa

Далее нужно добавить ключ SSH в свою учетную запись GitHub.

Добавление ключа SSH в свою учетную запись GitHub

Чтобы настроить учетную запись GitHub для использования нового (или существующего) ключа SSH, вам также необходимо добавить его в свою учетную запись GitHub.

Прежде чем добавлять новый SSH-ключ в вашу учетную запись GitHub, вы должны были:

  • проверить наличие существующих ключей SSH;
  • сгенерировать новый ключ SSH и добавить его в ssh-agent.

После добавления нового ключа SSH в свою учетную запись GitHub вы можете перенастроить любые локальные репозитории для использования SSH. Про переключение удаленных URL-адресов с HTTPS на SSH мы поговорим в следующих статьях.

Примечание. Ключи DSA (SSH-DSS) больше не поддерживаются. Существующие ключи будут продолжать работать, но вы не сможете добавить новые ключи DSA в свою учетную запись GitHub.

1. Скопируйте ключ SSH в буфер обмена.

Если ваш SSH-файл ключа имеет другое имя, чем в примере, измените имя файла, чтобы оно совпадало с вашими текущими настройками. При копировании ключа не добавляйте новые строки или пробелы.

Mac

$ pbcopy < ~/.ssh/id_rsa.pub
# Copies the contents of the id_rsa.pub file to your clipboard
Совет. Если pbcopy не работает, вы можете найти скрытую папку .ssh, открыть файл в своем любимом текстовом редакторе и скопировать его в буфер обмена.

Windows

$ clip < ~/.ssh/id_rsa.pub
# Copies the contents of the id_rsa.pub file to your clipboard
Совет. Если clip не работает, вы можете найти скрытую папку .ssh, открыть файл в любимом текстовом редакторе и скопировать его в буфер обмена.

Linux

$ sudo apt-get install xclip
# Downloads and installs xclip. If you don't have `apt-get`, you might need to use another installer (like `yum`)

$ xclip -selection clipboard < ~/.ssh/id_rsa.pub
# Copies the contents of the id_rsa.pub file to your clipboard
Совет. Если xclip не работает, вы можете найти скрытую папку .ssh, открыть файл в любимом текстовом редакторе и скопировать его в буфер обмена.

2. В правом верхнем углу любой страницы кликните на свою фотографию в профиле, затем нажмите кнопку Settings (Настройки).

3. На боковой панели настроек пользователя нажмите «SSH и GPG ключи» (SSH and GPG keys).

4. Нажмите кнопку «Новый SSH ключ» (New SSH key) или «Добавить SSH ключ».

5. В поле «Заголовок» (Title) добавьте описательную метку для нового ключа. Например, если вы используете персональный Mac, вы можете назвать эту клавишу «Personal MacBook Air».

6. Вставьте свой ключ в поле «Ключ» (Key).

7. Нажмите кнопку «Добавить SSH ключи» (Add SSH key).

8. Если появится форма подтверждения — подтвердите пароль GitHub.

Проверка SSH-соединения

После того, как вы настроили свой SSH-ключ и добавили его в свою учетную запись GitHub, вы можете проверить соединение.

Перед тестированием вашего SSH соединения, вы должны были:

  • проверить наличие существующих ключей SSH;
  • сгенерирован новый ключ SSH;
  • добавить новый SSH-ключ к учетной записи GitHub.

Когда вы тестируете ваше соединение, вам нужно будет аутентифицировать это действие, используя ваш пароль, который является ключевой парольной фразой SSH, созданной вами ранее.

1. Откройте Терминал (Terminal).

1. Откройте Git Bash.

1. Откройте Терминал (Terminal)

2. Введите следующее:

$ ssh -T git@github.com
# Attempts to ssh to GitHub

Вы можете увидеть такое предупреждение:

> The authenticity of host 'github.com (IP ADDRESS)' can't be established.
> RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
> Are you sure you want to continue connecting (yes/no)?

или такое:

> The authenticity of host 'github.com (IP ADDRESS)' can't be established.
> RSA key fingerprint is 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48.
> Are you sure you want to continue connecting (yes/no)?

Убедитесь, что отпечаток (fingerprint) в сообщении, который вы видите, совпадает с одним из сообщений на шаге 2, затем введите yes:

> Hi username! You've successfully authenticated, but GitHub does not
> provide shell access.

Убедитесь, что полученное сообщение содержит ваше имя пользователя. Конечно, вы можете получить сообщение «разрешение отклонено», но об этом мы поговорим в следующих статьях.

Ошибки Git

Ниже я дополняю данный курс разбором основных ошибок, которые появляются при работе с Git и Github.

fatal: refusing to merge unrelated histories

Git-ошибка «fatal: refusing to merge unrelated histories» возникает при слиянии двух несвязанных проектов (т.е. проектов, которые не знают о существовании друг друга и имеют несовпадающие истории коммитов).

Рассмотрим следующие два случая, в которых возникает эта ошибка:

  1. Вы клонировали проект, и каким-то образом каталог .git был удален или поврежден. Это привело к тому, что Git не знает о вашей локальной истории и поэтому выдает эту ошибку при попытке push в удаленный репозиторий или pull из него.
  2. Вы создали новый репозиторий, добавили в него несколько коммитов, а теперь пытаетесь извлечь из удаленного репозитория, в котором уже есть несколько собственных коммитов. Git также выдаст ошибку в этом случае, поскольку он не имеет представления о том, как связаны эти два проекта.

Решение

Ошибка устраняется переключением переключателя allow-unrelated-histories. После команды git pull или git merge добавьте следующий тег:

git pull origin master --allow-unrelated-histories

Больше информации можно найти по этой ссылке​ в официальной документации Git.

Словарь и команды Github

Для понимания некоторых слов из терминологии разработчиков и их использования — используйте этот небольшой словарик:

  • git (рус. — гит) — система контроля версий
  • github (рус. — гитхаб) — сервис репозиториев и совместной разработки
  • репозиторий — хранилище (каталог) файлов проекта
  • локальный репозиторий — репозиторий, расположенный на локальном компьютере программиста
  • удалённый репозиторий — репозиторий, находящийся на удалённом сервере
  • fork (рус. — форк) — копия репозитория или внешняя ветка текущего репозитория
  • обновление из апстрима — обновление локальной версии форка до последней версии основного репозитория, от которого сделан форк
  • обновление из ориджина — обновление локальной версии репозитория до последней удалённой версии этого репозитория
  • клонирование (англ. — clone) — скачивание репозитория с удалённого сервера на локальный компьютер в определённый каталог для дальнейшей работы с этим каталогом как с репозиторием
  • ветка (англ. — branch) — параллельная версия репозитория, которая является частью репозитория, но не влияет на основную версию, что позволяет свободно работать в параллельной версии, а после внесения правок объединить их с главной версией
  • мастер (англ. — master) — основная ветка репозитория
  • коммит (англ. — commit) — фиксация изменений или запись изменений в репозиторий на локальной машине
  • пул (англ. — pull) — получение последних изменений с удалённого репозитория
  • пуш (англ. — push) — отправка коммитов в удалённый репозитория
  • пулреквест (англ. — pull request) — запрос на слияние форка репозитория с основным репозиторием и при этом пулреквест может быть принят или отклонён владельцем репозитория
  • мёрдж (англ. — merge) — слияние изменений из какой-либо ветки репозитория с любой веткой этого же репозитория
  • кодревью (англ. — codereview) — процесс проверки кода на соответствие определённым требованиям, задачам и внешнему виду.

Инициализация нового git-репозитория:

$ git init

Отобразить статус git-репозитория и рабочего каталога:

$ git status

Добавить в индекс все измененные файлы:

$ git add .

Добавить в индекс изменения:

$ git add <filename>

Удалить файл с внесением в индекс:

$ git rm <filename>

Переименование файла/перенос в другую директорию с внесением в индекс:

$ git mv <filename>

Зафиксировать изменения в репозитории, находящиеся в индексе:

$ git commit -m "<message>"

Комбо:

$ git commit -a -m "<message>" = git add . + git commit -m "<message>"

История коммитов:

$ git log

Переход к старому состоянию проекта:

$ git checkout <hash>

Переход к старому состоянию проекта и удалению последующих фиксаций (параметр --hard указывает, что рабочий каталог должен быть обновлен в соответствии с новым head ветки):

$ git reset --hard <hash>

Клонирование проекта из удаленного репозитория

$ git clone <откуда> <куда>

Примеры git clone:

$ git clone ssh://dmn@192.168.1.100:22/var/www/superproject/htdocs/.git superproject
$ git clone /home/username/project myrepo
$ git clone http://user@somehost:port/~user/repository/project.git
$ git clone --bare hello hello.git

Последний пример создает т.н. «чистый» репозиторий. «Чистые» репозитории не хранят рабочие каталоги и обычно используются для расшаривания.

Обычный git-репозиторий подразумевает, что вы будете использовать его как рабочую директорию, поэтому вместе с файлами проекта в актуальной версии, git хранит все служебные, «чисто»-репозиториевские файлы в поддиректории .git.

В удаленных репозиториях нет смысла хранить рабочие файлы на диске (как это делается в рабочих копиях), а все что им действительно нужно — это дельты изменений и другие бинарные данные репозитория. Вот это и есть «чистый» репозиторий.

Получение изменений из удаленного репозитория и их слияние с локальным:

$ git pull

Внесение локальных изменений на удаленный:

$ git push

Просмотр веток:

$ git branch

Добавление ветки:

$ git branch <имя_ветки>

Удаление ветки:

$ git branch <имя_ветки> -d

Переход между ветками:

$ git checkout <имя_ветки>

Слияние двух веток:

$ git merge <имя_ветки>

Дополнительные материалы:

Интерактивный учебник по git

Большая книга по git

Спасибо за прохождение этого курса.