Страницы

Поиск по вопросам

воскресенье, 8 декабря 2019 г.

Как создать git-репозиторий на базе репозитория подрядчика

#git


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

Ниже -- детали вопроса.

Организация-заказчик. В интернет выставлен сервер, используемый в качестве git-сервера,
сложных методологий работы с git (типа git-flow) не использовали - хватало модели «общего
репозитория» (The Shared Repository Model). Одна ветка master, в которую вливали все
изменения - вот и вся методика.

Организация-подрядчик. В интернет выставлен сервер с gitlab на борту. Можно сделать
git clone на "посмотреть".

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

Хочется следующего:


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

    


Ответы

Ответ 1



В любом случае, кто то должен кому то дать доступ к репозиторию. Но гит на то он и гит, что позволяет использовать два удаленных репозитория. Первый вариант. Назначается один (или несколько) "ответственный за интеграцию". У него должен быть доступ к обеим серверам с гит репозитариями. Он будет пулить с обеих репозиториев, мерджить и пушить обратно. Детальнее можно читать здесь. Если админы и начальство категорически не разрешает выпускать гит наружу (всякое бывает), то данный человек может делать это с ноутбуком и перемещатся между офисами или использовать vpn. Если изменения будут проходить в основном с одной стороны, то работа будет очень простой. Плюсы: репозитории легко поддерживать в согласованном состоянии минимум ручной работы Минусы: нужны доступы возможна утечка конфиденциальной информации Способ второй. У каждого свой репозиторий. Когда вносят какие то изменения (пофиксили баг), то патч высылается почтой (обычной, электронной). А на другой строне просто применяется. В git для этого есть целый набор инструментов и достаточно хорошо автоматизировано. В этой схеме должно быть как минимум два человека - один, который будет формировать патчи и отправлять их почтой, другой, который будет их применять. Плюсы: репозитории независимы. никто не знает, что именно есть в чужом репозитории. можно применять избранные патчи можно хорошо анализировать патчи Минусы: репозитории скорее всего "разойдутся". много нужно делать "ручками"

Ответ 2



Попробовал смоделировать ситуацию на двух тестовых репозиториях: avn - репозиторий, который находится у фирмы-подрядчика fcs - репозиторий, который находится у фирмы-заказчика Ответственных за интеграцию двое: один у заказчика, один у подрядчика. Оба репозитория полагаем доступными по сети интернет для менеджеров. Фаза 1. Разработка на сервере подрядчика. Заполним два-три коммита для моделирования того, как подрядчик работает: touch avn-file1.txt git add avn-file1.txt git commit -m "avn-file1.txt" ... touch avn-file3.txt git add avn-file3.txt git commit -m "avn-file3.txt" И периодически пушим их на сервер. В какой-то момент принимается решение, что настал "час Х" и можно публиковать проект у заказчика. Останавливается разработка, в репозитории avn у подрядчика вот такая история коммитов: pick fdf9508 avn-file1.txt pick 0633d9c avn-file2.txt pick 4d71f77 avn-file3.txt Фаза 2. Создание собственного репозитория на базе репозитория подрядчика Клонируем репозиторий подрядчика и переписываем origin на адрес собственного репозитория (правим файл /.git/config -- ну или по-грамотному: через git remote set-url origin <сервер заказчика>), затем git push -f. Получаем на собственном сервере абсолютно точную копию репозитория подрядчика, с полным сохранением истории и даже SHA-1 коммитов будут совпадать: pick fdf9508 avn-file1.txt pick 0633d9c avn-file2.txt pick 4d71f77 avn-file3.txt Переходим к следующей фазе. Фаза 3. Заказчик выполняет какие-то доработки на своё усмотрение и без оглядки на бывшего подрядчика. Ну, допустим, опять же создадим несколько коммитов: touch fcs-file1.txt git add fcs-file1.txt git commit -m "fcs-file1.txt" ... touch fcs-file3.txt git add fcs-file3.txt git commit -m "fcs-file3.txt" И будем их периодически пушить на собственный сервер. (В реальности fcs -- это bare-репозиторий на сервере, который несколько разрабочиков в компании-заказчика склонировали себе на рабочие станции, но это некритично для теста.) Получаем на своём сервере такую историю: pick fdf9508 avn-file1.txt pick 0633d9c avn-file2.txt pick 4d71f77 avn-file3.txt pick 7dd4772 fcs-file1.txt pick f33cdda fcs-file2.txt pick c54c562 fcs-file3.txt (Первые три коммита -- это сделанные когда-то подрядчиком, следующие три -- уже заказчик. У подрядчика до сих пор в его репозитории только три коммита) И тут в некоторый момент, заказчик вспоминает про подрядчика и даёт ему какую-то задачу на доработку. Дальнейшее взаимодействие идёт по схеме: а) подрядчик забирает изменения сделанные заказчиком после сдачи проекта б) подрядчик делает какие-то доработки в своём репозитории в) заказчик забирает доработки к себе на сервер. Итак, поехали: Фаза 4. Подрядчик забирает изменения сделанные заказчиком У подрядчика есть какой-то сотрудник, ответственный за интеграцию, скажем, Вася или Петя. Вася в репозитории avn (на своей машине) подключает удалённый репозиторий fcs и называет его (внезапно) именно как fcs: git remote add fcs <адрес репозитория подрядчика> И может периодически вливать в свою ветку мастер изменения, которые внесены заказчиком (разом, не мелочимся с fetch+merge): [vasya@wrkst1 avn]$ git pull fcs master remote: Counting objects: 7, done. remote: Compressing objects: 100% (6/6), done. remote: Total 6 (delta 2), reused 0 (delta 0) Unpacking objects: 100% (6/6), done. From gitserver:polygon/fcs * branch master -> FETCH_HEAD Updating 4d71f77..c54c562 Fast-forward fcs-file1.txt | 0 fcs-file2.txt | 0 fcs-file3.txt | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 fcs-file1.txt create mode 100644 fcs-file2.txt create mode 100644 fcs-file3.txt И на сервере подрядчика оказываются те же самые 6 коммитов, что и у заказчика с теми же самыми SHA-1. Фаза 5. Подрядчик делает какую-то доработку touch avn-megafix1.txt git add avn-megafix1.txt git commit -m "avn-megafix1.txt" Теструет, заливает в своё хранилище, сообщает ответственному за интеграцию со стороны заказчика, чтобы тот забрал доработки. Фаза 6. Заказчик забирает изменения в свой репозиторий. В принципе, действия симметричны шагу 4: ответственный за интеграцию у заказчика подключает на своей копии репозитория fcs удалённый репозиторий avn: git remote add avn <адрес репозитория подрядчика> И после этого может забирать изменения с сервера подрядчика: git pull avn master Получая точно таки же коммиты, с теми же самыми идентификаторами SHA-1, что и у подрядчика. В принципе, вот и всё в общих чертах. Действительно, ничего сложного - главное, чтобы сервера были доступны.

Ответ 3



Вариант "передать бэкап базы и архив с файлами" разумеется не подходит: хочется оставить всю историю коммитов git — это распределённая система управления версиями. любой клон (сделаный командой git clone) — это полноценное хранилище с полной историей. если единственный способ связи — обмен файлами, то можно воспользоваться, например, командой git bundle. или, в крайнем случае, сделать архив содержимого хранилища — то есть (в не-bare хранилище) каталога .git. в этом каталоге и содержится вся история. предусмотреть возможность внесения патчей подрядчиками без доступа к хранилищам друг друга заказчик и разработчик могут обмениваться патчами: с помощью команды git format-patch можно сформировать набор патчей (по одному на коммит), а с помощью команды git apply можно применить эти патчи к другому клону этого хранилища. если всё же есть доступ к хранилищу подрядчика по любому поддерживаемому программой git протоколу — git/ssh/http/https, то можно подключить к существующему клону и дополнительные хранилища с помощью команды git remote, забирать изменения командой git fetch и сливать их с локальной веткой командой git merge. подробности: создание пакетов (bundles) и man git-bundle патчи: общее применение и man git-format-patch, man git-apply несколько удалённых хранилищ и man git-remote, man git-fetch, man git-merge

Комментариев нет:

Отправить комментарий