Close

Форки и вышестоящие репозитории в Git: инструкции и интересный совет

Фотография Николы Паолуччи
Николя Паолуччи

Консультант по разработке


Создав форк проекта для внесения изменений, вы сможете легко интегрировать собственный код. Но если вы не отправляете изменения в вышестоящий (родительский) репозиторий, то рискуете потерять их из виду. Это может привести к появлению в репозитории расходящихся веток. Чтобы наладить рабочий процесс, в котором все участники получают код из одного источника, нужно знать некоторые принципы взаимодействия форков Git с вышестоящим репозиторием Git. В этом блоге я познакомлю вас с основами, расскажу о подводных камнях и дам полезный совет, который поможет вам быть на шаг впереди.

Вышестоящий репозиторий Git: следите за обновлениями и вносите свой вклад


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

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

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

git remote -v

origin  git@bitbucket.org:my-user/some-project.git (fetch)
origin  git@bitbucket.org:my-user/some-project.git (push)

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

git remote add upstream git@bitbucket.org:some-gatekeeper-maintainer/some-project.git
базы данных
Связанные материалы

Перемещение полного репозитория Git

Логотип Bitbucket
СМ. РЕШЕНИЕ

Изучите Git с помощью Bitbucket Cloud

Убедитесь, что удаленное подключение добавлено правильно:

git remote -v

origin    git@bitbucket.org:my-user/some-project.git (fetch)
origin    git@bitbucket.org:my-user/some-project.git (push)
upstream  git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (fetch)
upstream  git@bitbucket.org:some-gatekeeper-maintainer/some-project.git (push)

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

(Если в проекте есть теги, которые не объединены с главной веткой, нужно также выполнить команду git fetch upstream --tags.)

git fetch upstream

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

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

git checkout main
git merge upstream/main

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

Кроме того, вы можете провести перебазирование с помощью команды rebase, а затем выполнить слияние командой merge, чтобы оставить в вышестоящем репозитории чистый набор коммитов (а лучше всего один) для оценки:

git checkout -b feature-x

#some work and some commits happen
#some time passes

git fetch upstream
git rebase upstream/main

Публикация в форке репозитория Git


Выполнив описанные выше действия, опубликуйте работу в своем удаленном форке простой командой push:

git push origin feature-x
git push -f origin feature-x

Я предпочитаю сохранять историю максимально чистой и поэтому выбираю третий вариант, однако у разных команд разные рабочие процессы. Примечание: совершайте эти операции только при работе с собственным форком. НИ В КОЕМ СЛУЧАЕ не перезаписывайте историю общих репозиториев и веток.

Полезный совет: значения опережения/отставания в подсказке


Выполнив команду git status после fetch, вы сможете просмотреть, на сколько коммитов ваша ветка опережает синхронизированную удаленную ветку или отстает от нее. Было бы здорово видеть эту информацию в своей верной командной подсказке, не правда ли? Я тоже так подумал, поэтому настроил в Bash соответствующие параметры.

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

nick-macbook-air:~/dev/projects/stash[1|94]$

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

function ahead_behind {
    curr_branch=$(git rev-parse --abbrev-ref HEAD);
    curr_remote=$(git config branch.$curr_branch.remote);
    curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);
    git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';
}
export PS1="\h:\w[\$(ahead_behind)]$"

«Внутренняя кухня»

Изложу принцип работы для тех, кто любит развернутые пояснения.

Получаем символическое имя текущего указателя HEAD, то есть текущей ветки:

curr_branch=$(git rev-parse --abbrev-ref HEAD);

Получаем удаленную ветку, на которую указывает текущая ветка:

curr_remote=$(git config branch.$curr_branch.remote);

Получаем ветку, с которой нужно объединить эту удаленную ветку (в Unix можно легко убрать все символы до последней косой черты [/] включительно):

curr_merge_branch=$(git config branch.$curr_branch.merge | cut -d / -f 3);

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

git rev-list --left-right --count $curr_branch...$curr_remote/$curr_merge_branch | tr -s '\t' '|';

Для преобразования символа табуляции в разделитель | используем привычную команду tr в Unix.

Начало работы с вышестоящим репозиторием Git


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

Решение Bitbucket Data Center поддерживает синхронизацию форков, которая освобождает разработчиков от обязанности поддерживать актуальность своих форков. В рамках Bitbucket Cloud используется простая одноэтапная синхронизация. Опробуйте эти возможности самостоятельно!

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


Поделитесь этой статьей
Следующая тема

Рекомендуемые статьи

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

Люди сотрудничают друг с другом, используя стену со множеством инструментов

Блог Bitbucket

Рисунок: DevOps

Образовательные программы DevOps

Демонстрация функций в демо-зале с участием экспертов Atlassian

Как инструмент Bitbucket Cloud работает с Atlassian Open DevOps

Подпишитесь на информационную рассылку по DevOps

Thank you for signing up