В предыдущей статье я обсуждал, как начать работу с Git , и в основном сосредоточился на использовании Git при работе в одиночку. Основная философия Git, однако, вращается вокруг концепции распределенной системы контроля версий.
Понятие «распределенный» означает, что существует много независимых версий одного проекта, каждый со своей историей. Таким образом, Git — это инструмент, который помогает вам работать с командой, которая может быть географически распределена .
Мы обсуждали, как вы можете управлять своими файлами с помощью Git в предыдущем уроке, но цель состояла в том, чтобы ознакомиться с концепциями git (добавить, зафиксировать, нажать). Теперь, когда вы знаете, как Git работает локально, вы можете использовать более продвинутые функции.
клонирование
Первым шагом в этом процессе является получение кода (при условии, что Git установлен) с удаленного ресурса. remote
относится к удаленной версии хранилища или проекта. Мы начинаем с клонирования ресурса, используя команду git clone
.
git clone https://github.com/sdaityari/my_git_project.git
URL-адрес клона можно получить с главной страницы репозитория GitHub на боковой панели. При успешном клонировании хранилища создается каталог (по умолчанию это то же имя, что и у проекта). Еще один интересный факт заключается в том, что удаленный источник теперь указывает на ресурс, с которого я клонировал репозиторий (в данном случае https://github.com/sdaityari/my_git_project.git
).
Хотя Git следует распределенной модели, обычно поддерживается центральный репозиторий, содержащий стабильный, обновленный код.
Какой протокол использовать при клонировании?
Обратите внимание, что хранилище клонируется по протоколу https
в этом примере. Другие популярные варианты, которые у вас есть, это ssh
и git
.
Клонирование по протоколу git
требует, чтобы вы использовали источник, похожий на git://github.com/[username]/[repository]
. Это не обеспечивает никакой безопасности, кроме безопасности самого Git. Обычно это быстро, но большим недостатком является невозможность push
изменений, поскольку он предоставляет только доступ только для чтения.
Если вы используете протокол https
, ваше соединение зашифровано. GitHub позволяет анонимно запрашивать https
для общедоступных репозиториев, но для отправки любого кода ваши имя пользователя и пароль будут проверены. GitHub рекомендует использовать https поверх ssh .
Протокол ssh
использует аутентификацию с открытым ключом . Для этого необходимо установить соединение с удаленным сервером через ssh
. Чтобы настроить аутентификацию с использованием ssh
, вам нужно сгенерировать пару открытый / закрытый ключ. В Linux вы запускаете следующую команду в терминале, чтобы сгенерировать вашу пару ключей. Но если вы используете настольный клиент GitHub, этот процесс автоматически выполняется программным обеспечением, и вы получаете электронное письмо, в котором ключ SSH был добавлен в вашу учетную запись GitHub.
ssh-keygen -t rsa -C "[email_address]"
Примечание: в этих примерах кода я часто буду включать разделы в квадратных скобках. Эти разделы, заключенные в квадратные скобки, будут заменены тем, что указано внутри скобок, но с удаленными скобками.
При желании вы можете указать кодовую фразу, которая будет необходима при каждом подключении. Мы оставляем это пустым в нашем случае. Вы также можете указать файл, в котором вы можете сохранить ключ. Мы оставляем это по умолчанию id_rsa
.
Открытый и закрытый ключи хранятся в id_rsa.pub
и id_rsa
соответственно. В случае GitHub вам необходимо вставить содержимое вашего открытого ключа в раздел «SSH» в вашем профиле.
Чтобы убедиться, что процесс был успешно завершен, вы можете установить соединение с пользователем git на github.com.
ssh git@github.com
Как видите, подключение к GitHub было успешным, но оно было разорвано, потому что GitHub не разрешает доступ к оболочке. Это означает, что вы можете использовать протокол ssh
для получения или отправки изменений.
Интересным фактом является то, что remote
содержит протокол. Это означает, что подключение к ресурсу через протоколы https
и ssh
необходимо хранить как отдельные пульты.
ветви
Одна из лучших функций Git — ветвление. Думайте о ветвях как о путях, которые вы выбираете, когда продвигаетесь по своему коду. Эти ветви могут быть визуализированы ветвями дерева. Единственное место, где наша аналогия с деревьями не работает, это то, что Git также позволяет вам объединять ветви.
Если вы ранее использовали ветки в других системах контроля версий, вам нужно очистить свой разум, поскольку концепции немного отличаются. Например, если вы сравниваете Subversion и Git, их механизмы слияния будут другими .
Представьте, что вы делаете приложение для чата. В какой-то момент вы решаете, что хотите, чтобы снимки людей появлялись рядом с их именем, но эта идея еще не была одобрена вашим боссом. Вы создаете ветку и работаете над своей идеей, в то время как старые функции остаются неизменными в отдельной ветке. Если вы хотите продемонстрировать свою старую работу, вы можете переключиться на старую ветку. Если ваша идея одобрена, вы можете объединить новую ветку со старой, чтобы внести изменения.
Чтобы проверить список ветвей и текущую ветку, над которой вы работаете, выполните следующую команду. Он показывает список веток в вашем репозитории со звездочкой напротив текущей рабочей ветки.
git branch
Создание веток
Git предоставляет master
ветку, над которой вы работаете по умолчанию. При создании веток вы должны правильно называть их, как функции или сообщения коммитов. Чтобы создать ветку, выполните следующую команду.
git branch [branch_name]
Это создает новую ветвь на основе последнего коммита, но остается в той же ветке. Чтобы переключиться на другую ветку, выполните следующую команду
git checkout [branch_name]
Чтобы создать новую ветку и сразу перейти к ней, используйте:
git checkout -b [branch_name]
Это создаст новую ветку на основе последнего коммита вашей текущей ветки. Если вы хотите создать ветку на основе старого коммита, вы должны добавить хеш, который идентифицирует коммит, с помощью команды.
git checkout -b [branch_name] [commit_hash]
Модели ветвления
В предыдущем посте я говорил о руководящих принципах, которым нужно следовать, внося свой вклад в проекты с открытым исходным кодом. Каждая новая функция должна быть построена на новой ветви, и запрос на извлечение или исправление должны быть отправлены из этой новой ветви. Основная ветвь должна использоваться только для синхронизации с исходным источником проекта.
Существует ряд различных моделей, которые используются организациями для управления своими проектами. В этом посте о ветвлении git обсуждается обобщенная модель, которая подходит для большинства организаций сегодня.
Визуализация прогресса через ветви
Теперь, когда вы знаете, как создавать ветки, вы должны задаться вопросом, как мы могли понять идею с помощью одной команды. Клиенты GUI для Git делают это одним щелчком мыши, но вы можете сделать то же самое в терминале. В нашем случае мы добавили несколько new_feature
в ветви — master
, new_feature
и another_feature
.
git log --graph --all
Использование git log
показывает историю проекта. --graph
показывает направление --graph
, тогда как --all
показывает все ветви. Вы можете добавить --oneline
для отображения --oneline
в одной строке (конечно, без их подробностей).
Слияние ветвей
Давайте рассмотрим, пожалуй, самую важную часть этого урока: возможность объединения веток в Git. Одна из обсуждаемых нами моделей ветвей заключалась в том, что все функции разрабатываются в отдельных ветках, а те, которые дают желаемые результаты, объединяются с master
. Для этого вам нужно checkout
в master
ветке и объединить с ней ветку feature
.
git checkout master git merge [branch_name]
Однако в нашем случае мы видим, что возник конфликт. Почему это случилось? Были внесены изменения в один и тот же файл в обеих ветках, и Git не смог определить, какие изменения оставить, что привело к конфликту в процессе. Мы увидим, как разрешать конфликты позже в этом уроке.
Сотрудничество с Git
В посте Git for Beginners мы закончили с использованием git push
который синхронизировал наш код на GitHub. Таким образом, вы должны знать, что для эффективной отправки кода с локального компьютера на другой remote
вы используете команду git push
. Различные способы сделать толчок заключаются в следующем.
git push git push [remote] git push [remote] [branch] git push [remote] [local_branch]:[remote_branch]
Первая команда отправляет ваш код в текущую ветку origin
удаленно. Когда вы указываете удаленное имя, код из вашей текущей активной ветви передается в ветку с тем же именем на удаленном. Кроме того, вы можете выдвинуть из локальной ветви в ветку с другим именем на удаленном.
Если вы предпочитаете, чтобы последняя команда выдвигалась, есть хитрость, которая удаляет ветку на пульте. Если вы предоставите пустой [local_branch]
, он удалит remote_branch
на сервере. Это выглядит так:
git push [remote] :[remote_branch]
push
не всегда принимается на пульте, хотя. Возьмите следующий случай.
Ветвь «без ускоренной пересылки» относится к тому факту, что фиксация на кончике удаленной ветки не совпадает с коммитами в моей локальной системе. Это означает, что удаленная ветвь изменилась с момента последней синхронизации.
В такой ситуации мне нужно будет извлечь изменения из удаленной ветви, обновить локальную ветвь и затем отправить изменения. В общем, считается хорошей практикой всегда тянуть перед толчком. Синтаксис точно такой же, как и у аналогов push.
git pull --rebase [remote] [branch]
С другой стороны, некоторые люди делают git fetch
последующим git merge
а не git pull
. По сути, извлечение делает выборку, а затем слияние . Также следует использовать --rebase
, потому что он сначала переносит изменения в вашу ветку, а затем помещает вашу работу поверх нее. Это желательно, потому что все возможные конфликты возникают на основе изменений, которые вы сделали, и, следовательно, вы в состоянии решить, что оставить, а что нет.
Как еще одна возможность, организации, которые не предоставляют каждому участнику push
доступ к своим репозиториям, работают через электронную почту. В таком случае вы должны создать diff
файл, сравнивая различия между коммитами или ветвями. Команда git diff
показывает разницу, а изменения сохраняются в файле, который затем отправляется по почте в организацию. Эти файлы различий широко известны как «патчи».
git diff [branch1] [branch2] > [file_name]
Сгенерированные части файла diff подробно описаны в этом посте . Если у вас есть файл diff
и вы хотите применить патч, вы просто используете команду ниже.
git apply [file_name]
Разрешение конфликтов
Разрешение конфликтов важно в любом рабочем процессе Git. Вполне естественно, что многие люди работают с одним и тем же файлом, и на сервере установлена более новая версия этого файла с момента последнего изменения изменений. Конфликты также могут возникать при попытке объединить две ветви, которые имеют изменения в одном файле. Иногда Git пытается применить определенные алгоритмы, чтобы посмотреть, сможет ли он решить конфликт самостоятельно, но он часто поднимает красный флаг, чтобы убедиться, что нет потери данных.
Когда мы попытались объединить наши филиалы, мы заметили, что возник конфликт. Давайте посмотрим, как мы можем решить это. Состояние git status
показывает вам, что вызвало конфликт.
Затем мы можем открыть указанный файл с помощью текстового редактора (например, VIM), чтобы увидеть, что не так. Содержимое файла выглядит так:
Посмотрите на файл внимательно. Обратите внимание на три строки, которые были вставлены Git.
<<<<<<<< HEAD ... ... ======== ... ... >>>>>>>> another_feature
Что это значит, довольно просто. Строки кода между <<<<<<<< HEAD
и ========
являются частью вашей текущей ветви, тогда как строки между ========
и >>>>>>>> another_feature
присутствует в ветке, которую вы пытаетесь объединить. Что вам нужно сделать, это удалить эти три линии маркера и отредактировать содержимое между ними так, как вам нужно. В нашем случае давайте сохраним всю информацию, поэтому конечный файл будет выглядеть примерно так.
Несмотря на то, что мы сохраняем весь контент в обоих блоках, вы можете удалить весь контент, оставить часть контента или написать что-то другое на их месте, пока разрешаете конфликт.
Этот конфликт был довольно прост в нашем случае. В более сложных проектах у вас может быть много экземпляров, которые приводят к конфликтам, с несколькими экземплярами строк, показанных выше, включенными в конфликтующие файлы. Процесс разрешения довольно сложного конфликта остается тем же: проверьте затронутые файлы через состояние git status
, откройте каждый из них и найдите вхождения HEAD
.
Конфликты могут возникать и при удалении. В этом случае последняя строка будет читать >>>>>>>> [commit_hash]
вместо >>>>>>>> [branch_name]
, где [commit_hash]
будет идентифицирующим хешем для фиксации.
Вывод
Git популярен в сообществе разработчиков, но критики часто сравнивают его со швейцарским армейским ножом. Это правда, что Git предлагает много возможностей. Но как только вы поймете основы, они станут интуитивно понятными в использовании. Будем надеяться, что этот учебник поможет вам начать работу с Git таким образом, чтобы вы могли внести свой вклад в командную среду.
Если у вас есть что добавить к любой из функций, описанных выше, пожалуйста, добавьте ваши комментарии.