Создание сайтов в Дзержинске, ДНР. Понимание и работа с подмодулями в Git

 
 

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

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

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

Хранение кода отдельно

Чтобы понять, почему подмодули Git действительно являются бесценной структурой, давайте рассмотрим случай без подмодулей. Когда вам нужно включить сторонний код (например, библиотеку с открытым исходным кодом), вы, конечно, можете пойти простым путем: просто загрузить код с GitHub и выгрузить его куда-нибудь в свой проект. Хотя этот подход, безусловно, быстрый, он определенно грязный по нескольким причинам:

Путем грубого копирования стороннего кода в ваш проект вы эффективно смешиваете несколько проектов в один. Граница между вашим собственным проектом и чужим (библиотекой) начинает стираться.

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

Общее правило в разработке программного обеспечения «разделять отдельные вещи» существует не просто так. И это, безусловно, верно для управления сторонним кодом в ваших собственных проектах. К счастью, концепция подмодуля Git была создана именно для таких ситуаций.

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

Однако вы можете возразить, что архитектура подмодулей Git имеет несколько преимуществ:

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

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

Что такое подмодули Git на самом деле

Подмодули в Git — это просто стандартные репозитории Git. Никаких модных инноваций, только те репозитории Git, которые мы все уже так хорошо знаем. В этом также заключается часть силы субмодулей: они настолько надежны и просты, потому что они такие «скучные» (с технологической точки зрения) и проверенные в полевых условиях.

Единственное, что делает репозиторий Git подмодулем, это то, что он помещается внутри другого, родительского репозитория Git.

В остальном подмодуль Git остается полностью функциональным репозиторием: вы можете выполнять все действия, которые вы уже знаете из своей «обычной» работы с Git — от изменения файлов до фиксации, извлечения и отправки. В подмодуле возможно все.

Добавление подмодуля

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

$ mkdir lib

$ cd lib

Теперь мы готовы закачать в наш проект сторонний код, но упорядоченно, используя подмодули. Допустим, нам нужна небольшая JavaScript-библиотека «преобразователь часовых поясов»:

$ git submodule add https://github.com/spencermountain/spacetime.git

Когда мы запускаем эту команду, Git начинает клонировать репозиторий в наш проект как подмодуль:

Cloning into 'carparts-website/lib/spacetime’...

remote: Enumerating objects: 7768, done.

remote: Counting objects: 100% (1066/1066), done.

remote: Compressing objects: 100% (445/445), done.

remote: Total 7768 (delta 615), reused 975 (delta 588), pack-reused 6702

Receiving objects: 100% (7768/7768), 4.02 MiB | 7.78 MiB/s, done.

Resolving deltas: 100% (5159/5159), done.

И если мы посмотрим на папку с нашей рабочей копией, то увидим, что файлы библиотеки действительно прибыли в наш проект.

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

— Так какая разница? Вы можете спросить. В конце концов, файлы сторонних библиотек находятся здесь, как если бы мы их скопировали и вставили. Ключевое отличие состоит в том, что они действительно содержатся в собственном репозитории Git! Если бы мы просто загрузили несколько файлов, добавили их в наш проект, а затем закоммитили — как и другие файлы в нашем проекте — они были бы частью того же репозитория Git. Однако подмодуль следит за тем, чтобы файлы библиотеки не «просочились» в репозиторий нашего основного проекта.

Посмотрим, что еще произошло:.gitmodulesв корневой папке нашего основного проекта создан новый файл. Вот что он содержит:

[submodule «lib/spacetime»]

path = lib/spacetime

url = https://github.com/spencermountain/spacetime.git

Этот.gitmodulesфайл является одним из нескольких мест, где Git отслеживает подмодули в нашем проекте. Другой —.git/config, который теперь заканчивается так:

[submodule «lib/spacetime»]

url = https://github.com/spencermountain/spacetime.git

active = true

И, наконец, Git также хранит копию.gitрепозитория каждого подмодуля во внутренней.git/modulesпапке.

Все это технические детали, которые вам не нужно помнить. Однако это, вероятно, поможет вам понять, что внутреннее обслуживание подмодулей Git довольно сложно. Вот почему важно убрать одну вещь: не возитесь с конфигурацией подмодуля Git вручную! Если вы хотите переместить, удалить или иным образом манипулировать подмодулем, сделайте себе одолжение и не пытайтесь делать это вручную. Либо используйте соответствующие команды Git, либо графический интерфейс рабочего стола для Git, например «Tower», который позаботится об этих деталях за вас.

Графические интерфейсы Git для настольных ПК, такие как Tower, упрощают работу с подмодулями Git.

Давайте посмотрим на статус нашего основного проекта, теперь, когда мы добавили подмодуль:

$ git status

On branch master

Changes to be committed:

(use «git restore —staged ...» to unstage)

new file:.gitmodules

new file: lib/spacetime

Как видите, Git рассматривает добавление подмодуля как изменение, как и любое другое. Соответственно, мы должны зафиксировать это изменение, как и любое другое:

$ git commit -m «Add timezone converter library as a submodule»

Клонирование проекта с помощью подмодулей Git

В нашем примере выше мы добавили новый подмодуль в существующий репозиторий Git. А как насчет «наоборот», когда вы клонируете репозиторий, который уже содержит подмодули?

Если бы мы выполнили ваниль git clone <remote-URL>в командной строке, мы бы загрузили основной проект — но обнаружили бы, что любая папка подмодуля пуста! Это еще раз яркое доказательство того, что файлы подмодулей являются отдельными и не включаются в свои родительские репозитории.

В таком случае, чтобы заполнить подмодули после того, как вы клонировали их родительский репозиторий, вы можете просто выполнить git submodule update —init —recursiveпотом. Еще лучший способ — просто добавить —recurse-submodulesопцию прямо во время звонка git clone.

Проверка изменений

В «обычном» репозитории Git мы обычно проверяем ветки. Используя git checkout or the newer git switch , мы сообщаем Git, какой должна быть наша текущая активная ветка. Когда в этой ветке делаются новые коммиты, указатель HEAD автоматически перемещается на самый последний коммит. Это важно понимать — потому что подмодули Git работают по-разному!

В подмодуле мы всегда проверяем конкретную ревизию, а не ветку! Даже когда вы выполняете команду, как git checkout mainв подмодуле, в фоновом режиме отмечается последняя на данный момент фиксация в этой ветке, а не сама ветка.

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

Если вы хотите узнать, какую версию используют ваши подмодули, вы можете запросить эту информацию в своем основном проекте:

$ git submodule status

ea703a7d557efd90ccae894db96368d750be93b6 lib/spacetime (6.16.3)

Это возвращает текущую проверенную версию нашего lib/spacetimeподмодуля. И это также позволяет нам узнать, что эта версия является тегом с именем «6.16.3». Теги часто используются при работе с подмодулями в Git.

Допустим, вы хотели, чтобы ваш подмодуль использовал более старую версию с тегом «6.14.0». Во-первых, мы должны изменить каталоги, чтобы наша команда Git выполнялась в контексте подмодуля, а не нашего основного проекта. Затем мы можем просто запустить git checkoutс именем тега:

$ cd lib/spacetime/

$ git checkout 6.14.0

Previous HEAD position was ea703a7 Merge pull request #301 from spencermountain/dev

HEAD is now at 7f78d50 Merge pull request #268 from spencermountain/dev

Если мы теперь вернемся в наш основной проект и git submodule statusснова выполним его, мы увидим отражение нашей проверки:

$ cd... /...

$ git submodule status

+7f78d50156ae1205aa50675ddede81a61a45fade lib/spacetime (6.14.0)

Однако внимательно посмотрите на вывод: маленький +символ перед этим хешем SHA-1 говорит нам, что подмодуль находится в другой версии, чем в настоящее время хранится в родительском репозитории. Поскольку мы только что изменили проверенную версию, это выглядит правильно.

Вызов git statusнашего основного проекта теперь также информирует нас об этом факте:

$ git status

On branch master

Changes not staged for commit:

(use «git add ...» to update what will be committed)

(use «git restore ...» to discard changes in working directory)

modified: lib/spacetime (new commits)

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

$ git commit -m «Changed checked out revision in submodule»

$ git push

Обновление подмодуля Git

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

Давайте сделаем простое git pullв нашем основном проекте — как мы, вероятно, делали бы довольно часто — чтобы получить новые изменения из общего удаленного репозитория:

$ git pull

From https://github.com/gntr/git-crash-course

d86f6e0... 055333e main → origin/main

Updating d86f6e0... 055333e

Fast-forward

lib/spacetime | 2 +-

1 file changed, 1 insertion (+), 1 deletion (-)

Предпоследняя строка указывает, что-то в нашем подмодуле было изменено. Но давайте посмотрим поближе:

$ git submodule status

+7f78d50156ae1205aa50675ddede81a61a45fade lib/spacetime (6.14.0)

Я уверен, вы помните этот маленький +знак: он означает, что указатель подмодуля был перемещен! Чтобы обновить нашу локально извлеченную версию до «официальной», которую выбрал наш товарищ по команде, мы можем запустить updateкоманду:

$ git submodule update lib/spacetime

Submodule path 'lib/spacetime’: checked out '5e3d70a88180879ae0222b6929551c41c3e5309e’

Хорошо! Наш подмодуль теперь проверен в ревизии, которая записана в нашем основном репозитории проекта!

Работа с подмодулями в Git

Мы рассмотрели основные строительные блоки работы с подмодулями Git. Остальные рабочие процессы действительно вполне стандартны!

Например, проверка новых изменений в подмодуле работает так же, как и в любом другом репозитории Git: вы запускаете git fetchкоманду внутри репозитория подмодуля, за которой, возможно, следует что-то вроде git pull origin main, если вы действительно хотите использовать обновления.

Внесение изменений в подмодуль также может быть полезным для вас, особенно если вы сами управляете кодом библиотеки (поскольку это внутренняя библиотека, а не сторонняя). Вы можете работать с подмодулем, как и с любым другим репозиторием Git: вы можете вносить изменения, фиксировать их, отправлять их и так далее.

Использование полной мощности Git

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

Если вы хотите углубиться и получить представление о некоторых других продвинутых методах Git, я настоятельно рекомендую «Advanced Git Kit «: это (бесплатная!) коллекция коротких видеороликов, которые знакомят вас с такими темами, как Reflog, Interactive Rebase, Cherry -Выбирая и даже разветвляя стратегии.

3D-печать5GABC-анализAndroidAppleAppStoreAsusCall-центрChatGPTCRMDellDNSDrupalExcelFacebookFMCGGoogleHuaweiInstagramiPhoneLinkedInLinuxMagentoMicrosoftNvidiaOpenCartPlayStationPOS материалPPC-специалистRuTubeSamsungSEO-услугиSMMSnapchatSonyStarlinkTikTokTwitterUbuntuUp-saleViasatVPNWhatsAppWindowsWordPressXiaomiYouTubeZoomАвдеевкаАктивные продажиАкцияАлександровск ЛНРАлмазнаяАлчевскАмвросиевкаАнализ конкурентовАнализ продажАнтимерчандайзингАнтрацитАртемовскАртемовск ЛНРАссортиментная политикаБелгородБелицкоеБелозерскоеБердянскБизнес-идеи (стартапы)БрендБрянкаБукингВахрушевоВендорВидеоВикипедияВирусная рекламаВирусный маркетингВладивостокВнутренние продажиВнутренний маркетингВолгоградВолновахаВоронежГорловкаГорнякГорскоеДебальцевоДебиторкаДебиторская задолженностьДезинтермедитацияДзержинскДивизионная система управленияДизайнДимитровДирект-маркетингДисконтДистрибьюторДистрибьюцияДобропольеДокучаевскДоменДружковкаЕкатеринбургЕнакиевоЖдановкаЗапорожьеЗимогорьеЗолотоеЗоринскЗугрэсИжевскИловайскИрминоКазаньКалининградКировскКировскоеКомсомольскоеКонстантиновкаКонтент-маркетингКонтент-планКопирайтингКраматорскКрасноармейскКрасногоровкаКраснодарКраснодонКраснопартизанскКрасный ЛиманКрасный ЛучКременнаяКураховоКурскЛисичанскЛуганскЛутугиноМакеевкаМариупольМаркетингМаркетинговая информацияМаркетинговые исследованияМаркетинговый каналМаркетинг услугМаркетологМарьинкаМедиаМелекиноМелитопольМенеджментМерчандайзерМерчандайзингМиусинскМолодогвардейскМоскваМоспиноНижний НовгородНиколаевНиколаевкаНишевой маркетингНовоазовскНовогродовкаНоводружескНовосибирскНумерическая дистрибьюцияОдессаОмскОтдел маркетингаПартизанский маркетингПервомайскПеревальскПетровскоеПлата за кликПоисковая оптимизацияПопаснаяПравило ПаретоПривольеПрогнозирование продажПродвижение сайтов в ДонецкеПроизводство видеоПромоПромоушнПрямой маркетингРабота для маркетологаРабота для студентаРазработка приложенийРаспродажаРегиональные продажиРекламаРеклама на асфальтеРемаркетингРетро-бонусРибейтРитейлРовенькиРодинскоеРостов-на-ДонуРубежноеСамараСанкт-ПетербургСаратовСватовоСвердловскСветлодарскСвятогорскСевастопольСеверодонецкСеверскСедовоСейлз промоушнСелидовоСимферопольСинергияСколковоСлавянскСнежноеСоздание сайтов в ДонецкеСоледарСоциальные сетиСочиСтаробельскСтаробешевоСтахановСтимулирование сбытаСуходольскСчастьеТелемаркетингТельмановоТираспольТорговый представительТорезТрейд маркетингТрейд промоушнТюменьУглегорскУгледарУкраинскХабаровскХарцызскХерсонХостингЦелевая аудиторияЦифровой маркетингЧасов ЯрЧелябинскШахтерскЮжно-СахалинскЮнокоммунаровскЯндексЯсиноватая