![Система контроля версий Git. Урок 3](https://storage.googleapis.com/static.istories.media/uploaded/images/7259c11fee1c4107a121caa5757ca4bb-1920x960px_1x.jpg)
Мы продолжаем курс по системе контроля версий git. Сегодня разберемся, как работать с ветками. Ветки позволяют работать над кодом так, чтобы на время разработки, основная версия проекта оставалась без изменений.
Представьте, что у вас есть код, который работает. В какой-то момент вы решили добавить в него изменения. Работа над изменениями может занять некоторое время, в какой-то момент код может даже перестать работать. А вам нужно, чтобы в любой момент можно было воспользоваться рабочей версией проекта. В таких ситуациях могут помочь ветки.
Как настроить отображение веток
Git изначально настроен на работу с ветками. Когда мы создавали репозиторий, у нас автоматически появилась ветка main, в которую и коммитились все наши изменения. Важно всегда понимать, в какой ветке мы сейчас находимся. В git для этого есть понятие current branch.
Откроем терминал по адресу нашей папки. На Windows вы сразу увидите, в какой ветке находитесь. На mac это нужно настроить.
Создадим файл: touch ~/.zchrc.
Откроем ее: open ~/.zchrc.
Введем в открывшийся редактор кусок кода:
function parse_git_branch() {
git branch 2> /dev/null | sed -n -e 's/^\* \(.*\)/[\1]/p'
}
COLOR_DEF=$'\e[0m'
COLOR_USR=$'\e[38;5;243m'
COLOR_DIR=$'\e[38;5;197m'
COLOR_GIT=$'\e[38;5;39m'
setopt PROMPT_SUBST
export PROMPT='${COLOR_USR}%n ${COLOR_DIR}%~ ${COLOR_GIT}$(parse_git_branch)${COLOR_DEF} $ '
Сохраним изменения в файле и вернемся в терминал.
Вводим команду source ~/.zchrc. Обозначение ветки появилось.
Когда в следующий раз будем открывать терминал, достаточно ввести только последнюю команду.
![Добавляем код в открывшийся редактор](https://storage.googleapis.com/static.istories.media/uploaded/images/31ea69018c24419383bdfce142990bd9-1200xautopx_1x.png)
![Наш терминал](https://storage.googleapis.com/static.istories.media/uploaded/images/12bd8fdec06a42268f9c7a339fd04268-1200xautopx_1x.png)
Как создать ветку в Git
Представим, что мы хотим добавить в код input, чтобы пользователь вводил свое имя с клавиатуры. Пробовать изменения мы будем в отдельной ветке.
Создать новую ветку можно с помощью команды git branch <название ветки>. Важно, чтобы название было понятным для вас и других участников проекта.
Создадим новую ветку для проекта: git branch input.
Переключимся на новую ветку с помощью команды git checkout input. (Чтобы создать ветку и переключиться на нее за одно действие, можно воспользоваться флагом -b: git checkout -b <название ветки>.)
Внесем изменения в наш файл в ветке input. Для этого перейдем в редактор. Пусть код запрашивает имя пользователя, а потом здоровается с ним.
Добавим в начало запрос на ввод: name = input("What's your name? ")
И изменим первую строку вывода: print("Hello, ", name,"!")
![](https://storage.googleapis.com/static.istories.media/uploaded/images/453245c4be6b462faf252da3e7adc40e-1200xautopx_1x.png)
![](https://storage.googleapis.com/static.istories.media/uploaded/images/65dffb4146f249b99da3d5d892c5355a-1200xautopx_1x.png)
Проверим, как работает наш код. Для этого нужно нажать на значок play в верхнем правом углу редактора. Код сначала просит нас ввести имя, а потом выводит нужную информацию. Изменения удались.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/ceb46ef9564b4c498fa294ccecbf668f-1200xautopx_1x.png)
Закоммитим изменения: git commit -a -m “Add input”.
Проверим git status, убедимся, что рабочее дерево чистое. Проверим историю: git log. Видим весь путь работы: последнее изменение и все изменения, которые были еще до ответвления. Чтобы выйти из истории, нужно нажать q в английской раскладке.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/4ce16b3d1c8049e8b1c1b86fe9d3363b-1200xautopx_1x.png)
Вернемся в основную ветку с помощью команды git checkout main и зайдем в редактор. Изменения пропали, потому что в основную ветку мы их еще не добавляли. Проверяем историю: git log. В ветке main видим только старые коммиты, до ответвления.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/b5285fb1bb42498c83e885418fa6f242-1200xautopx_1x.png)
Как сливать ветки и решать конфликты
Когда мы сделали все нужные изменения в коде, проверили, что они работают так, как мы хотим, можно переносить изменения в основной код.
Сначала нужно переключиться на основную ветку: git checkout main.
Теперь можем забрать изменения из ветки input: git merge --no-ff <название ветки, изменения из которой забираем> -m “Сообщение о слиянии веток”.
Такая команда создаст новый коммит, в котором объединятся две ветки.
Флаг --no-ff отменяет механизм fast-forward, который стоит в git по умолчанию. Если его не отменить, git не будет создавать новый коммит, в котором объединятся две ветки, а просто сделает дополнительную ветку веткой main. Иногда такой механизм полезен, но сейчас он нас запутает, поэтому отключаем его. Вы можете поэкспериментировать и посмотреть, в какой ситуации какой механизм вам больше подходит.
В нашем случае git понял, как нужно совместить две ветки. Проверим редактор, чтобы убедиться, что результат тот, который нам нужен.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/84ed27368d0d4e4485050029ea70e2f2-1200xautopx_1x.png)
![](https://storage.googleapis.com/static.istories.media/uploaded/images/a459a563c5ed41869872f386d903e4fd-1200xautopx_1x.png)
Иногда Git не понимает, как именно нужно объединить ветки и выводит сообщение о конфликте. В таких ситуациях, мы должны показать ему это. Для этого переходим в редактор, удаляем лишние символы и приводим код к тому виду, который нам нужен. Сохраняем файл в редакторе, проверяем git status — увидим сообщение о конфликте. Чтобы показать Git, что мы разрешили конфликт, просто закоммитим изменения: git commit -a -m «Add input in main».
Проверим историю: git log. Если видим сообщение о коммите, в котором сливаются две ветки, значит, все получилось.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/9352183cad204ff0880acaff5eaacfc8-1200xautopx_1x.png)
Историю изменений, создания новых веток и слияния можно визуализировать: git log --oneline --graph.
Звездочкой показан каждый коммит, мы видим, что происходило на каждом шаге, в какой момент появилась новая ветка и что мы в ней делали, в какой момент слили ветки.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/7f16090d8d024c139201afd82babe29d-1200xautopx_1x.png)
Как залить изменения на GitHub
Отправляем изменения на удаленный репозиторий: git push.
Проверяем GitHub. Изменения появились, но залилась только ветка main. Другие ветки нужно заливать отдельно: git push -u origin <название ветки>.
Зальем ветку input: git push -u origin input. Видим, что на GitHub появились две ветки. Переключиться между ветками можно в меню branch.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/c65fb8dbe8ae4f279267c895ca27fc6d-1200xautopx_1x.png)
Как перемещаться по коммитам
Еще один важный указатель в git — это head. Он указывает, на какой ветке мы находимся. Если мы перейдем в историю, увидим, что head указывает на ветку main и на удаленную ветку origin_main. Это значит, наш локальный и удаленный репозитории синхронизированы.
Перейдем на другую ветку командой git checkout input, и в истории head будет указывать уже на input.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/de7f7b9ec21d43e8840d760aa7b1dcad-1200xautopx_1x.png)
![](https://storage.googleapis.com/static.istories.media/uploaded/images/7a97d436e0ba47869c561af12c4a9ac8-1200xautopx_1x.png)
Мы можем перейти не только на другую ветку, но и на отдельный коммит. Будто перенестись в прошлое и посмотреть, как работал наш код на одном из этапов разработки. Сначала переключимся на основную ветку.
Посмотрим историю изменений: git log --oneline. (Эта команда дает более компактное отображение истории по сравнению с git log.)
Переходим на один из первых коммитов: git checkout <первые символы кода идентификатора>. Head уже будет указывать на отдельный коммит, а в редакторе код тоже вернулся на тот этап.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/56a225abcb3d4f5e970ab040f2a58e57-1200xautopx_1x.png)
![](https://storage.googleapis.com/static.istories.media/uploaded/images/228118a06a4948cba486aaea3cd25f5a-1200xautopx_1x.png)
С помощью таких перемещений по коммитам, мы можем искать ошибки, понимать, в какой момент код работал хорошо, а с какого этапа что-то пошло не так. Мы можем даже вносить изменения на этом этапе, но для этого нужно создать отдельную ветку.
Создадим новую ветку и переключимся на нее в одно действие с помощью флага -b: git checkout -b calc.
Добавим изменения в редактор: допишем строку 2+2. Сохраняем изменения в редакторе.
Добавим файл в отслеживание и коммитим изменения: git commit -a -m “Add calculation”.
Вернемся в основную ветку: git checkout main. Посмотрим все ветки: git branch. Видим, что появилась новая ветка calc.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/dd768ac8047948ff91bcbd0e20507552-1200xautopx_1x.png)
Сделаем визуализацию наших изменений: git log --oneline --graph --all. Видим, что со второго коммита ответвилась еще одна ветка.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/dd4d84f571ff4387856373eb0d574187-1200xautopx_1x.png)
Как удалить ветку в Git
Если мы понимаем, что ветка больше не нужна, можно ее удалить. При этом удаляемая ветка не должна быть той веткой, в которой мы находимся. Удалим ветку calc: git branch -d calc. Git предупреждает, что ветка еще не объединена с основной веткой и что удалять ее опасно. Но мы уверены, что хотим удалить ветку, поэтому вводим еще одну команду, которую нам подсказывает git: git branch -D calc.
Теперь удалим ветку input. Она уже залита на GitHub, поэтому сначала удалим ее с удаленного репозитория: git push --delete origin input
Проверим Git Hub: ветка удалилась. Теперь удаляем ветку локально: git branch -d input.
Проверим наши ветки: git branch. Ветки удалились, осталась только ветка main.
![](https://storage.googleapis.com/static.istories.media/uploaded/images/a55ef55c074243bcbd8bd39e46df6c7d-1200xautopx_1x.png)
Если по ходу работы у вас появляются ошибки, попробуйте найти решение в интернете. Часто достаточно скопировать полученную ошибку и вбить ее в поиск в браузере. Если все же не получается найти ответ, пишите нам в чате в Telegram.