(java || kotlin) && devOps
369 subscribers
6 photos
1 video
6 files
306 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Всем привет!

Поговорим про комментариях к commit.
Вот статья, где приводится пример интересного комментария: https://dhwthompson.com/2019/my-favourite-git-commit

Вообще, я двумя руками за содержательные комментарии, объясняющие что изменилось и почему.
Но этот мне не нравится)
Почему?
1) это перебор. Время, которое мы можем потратить на разработку, конечно. Соответственно, размер комментария должен быть пропорционален его важности и\или объему измененного кода.
2) для того, чтобы поделится знаниями о проблеме, комментарии git не лучший вариант. Они не индексируются поисковиками, если речь про открытые проекты Github. В случае закрытых проектов часто доступ к git-у открыт не для всех. Какой выход - написать статью или пост о решенной проблеме.
3) даже для формирования what's new такой комментарий плохо подходит, т.к. слишком большой и отвлекает внимание на себя от других изменений.

Что думаете?

#git #code_review
Всем привет!

Иногда возникает необходимость создать ветку в репозитории Git никак не связанную с уже существующими ветками.

Первым делом при такой потребности я хочу процитировать наверное самый популярный ответ на StackOverflow - а вам точно нужно это делать?) В данном случае он справедлив, т.к. не стоит хранить в одном репозитории слабосвязанный код:
а) приложение и его библиотеки
б) код и API\документацию\настройки\скрипты БД если их создают члены команды с разными ролями и разным подходом к код-ревью и слиянию - к примеру разработчики и аналитики
в) наоборот, если API\документацию\настройки\скрипты БД создают одни и те же люди - не стоит их разносить по разным веткам.

Но бывают кейсы, требующие нескольких несвязанных между собой веток. Например, две сильно различающиеся версии приложения.
Есть три способа решить эту задачу.
1) очевидный и неправильный - создать новую ветку на основе существующей, удалить все файлы и залить новые
2) изначально завести ветку c readme.md, от которой можно будет создавать новые чистые ветки
3) выполнить вот такие команды
git checkout --orphan newbranch
git rm -rf .
и далее как обычно.

#git
Всем привет!

В продолжение темы функциональности IDEA и подготовки кода к code review, см. https://t.me/javaKotlinDevOps/148
Некоторые проверки и исправления можно подвесить на одно из двух событий:
1) на сохранение файла: Alt-Alt - Actions on Save. Рекомендую включить Reformat code и Optimize import.
2) перед commit на Git сервер - открыть окно Commit (Ctrl-K) и нажать там шестеренку. Рекомендую включить Analyze code, Check TODO и если выполнение тестов занимает приемлемое время - то еще и прогон тестов.
Легко заметить, что набор опций в обоих случаях похож, но на сохранении можно включить только те, где фиксы применяются без участия человека. В частности и Cleanup, и Analyze выполняют правила из набора инспекций (Inspections), только в первом случае включаются только те правила, где есть quick fixes, которые можно применить автоматически.
Насчет Cleanup - IMHO его вполне можно включить на commit, главное перепроверить набор активных правил: Shift-Shift - Inspections, а там включить фильтр Cleanup only. К слову - там еще есть профили с набором правил, можно добавить свой.
И еще важный момент - инспекции из IDEA можно запустить из командной строки, и т.об. включить в CI процесс: https://www.jetbrains.com/help/idea/command-line-code-inspector.html
Они частично повторяют проверки SonarQube, но не идентичны им.

#idea #code_review #clean_code #git
Всем привет!

Уже прошел примерно год как появился ChatGPT. Его активно пытаются применить везде - для решения бизнес-задач, автоматизации рутины и конечно же написания кода. Какую же рутину можно автоматизировать в разработке? А например такую - https://github.com/Nutlope/aicommits

#git #commit
Всем привет!

Микросервисная архитектура, которая становится все более популярной, требует хранения кода каждого сервиса в отдельном репозитории. На всякий пожарный - про остальные требования к микросервисам можно почитать тут https://t.me/javaKotlinDevOps/55
Бонусом мы получаем "штатную" работы IDE, pipeline, механизмов код-ревью. Микросервис подразумевает небольшой объём кода, т.е. все инструменты будут отрабатывать достаточно быстро, с меньшей вероятностью тормозить или падать, меньше вероятность конфликтов merge и т.д.

Зачем же тогда могут понадобится гигантские монорепы?
А ведь примеров хватает:
Яндекс https://habr.com/ru/companies/yandex/articles/469021/
Гугл https://qeunit.com/blog/how-google-does-monorepo/
Microsoft Windows https://habr.com/ru/articles/795635/
И даже Юла: https://habr.com/ru/companies/oleg-bunin/articles/531632/

Отдельно я бы выделил три типовых кейса, не относящиеся к микросервисам:
1) собственно монолит. И причина понятна - странно части монолита собирать из разных репозиториев. Релизный цикл, pipeline все равно же общие
2) игры. Тоже по сути отдельный вид монолита - огромные размеры репо, особенность: основной объем занимают бинарные данные: текстуры, картинки, видео...
3) большие мобильные приложения, SuperApp или стремящиеся к ним. Тоже по сути отдельный случай монолита.

Но в списке выше есть и микросервисы, зачем им лезть в монорепы? Суммируя, можно выделить такие причины:
1) проще контроль над своевременностью обновления библиотек
2) возможность одним PR занести кросс-сервисную фичу. Кстати, полезная штука
3) обучение новичков и обмен знаниями на примерах из других сервисов. Кажется, что это можно сделать и с разными репо, но в монорепе, конечно, удобнее
4) облегчение работы с общим кодом - не надо подключать новые модули явно в каждый сервис, просто работаем с тем, что есть в develop. Опять же все ошибки при выпуске новой версии общего кода ловятся быстрее, т.к. все тесты в одном месте. Конечно тесты, а точнее достаточное тестовое покрытие, должно быть) Рефакторинг, застрагивающий все части системы, как правило связанный с изменением общего API, также проводить проще
5) легче обеспечить унификацию требований к коду. Тоже - можно решить на уровне pipeline и commit hook, но в одном репо проще
6) т.к. модули в монорепо скорее всего работают вместе, а иначе зачем их код хранится вместе - с монорепо можно развернуть тестовый стенд проще, чем с отдельными микросервисами

Что касается минусов - про то как их побороть, можно глянуть статьи выше. Особенно полезна статья про Microsoft, содержащая технические советы по обслуживанию репо на уровне git-а. Часть я знал и ранее, и даже использовал, часть для меня стало сюрпризом. Что особенно важно - все доработки из своего форка git Microsoft портировала в master git. Вот краткий список советов:
1) sparse checkout - выкачивание только нужных папок
2) shallow copy - выкачивание ограниченного числа версии из истории изменений, как правило, только последней
3) клонирование без blob (--filter=blob: none) В blob хранится содержимое файлов. Ясно, что без содержимого файлов разработка невозможна, но в этом режиме git во-первых подкачивает blob для последней версии, а во-вторых - будет подкачивать необходимые ему файлы по требованию
4) также может быть полезно клонирование без checkout, опция --no-checkout, т.е. без копирования собственно файлов в рабочий каталог. Так мы сможем избежать случайного копирования всех файлов до того, как будет проведена фильтрация
5) запуск git maintenance в фоне - обновление графа коммитов, ускоряет выполнение некоторых команд git
6) фоновый монитор файловой системы, настройка git config core.fsmonitor true. Слушает уведомления об изменений файлов в каталоге с исходниками, поэтому git status отрабатывает быстрее.

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

Итоги: если можно обойтись без монорепо - так и нужно делать. Но если все же решили его использовать - боль можно облегчить)

#git #microservices #monorepo
Всем привет!

Нашел вот такую интересную штуку для работы с git - https://gitbutler.com/ По сути ребята взяли идею IDEA ))) с change list-ами, и сделали из change list полноценную ветку. Ну как полноценную - виртуальную, git про них не знает, вся информация о такой ветке хранится локально. change list-у можно дать название и закоммитить отдельно, а в виртуальной ветке, как и в обычной, кроме того можно делать коммиты, а также объединять, переименовывать и откатывать их. Вот видео с основными фишками https://www.youtube.com/watch?v=PWc4meBj4jo

Цель утилиты - одновременная работа над несколькими ветками. Причем судя по видео создание новых веток и переключение между ними реально быстрое, у меня даже иногда возникала мысль - а не ускорили ли они видео) Ну и надо сказать, утилита пропагандирует минимально возможные изменения в коммите и в ветках, в пределе - одно изменение = один коммит, что также способствует скорости работы. В этом она мне напомнила https://darcs.net/Features, где тоже идет упор на то, что каждая строчка с изменением может стать отдельным коммитом. Но в отличие от Darcs GitButler полностью совместим с Git. И активно развивается.

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

Главное неудобство - нельзя работать с ветками в IDEA, т.к. git client, встроенный в IDEA, ничего не знает о виртуальных ветках.

Второй момент - пока доступно только для Mac и Linux, а так я бы попробовал(

#git
Всем привет!

Я уже рассказывал про 5 возможных моделей ветвления в git https://t.me/javaKotlinDevOps/95
Нашел еще одну, причем уверен некоторым читателям этого блога она покажется знакомым)
Встречайте stacked pull requests.
Вот краткое описание https://www.michaelagreiler.com/stacked-pull-requests
А вот еще более краткое от меня:
1) работаем через Pull Requests (PR), они же Merge Requests
2) PR выстраиваем в лесенку
3) вливаем в обратном порядке
4) при изменениях в родительском PR, например, по результату код-ревью, проталкиваем изменения во все дочерние PR

Основное назначение данной схемы:
1) упор на ревью небольших кусочков кода, разделение фичи на мелкие commit-ы, удобные для ревью
2) разного рода миграции, когда на промежуточных стадиях код не компилируется и тесты не проходят, а все вместе - неудобоваримо для код ревью

Данная модель может работать поверх любого их описанных выше flow, за исключение trunk based. trunk based, напомню, вообще убирает Pull Requests, а процесс ревью осуществляется либо при парном программировании, либо пост-фактум.

Альтернативой является один PR с предположим 10 commits. Но преимущество данной схемы в том, что создавая вместо этого 10 PR автор скорее задумается о том, чтобы каждый из них представлял атомарное изменение, удобное для ревью.

#git #vcs #branching
Всем привет!

Минутка истории. И разных подходов к работе с opensource.

1-я история. Жила была компания Microsoft, и в какой-то момент она "запустила" свою инфраструктуру разработки. Были выделены ресурсы для исправление этой ситуации. Один из примеров такой деятельность - перенос исходников в git, создание своего форка git, проверка его на GitHub и вливание форка в основную ветку git. Вот тут немного подробнее про доработку git под требования Microsoft - большой объем репозитория - https://habr.com/ru/articles/795635/

2-я история. Жила была компания Facebook, тогда еще не иноагент) Компания была молодая, но тоже уже столкнулась с проблемой хранения и организации код-ревью на большом объеме кода. Разработчики компании готовы innersource-ить, чтобы решить проблему. Постучались в git, получили отказ с формулировкой - это частный случай, для основной массы пользователей не нужно, делайте маленькие репозитории. Постучались в Mercurial - там ее pull request согласились принять. Перешли на Mercurial https://habr.com/ru/articles/798881 Но предположу, что часть разработчиков на этом не успокоилась и в результате появился Sapling https://sapling-scm.com/docs/introduction/differences-hg
Это новая Version Control System, которая может работать как со своим форматом repo, так и с git. При этом делает упор на частичное клонирование репо и работу с коммитами: быстрый откат, сохранение истории изменений при слиянии коммитов и даже https://sapling-scm.com/docs/commands/absorb

Тут наверное нужна мораль...)
На первый взгляд подход git более последователен - выбрали лидера рынка, допилили, вернули в основную ветку, помогли opensource сообществу. Но с другой стороны git хоть и является стандартом, но не идеален. И Sapling решает ряд его проблем. Кто-то должен протаптывать новые тропы, пусть и ценой чуть большего беспорядка в своей инфраструктуре разработки

#git #vcs
Всем привет!

Небольшой пост из серии "хозяйке на заметку")

Можно ли слить в git 2 проекта, не имеющих общей истории?
Первый вопрос, который тут возникает - а зачем???
Но похоже иногда такая потребность есть, потому что у git merge есть опция --allow-unrelated-histories.
Можно предположить, что такая опция может понадобится если проект начал разрабатываться 2 людьми, при этом забыли сделать общий первый commit. Или были жесткие rewrite-ы)

#git #tricks
Примерный набор команд:
git config submodule.recurse true # добавляет ключ --recurse-submodules ко всем командам кроме clone. В частности checkout и pull
git config diff.submodule log # отображать также изменения в подмодулях при выполнении diff в корне
git config alias.clones 'clone --recurse-submodules' # подтягивать подмодули при клонировании
git config alias.diffs '!'"git diff && git submodule foreach 'git diff'" # показать изменения по всем подмодулям
git config alias.pushs 'push --recurse-submodules=on-demand' # запушить изменения вначале в подмодулях, потом в основной проект
git config alias.updates 'submodule update --remote --merge' # подтянуть изменения подмодулей из удаленных репозиториев и влить их в локальную копию. После этого можно самому вносить изменения в подмодуль

В любом случае предлагаю прочитать статью по ссылке выше.

#git #api #integraion
Вроде простая картинка про работу git, но думаю будет полезно. Ключевые моменты - наличие локального репозитория и staging area #git
Всем привет!

Уже писал про импортозамещение в ПО:

1) IDE https://t.me/javaKotlinDevOps/353
2) Spring plugins https://t.me/javaKotlinDevOps/358

Две ремарки - термин импортозамещение сильно скомпрометировали, но другой более удачный я пока не придумал) И некоторые из описываемых продуктов разрабатывались не для импортозамещения, но события последних лет дали неплохой импульс для их развития.

Так вот, на Highload-е нашёл 2 аналога GitLab/GitHub:

1) GitVerse от Сбера. Как и GigaIDE находится в процессе разработки, в частности аналог Git Actions планируют допилить в ближайших релизах, сейчас для настройки требуется много ручных действий. Две основные фишки: интеграция с GigaCode и облачная IDE на основе VS Code, доступная в рамках бета-тестирования. Для облачной IDE нужен аккаунт и настройка в облаке Сбера - cloud.ru. И к сожалению не поддерживается Java - зато есть Python, Go, С#. Интерфейс аскетичный, но подсветка синтаксиса, AutoComplete, работа с тестами, отладка и консоль есть. Пока все бесплатно, конечно временно) Еще фишка - доступно AI ревью кода https://gitverse.ru/docs/collaborative-work/code-review/#ai-ревью И в целом ревью неплохое - я скормил ему кусок кода "с запахами", и AI нашел там 6 багов из 18. Минус: все работает медленно - думаю сказывается бесплатность и статус беты.

2) GitFlic от Астра (которая Linux). В нём есть Ci/CD, реестр артефактов, статический анализ кода (названный почему-то SAST), REST API и интеграция с Telegram и JIRA. И платная версия, позволяющая добавлять более 5 человек в private репозиторий плюс расширенную поддержку https://gitflic.ru/price Пока нет полноценно баг-трекера, обещают сделать. Еще плюс - тут я быстро нашел как разрешить force push, в отличие от GitVerse)

GitFlic на данный момент выглядит законченным продуктом, но у GitVerse есть свои плюсы - см. выше. Плюс тесная интеграция с облачным провайдером cloud.ru

#импортозамещение #git
(Не) храните большие бинарные файлы в git

Есть такое общеизвестное правило - никогда не храните большие бинарные файлы в git. Почему?
Причин несколько:

1) большие файлы как правило бинарные, а при работе с бинарными файлами мы теряем значительную часто возможностей git - просмотр diff-ов, да процесс code review в целом

2) git начинает тормозить при разрастании репозитория, а учитывая, что хранится вся история изменений - с большими файлами выйти на этот предел (десятки и сотни Gb, вот тут есть пример от Microsoft https://t.me/javaKotlinDevOps/272) уже значительно проще.

И если с первой причиной что-то сделать сложно, то для второй решение есть. И называется оно Git LFS https://git-lfs.com/

Для начала небольшая справка. При git clone скачивается следующая информация:

1) метаданные
а) настройки git
б) список существующих веток и тэгов

2) история коммитов по всем веткам (.git)

3) актуальные версии файлов в текущей ветке

Суть решения:

1) большие файлы хранятся отдельно от текстовых, с текстовыми файлами хранятся только ссылки на них. Переиспользуем возможности файловой системы Linux

2) при клонировании репозитория большие файлы копируются только для текущей ветки, что ускоряет загрузку

Главный вопрос - когда это все может понадобится? Видится такой вариант - хранить контент вместе с исходниками. Вообще контент лучше хранить в CMS, но, например, если есть тесная связь контента с релизом, то может иметь смысл хранить их рядом. Что точно не стоит хранить в git - так это jar-ники.

Еще важный момент - для того, что Git LFS заработал, нужно:
1) проинсталлировать его на сервере
2) включить на репозитории
3) добавить в репозиторий по маске список файлов, которые надо считать большими.
4) существующие файлы в LFS не попадают, их нужно добавить заново или мигрировать

В целом LFS работает прозрачно, но команды git lfs clone и git lfs pull оптимизированы для работы с LFS и загружают данные быстрее.

Проект open source и поддерживаемый, был создан усилиями заинтересованных лиц - GitHub, Bitbucket.

#git