Git (практика, часть 1)
LINEЭто вторая (практическая) статья про git. В теоретической статье (она здесь) мы рассмотрели основные понятия и идеи git.
В практической части мы посмотрим на частые случаи использования git на практике в виде: Как сделать что то -> способы это сделать.
Чтобы размер статьи не стал слишком большим, она разбита на несколько частей.
Настроить имя и почту пользователя
После установки git нужно добавить имя и электронную почту, т.к. эта информация включается в каждый коммит. Для этого нужно вызвать git config --global user.name "<имя>" и git config --global user.email "<email>".
Global в данном случае указывает, что эти настройки действуют на любой созданный репозиторий. Вы можете обойтись без этого флага и задавать разные значения каждому репозиторию.

Настроить редактор
При создании коммита git просит написать сообщение коммита и открывает редактор, установленный по умолчанию. Но вы можете выбрать свой редактор с помощью git config --global core.editor

Просмотреть состояния файлов
В git файл может находиться в нескольких состояниях: под версионным контролем и нет. Если файл под контролем git, он может быть неизмененным, измененным и подготовленным.
Для просмотра состояния файлов используется команда git status. У нее есть версия с флагом --short (или просто -s), которая выводит состояние файла с помощью 2-х символов и названия файлов (более короткий вывод).
Начнем с момента, когда мы только что сделали коммит и status ничего не возвращает

Добавим любой текстовый файл с любым содержимым (file_1, содержащий "line 1"). Посмотрим на состояние файла

Этот файл не находится под версионным контролем, поэтому находится в области untracked files. В короткой записи он обозначен как ??.
Добавим этот файл в индекс (с помощью add) и сделаем коммит с сообщением "add file_1"

Теперь git status опять ничего не вернет, все изменения сохранены.
В каком состоянии теперь находится file_1? Он сохранен в прошлом коммите и с этого момента не изменялся, поэтому он в состоянии неизмененный (unmodified). Git ничего не нужно с ним делать, поэтому его git даже не показывает. Но давайте добавим в файл file_1 новую любую строку.

Теперь файл изменен по сравнению с последним коммитом - мы добавили еще одну строчку, т.е. такой файл в состоянии изменен (modified). В коротком выводе такой файл обозначен как _M (первый символ пуст). Давайте добавим этот файл в индекс и сохраним изменения с помощью git add.

Файл file_1 теперь в состоянии подготовленный, т.е. его изменения войдут в следующий коммит. В коротком выводе такой файл помечен как M_(второй символ пустой). Давайте изменим его еще раз, добавив еще строчку. Теперь git status вернет следующее

Кажется странным, но файл file_1 теперь И изменен и подготовлен к коммиту И изменен и не подготовлен к коммиту. Что это значит.
Изначально у нас не было файла. Мы создали файл, добавили в него текст (line 1). После этого файл перешел в состояние неотслеживаемого git (untracked). Дальше мы добавили файл в индекс, файл перешел в состояние подготовленного к следующему коммите(staged). Мы сделали коммит и после коммита файл находится в таком же состояние, как и в предыдущем коммите, т.е. он не изменен(unmodified). После мы изменили файл, добавив "line 2" и теперь файл отличается от того, что был в последнем коммите и от того, что есть в индексе - файл изменен(modified). Как только мы добавим файл в индекс, файл снова перейдет в состояние подготовленного к коммиту (staged). Но если мы еще раз изменим файл (добавим line 3), то файл, уже подготовленный к коммиту будет еще и модифицирован. Именно поэтому этот файл в двух областях - changes to be commited и changes not staged for commit. Мы сначала добавили файл в индекс, а затем еще раз изменили его - и в следующий коммит не войдут изменения, произошедшие после последней команды add (т.е. line 3).

Что обозначают символы в выводе короткой версии status? Первый символ говорит о том, в каком состоянии находится файл, а вторая - изменен ли он после этого.
- ?? - файл не отслеживается git
- A_ - файл был добавлен в git в этом коммите
- _M - файл изменен и эти изменения не находятся в индексе
- M_ - файл изменен и изменения добавлены в индекс
- MM - файл изменен и изменения добавлены в индекс, и после этого файл еще раз изменен
Добавить новый коммит
- git commit
Самый простой способ добавить коммит - git commit. После этого откроется следующее окно, в котором нужно добавить сообщение коммита. Все, что начинается с символа # в таком сообщение не будет сохранено. Если вы хотите выйти из коммита, не сохраняя его - нужно оставить тело сообщения пустым. В сообщение указывается ветка и изменения в файлах, которые будут сохранены в коммите.

Чтобы сохранить изменения, нужно нажать или Esc и ввести :wq , или нажать ctrl + X, выбрать Y и нажать enter для сохранения названия файла.
- git commit -v
Просто команда git commit показывает измененные файлы, но не сами изменения. Флаг -v позволяет посмотреть на эти изменения при написании сообщения коммита. Например, мы добавили новый файл new_feature с текстом "this is simple text, no more". git commit -v выведет следующее

Все что обозначено желтым цветом (diff) не нужно удалять, эти строки не войдут в коммит. Здесь показано, что изменился файл new_feature и добавлена новая строка.
- git commit -m
Если мы не хотим открывать редактор и точно знаем все изменения, можно воспользоваться командой git commit -m <сообщение коммита>

Просмотреть историю коммитов
Git log - необычайно богатая команда, которая нужна как для просмотра истории, так и для нахождения определенных коммитов.
Представим историю из 3-х коммитов (first commit -> second commit -> third commit). В каждом коммите был добавлен один текстовый файл с одной строкой в файле(file N message).
Команда git log без аргументов выведет следующее

Мы получаем историю, начиная с последнего коммита (тот, что сделан позднее всех). Для каждого коммита указывается полный hash, автор в формате: имя email и дата в формате: день недели, месяц, число время год часовой пояс (например так Fri Aug 6 13:05:05 2021 +0300)
У git log есть флаг --pretty, значение которого влияет на вывод. Например --pretty=short выведет следующее

Вывод такой же, но без даты. Со значением --pretty=full вывод будет содержать и автора, и коммитера

В чем различие между автором и коммитером? Можно привести такую аналогию - автор тот, кто написал письмо, а коммитер - тот, кто это письмо отправил. В большинстве автор сам делает изменения и сам же их коммитит, т.е. это один человек.
Самый подробный вывод можно получить с помощью --pretty=fuller

Дополнительно добавлены даты изменений к автору и комиттеру.
Такой подробный вывод не всегда то, что нужно. Все коммиты можно выводить в одну строку с помощью --pretty=oneline. Это довольно популярная команда, так что у нее есть версия git log --oneline. Различия между ними в длине hash коммита.

Просмотреть историю коммитов, начиная с заданного и (или) указывая конечный
Мы можем указать, с какого коммита начинать с помощью git log <commit>, например по hash коммита

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

А можем сказать, до какого коммита продолжать с помощью git log <commit>.. (в конце две точки)

Визуально это выглядит так. Мы начинаем с самого последнего коммита и заканчиваем тогда, когда коммит равен указанному перед "..". Сам указанный коммит не включается.

Можно комбинировать эти команды, т.е. указать с какого начать и каким закончить через git log <закончить на этом коммите, не включая его>..<начать с этого коммита>

Просмотреть историю с заданным форматом времени
Мы можем указать, в каком формате мы хотим видеть время изменения. Для этого используется --date=<формат>. Например, relative указывает время в относительном виде (столько то минут/часов/дней назад).

Введите --date= и нажмите tab 2 раза, чтобы git показал возможные варианты форматов.

Просмотреть указанное количество коммитов
Мы можем просмотреть только определенное количество коммитов с помощью git log -n <количество коммитов>, или просто git log -<количество коммитов>

Найти коммиты, которые изменяли указанный файл
После git log можно указать файл и git выведет все коммиты, которые меняли заданный файл. Можно также указывать другие флаги для нужного формата.

Найти все коммиты, которые изменили указанную строку
Это пожалуй самая мощная возможность git log - поиск по строкам. Для этого используется git log -S "строка для поиска"

Найти все коммиты, у которых в сообщение коммита есть указанная строка
Искать можно не только по файлам, но и по сообщениям коммитов. Для этого используется git log --grep "строка для поиска"

Найти коммиты, сделанные в указанное время или промежуток времени в прошлом
Для поиска по времени используются флаги --since(или --after) и --until(или --before). Since говорит что нужно найти коммиты, которые произошли после указанной даты, unit - до. Дату можно задавать в абсолютном виде(год-месяц- число) или в относительном виде(столько то минут, дней назад).
Например, коммиты после 9:00 6 августа 2021

Коммиты, кроме тех, что были сделаны за последние 2 часа

Коммиты, которые сделаны 6 августа 2021 с 8:00 до 15:00

Найти коммиты, сделанные определенным автором или коммитером
Для поиска автора используется флаг --author="имя автора"

С коммитером абсолютно тоже, но флаг --committer="имя коммитера"
Просмотреть изменения, внесенные коммитом
Мы можем увидеть в истории файлы, которые изменил коммит с помощью git log --stat. Так мы увидим общую картину - где были изменения и как их было много

А можем вывести сами изменения с помощью git --patch(или просто -p). Вывод показан только для последнего коммита.

Посмотреть на различия между рабочей директорией и индексом
Чтобы увидеть файлы, измененные (или добавленные) в рабочую директорию, но еще не добавленные в следующий коммит, нужно использовать команду git diff. Если добавить к каждому файлу из предыдущих примеров по новой строке ("another line n"), то все 3 файла будут изменены и эти изменения не добавлены в индекс.

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

Можно сказать, что так git показывает то, что НЕ войдет в следующий коммит. Это есть в рабочей директории, но не в индексе.
Посмотреть на различия между индексом и прошлым коммитом
git diff --staged выводит разницу между индексом и состоянием файла в прошлом коммите. Говоря простыми словами - это то, какие изменения принесет коммит.

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

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