Git — несколько решений Visual Studio в одном репозитории

Из VS2022 невозможно создать один репозиторий Git для хранения нескольких решений VS, поэтому для достижения этой цели мы использовали SourceTree. В статье представлены технические подробности этого процесса.

У меня появилась задача — я хотел опубликовать на GitHub исходный код из одной своей статьи, чтобы пользователи могли его скачивать. Проблема заключалась в том, что исходный код для одной статьи состоял из четырёх решений Visual Studio на C#. Я не хотел мерджить решения в одно, к тому же это было бы глупо, ведь эти решения VS содержали проект с одинаковым названием, который являлся эволюцией кода, объясняемого мной в статье. Я хотел, чтобы пользователь смог получить весь исходный код из статьи в одном клоне. Структура папок выглядит так:

Я открыл VS2022 и оказался в тупике. В VS2022 один репозиторий Git должен соответствовать одному решению VS. А у меня было несколько решений VS на C#, которые мне нужно было упаковать в один репозиторий. И что теперь делать?

1. Проверяем технологию: Git Submodule или Git Subtree

Я подумал, что мне поможет часть технологии Git, например, Submodule или Subtree. Однако после их тщательного изучения оказалось, что они не предназначены для этой задачи. Я не хотел делиться кодом библиотеки и получать всё с GitHub за один раз. Мне не удалось найти, как в Git создать «рабочее пространство», содержащее несколько репозиториев и обрабатываемое как один с точки зрения «git clone».

2. Решение — создание единого репозитория в SourceTree

Я решил, что лучше всего будет создать репозиторий Git в папке более высокого уровня, содержащей все четыре решения. Таким образом мне удастся хранить четыре решения в одном репозитории Git. Я сразу понял, что у меня будут ветки для репозитория, а не для каждого решения VS.

▍ 2.1. Создание репозитория

Я изучил опции Git в VS2022 и понял, что они ограничены, поэтому мне придётся использовать другой инструмент Git. Для создания репозитория папки высокого уровня я решил воспользоваться Sourcetree.

Пока коммиты выполнять нельзя! Сначала нам нужно настроить файл .gitignore. Если не настроить .gitignore, то в репозиторий будут сохраняться все файлы проекта, в том числе двоичные файлы и промежуточные файлы сборок, а нам этого не нужно.

▍ 2.2. Настраиваем .gitignore

Для эмуляции работы VS2022 я скопировал в корень моего репозитория два файла, сгенерированных VS2022: файлы .gitignore и .gitattributes, которые были созданы в другом проекте на C#, а затем закоммитил их.

Мы делаем это вручную, поскольку не используем VS2022 для создания репозитория Git; в противном случае VS2022 автоматически создал бы файл .gitignore, соответствующий выбранному типу проекта. Так как мы взяли на себя ответственность по ручному созданию репозитория в SourceTree, именно мы должны создать правильный файл .gitignore.

▍ 2.3. Коммиты файлов решений VS на C#

Затем я закоммитил все файлы решений Visual Studio в репозиторий. Так как .gitignore настроен, коммит будет игнорировать двоичные файлы и тому подобное.

▍ 2.4. Создание репозитория GitHub

Далее я создал удалённый аккаунт репозитория на GitHub и запушил файлы.

Можно просмотреть репозиторий на удалённой стороне и убедиться, что в него не выполнен коммит двоичных файлов или других файлов проекта. Если это произошло, значит, что-то не так с файлом .gitignore.

▍ 2.5. Мерджинг веток, которые невозможно смерджить

Проблема, которая возникла у меня сейчас, но, я уверен, возникнет многократно у меня и других людей, в том, что в конечном итоге у меня получились две ветки: main и master. Ветку main по умолчанию создаёт GitHub, в ней находится файл readme. Ветку master по умолчанию создаёт SourceTree, и в ней находится мой код (четыре решения VS).

Нам не нужны здесь две ветки, поэтому давайте смерджим их и избавимся от одной. Сохраним стандартную ветку main GitHub и удалим master.

Но при попытке слияния этих двух веток возникает проблема:

Это приводит к ошибке: fatal: refusing to merge unrelated histories.

Поскольку наши две ветки не имеют общего коммита-предка, SourceTree считает, что мы делаем что-то не так. Но мы знаем, что правы, и хотим заставить его это сделать.

В [1] написано, что эту проблему нельзя решить через GUI SourceTree. Значит, нам нужно выполнить команды командной строки Git в GitBash. Объяснение проблемы и инструкции приведены в [2].

Нужно выполнить git merge <branch-name> --allow-unrelated-histories.

Итак, можно открыть GitBash из SourceTree (кнопка Terminal), и исполнить команду. Вам будет предложено ввести комментарий к коммиту в отдельном текстовом редакторе. Затем продолжится мерджинг.

И вот как будут выглядеть слитые ветки:

Далее запушим изменения в GitHub и проверим, что в ветке main теперь находятся все наши файлы:

▍ 2.6. Удаление ненужной ветки

Теперь можно удалить ветку master локально в SourceTree и удалённо в GitHub. Вот как всё выглядит. История веток сохранилась, но в ней нет ветки master:

3. Проверка решения в VS2022

Далее нужно проверить, как всё выглядит на стороне VS2022. Сначала получим URL клонирования:

Затем клонируем репозиторий в VS2022.

И вот что мы получили: все четыре решения одновременно.

Нажав на одно из решений, мы перейдём к нему:

Нажав на кнопку выше, мы можем перейти к просмотру всех четырёх решений.

Именно этого мы и хотели. Единственная проблема заключается в том, что все четыре решения находятся в одной ветке — ветке main. Вероятно, лучше всего было бы создать по отдельной ветке для каждого решения и проверять изменения в коде там.

4. Заключение

Большинство моих проектов ведётся в TFS, поэтому я был поражён, насколько просто победить VS2022 простой идеей о помещении нескольких решений в один репозиторий Git. Без внешнего инструмента наподобие SourceTree или командной строки GitBash было бы невозможно это сделать.

Насчёт Git я подумал следующее: разве это не опенсорсный проект? Нельзя ли дополнить его концепцией «рабочего пространства», которое сможет содержать несколько репозиториев Git? Это позволило бы избежать неприятной ситуации, в которой все четыре решения находятся в одной ветке. Если у вас есть время изучить этот вопрос, то рекомендую посмотреть ссылки на сообщество Git [3] и [4].

5. Ссылки

Конкурс статей от RUVDS.COM. Три денежные номинации. Главный приз — 100 000 рублей.


ссылка на оригинал статьи https://habr.com/ru/company/ruvds/blog/685300/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *