В статье собраны особенности работы с git на проектах внедрения DirectumRX. Описаны настройки, которые доступны для среды разработки и репозиториев в целом. Рассмотрены основные команды git на примере GitExtensions. Приведены рекомендации по оформлению кода и слияния разработки.
В среде разработки Directum RX для хранения исходных кодов используется распределенная система контроля версий Git. Общая схема взаимодействия среды разработки и Git описана в справке Схема работы с исходными кодами.
Настройка локального и удалённого репозиториев задаётся в конфигурационном файле, который можно найти по пути "C:\Program Files\Directum Company\Sungero Development Studio\Bin\_ConfigSettings.xml".
Рассмотрим основные параметры для работы с git.
<var name="GIT_ROOT_DIRECTORY" value="C:\Source"/> - путь к папке с исходными кодами.
<repository folderName="Base" solutionType="Base" url=""/> - настройка репозитория для базового решения. Где folderName - путь к папке относительно параметра GIT_ROOT_DIRECTORY, а url - ссылка на удалённый репозиторий.
<repository folderName="Work" solutionType="Work" url=""/> - настройка репозитория для рабочего решения.
В конфигурационном файле может содержаться несколько настроек для базовых и рабочих решений. Среда разработки считывает настройки проходом по файлу сверху вниз, поэтому новые решения будут созданы в репозитории для рабочих решений, который находится выше всех в файле.
Учётные данные для подключения к репозиторию можно настроить в диспетчере учётных данных.
Также строку подключения можно задать в конфигурационном файле репозитория, например, url=https://username:password@tfsozrrx.directum.ru/DefaultCollection/DirRXCustomClients/_git/LLK.
Более подробно работа с удалённым репозиторием описана в статье Настройка GIT в DirectumRX под использование хостинга проектов Bitbucket (GitHub).
В новом репозитории автоматически создается ветка master. В ней фиксируется протестированная и прорецензированная разработка в состоянии, готовом для передачи клиенту.
Разработка ведется в рамках ветки dev, которую разработчик создаёт от ветки master после настройки репозиториев и импорта базовых решений. Она предназначена для фиксации прорецензированной разработки в состоянии, готовом для передачи в тестирование.
От dev создаются временные ветки для фич. После того, как фича прорецензирована, временная ветка фичи объединяется с исходной веткой.
Ниже представлена визуальная схема ветвления.
К моменту передачи разработки заказчику необходимо
Перед обновлением на новую версию необходимо создать ветку для бэкапа состояния заказной разработки до обновления. Название ветки – номер версии до обновления.
Обновление осуществляетcя в ветке master.
В заказной разработке после успешного обновления клиентов ветки предыдущих версий могут удаляться.
GitExtensions – одна из GUI-утилит для работы с git-репозиториями. Доступна для скачивания с GitHub. Справка доступна по адресу http://git-extensions-documentation.readthedocs.io/en/latest/.
Нажать на кнопку pull (выделена красным). Так же pull можно сделать через меню: Commands -> Pull… или горячими клавишами Ctrl-вниз.
В открывшемся окне в разделе Merge options доступны следующие варианты:
Merge – получает изменения с сервера в текущую ветку и при наличии локальных изменений создает merge-commit. Эту опцию в повседневной работе не используем, т.к. после нее история репозитория становится ветвистой и неудобной для восприятия.
Rebase – получает изменения с сервера в текущую ветку, а коммиты, которые были сделаны локально, пытается воспроизвести на новой версии исходников, полученных с сервера, таким образом история остается линейной и удобна для просмотра. Это основной режим, который мы используем для обновления исходников.
Fetch – позволяет получить изменения с сервера, но не применять их к рабочей папке. Эти изменения мы увидим только в истории репозитория.
После внесения изменений в исходный код необходимо эти изменения сохранить в репозиторий. Для этого нажать кнопку Commit.
Индексирование файлов
В открывшемся окне, в левой части, выбрать те файлы, которые нужно закоммитить, после чего нажать кнопку Stage. После чего выбранные файлы будут проиндексированы и попадут в коммит. Если после занесения файла в индекс его поменять в рабочей папке, то для того, чтобы новые изменения также попали в коммит, их снова необходимо проиндексировать.
Далее необходимо написать сообщение к коммиту.
После этого нажимаем кнопку Commit, и все проиндексированные изменения попадут в репозиторий.
Иногда перед отправкой может возникнуть необходимость подправить сделанные коммиты. Например, перегруппировать изменения или подправить комментарии к коммитам. Все это можно сделать, пока изменения не отправлены на сервер.
Важно: изменять коммиты уже отправленные на сервер нельзя, т.к. у других пользователей, работающих с этим репозиторием, сразу возникнут проблемы при получении и отправке изменений.
Часто встречается ситуация, когда разработчик делает множество локальных коммитов на любое небольшое изменение. В итоге к моменту отправки у него накапливается большое количество коммитов, которые и рецензировать будет сложно и историю репозитория они сильно замусорят – среди них сложно будет понять, что реально было сделано. В этом случае поможет схлапывание коммитов в один или несколько.
Существует несколько методов схлапывания. Выбирать конкретный метод стоит исходя из ситуации. Например, если ведется одновременная разработка клиента и сервера, и нужно схлопнуть коммиты по областям – отдельно серверные изменения, отдельно клиентские, то стоит воспользоваться методом схлапывания через reset.
Если нужно схлопнуть конкретные коммиты в несколько, то лучше воспользоваться интерактивным режимом rebase’а.
По истории репозитория ищем коммит, после которого расходится история локальной ветки и удаленной (в которую должны попасть изменения). Далее нажать ПКМ на этот коммит и выбрать пункт Reset current branch to here.
В открывшемся окне поставить опцию reset type в soft, которая поставит указатель текущей ветки в указанный коммит. После чего все изменения всех файлов из локальных коммитов попадут одним плоским списком в индекс, и их останется только закоммитить и сделать rebase на нужную ветвь.
Перед отправкой своих изменений на сервер необходимо предварительно получить свежие изменения с сервера. В противном случае при попытке отправки будет выведен диалог запроса на получение изменений, в котором необходимо ответить “pull with rebase”.
После получения всех изменений с сервера и решения конфликтов (если они получились), нужно нажать на кнопку push (выделена красным). Так же push можно сделать через меню Commands > Push… или горячими клавишами Ctrl-вверх.
В открывшемся окне убедиться, что отправляем на сервер нужную ветку и нажать на кнопку Push.
Если необходимо отменить изменения в рабочей папке, это можно сделать через окно коммита.
В открывшемся окне выбрать нужные файлы, изменения в которых необходимо откатить и через контекстное меню выбрать Reset file or directory changes.
Также для отмены всех изменений в рабочей папке можно воспользоваться командой из меню Commands -> Reset changes.
Если изменения еще не были отправлены на сервер, то один или несколько последних коммитов можно откатить, выполнив reset на требуемый коммит с опцией hard. Reset hard удаляет все изменения из рабочей папки, индекса и репозитория. Пользоваться этой опцией нужно аккуратно т.к. можно случайно потерять все свои изменения.
Просто отменить изменения на сервере через reset или rebase нельзя. Все, что отправлено на сервер – это история, которая не подлежит изменению. Если же оказалось необходимым откатить конкретный коммит, который уже был отправлен на сервер, то можно воспользоваться командой revert. Для этого выбрать в истории репозитория коммит, который хотим откатить, и через контекстное меню выбрать Revert commit.
После выполнения этой команды, откаченные изменения автоматически попадут в индекс, и их останется только закоммитить и отправить на сервер, или же можно поставить галочку “Automatically create a commit”, тогда коммит с откатом изменений будет создан автоматически, и останется только отправить его на сервер.
Чтобы исправить свои отправленные изменения, которые были откачены с помощью revert, можно сделать revert для revert-commit’а. Изменения появятся в индексе, их можно поправить и залить.
Чтобы создать ветку, нужно нажать ПКМ на нужном коммите, на котором будет находится текущий указатель ветки. В контекстном меню выбрать Create new branch. В открывшемся окне указать имя ветви и нажать Create branch.
Использовать слово master в ветках кроме master нельзя.
Для переключения веток нужно воспользоваться переключателем сверху:
В выпадающем списке отображаются только локальные ветки. Для переключения на remote-ветки необходимо выбрать пункт «Checkout branch...», и в открывашемся окне выбрать удаленную ветку, на которую надо переключиться.
При соблюдении рекомендаций, описанных ниже, будут исключено большинство ситуаций трудоёмкого объединения разработки, за счет исключения конфликтов слияния файлов программного кода и метаданных. В главе Рекомендации по разрешению конфликтов описаны примеры разрешения возникающих конфликтов.
При перекрытии и создании новых типов сущностей в среде разработки платформой создается множество автогенерируемых файлов. Поэтому рекомендуется создавать новые типы сущностей и перекрытия в ветке dev. При этом изменения необходимо сразу отправлять на сервер, чтобы разработчики могли использовать данные типы и перекрытия.
Если новый тип был создан в рамках ветки фичи, то изменения необходимо зафиксировать отдельным коммитом для возможности передачи изменений в другие ветки git-механизмом «cherry-pick». Пример использования данного механизма в Git Extensions Cherry pick commit.
Объекты, которые необходимо создавать в целевой ветке master или dev:
Примечание. При переименовании объектов меняется большое количество файлов метаданных. Объекты необходимо переименовывать только в ветке разработки в момент, когда нет активных веток фич. Для этого вся текущая разработка по фичам должна быть слита в целевую ветку, после переименования объектов создаются новые ветки для продолжения разработки с актуальными наименованиями. Данные работы необходимо проводить согласованно всей командой разработки.
Чтобы снизить вероятность ошибок при слиянии файлов cs, необходимо по возможности выделять блоки кода в регионы, примеры описаны ниже. Также необходимо добавлять новые функции при помощи команды «Добавить» из редактора формы сущности, чтобы они создавались в начале файла.
На начальном этапе разработки на проекте часто возникает ситуация, когда несколько разработчиков изменяют код инициализации модуля. Чтобы избежать конфликтов при слиянии разработки, рекомендуется копировать регионы, имена и порядок вызова функций из файла инициализации модуля Docflow. Функции инициализации добавляются по мере необходимости.
Во избежание дублирования функций и затирания разработки в обработчиках схемы задачи, необходимо разделять события на соответствующие блоки, выделять их в регионы и сохранять порядок по автоматической нумерации блоков из схемы задачи (например, «блок 4»). Такой подход позволит избежать дублирования кода при ручном слиянии разработки.
Для решения конфликтов рекомендуется использовать инструмент визуального сравнения и слияния исходного кода.
Метаданные новых свойств сущностей добавляются в файл ../<Имя_модуля>.Shared/<Имя_сущности>/<Имя_сущности>.mtd, в блок Properties. При слиянии разработки возникают конфликты из-за общей структуры, но разных идентификаторов и названий. Ниже показан пример конфликта при добавлении свойств параллельно в двух ветках.
Для решения конфликта необходимо оставить исходный файл целевой ветки и добавить метаданные свойства из ветки фичи, используя инструмент визуального сравнения и слияния разработки. Далее необходимо указать PreviousPropertyGuid идентификатора NameGuid для свойства целевой ветки как показано ниже.
Примечание. Выстроенный порядок метаданных может влиять на отображение в списках сущностей для абстрактных типов, в наследниках которых необходимо вывести одинаковые свойства.
Метаданные новых действий для сущностей добавляются в файл ../<Имя_модуля>.Shared/<Имя_сущности>/<Имя_сущности>.mtd, в блок Actions. Ниже приведён пример конфликта при слиянии двух новых действий.
Для решения конфликта необходимо оставить исходный файл целевой ветки и добавить метаданные свойства из ветки фичи как показано ниже, используя инструмент визуального сравнения и слияния разработки. При этом порядок расположения функций не влияет на сборку проекта.
При слиянии модификаций обложки модуля часто возникаю конфликты в метаданных для описания положения групп действий.
Для решения конфликта необходимо оставить исходный файл целевой ветки и добавить метаданные группы из ветки фичи, используя инструмент визуального сравнения и слияния разработки.
Авторизуйтесь, чтобы написать комментарий