company_banner

Мой любимый Git-коммит

Original author: David Thompson
  • Translation
Прим. перев.: Эта публикация британского программиста, ставшая настоящим хитом в англоязычном интернете, ссылается на Git-коммит 6-летней давности. Он был зафиксирован в одном из открытых репозиториев Government Digital Service — службы, занимающейся развитием цифровых услуг в Великобритании и поддерживающей проект GOV.UK. Сам коммит интересен не столько изменениями в коде, сколько сопровождающим их описанием…


Картинка из xkcd #1296

Я обожаю описания коммитов в Git. При правильном применении их можно назвать одним из самых мощных инструментов по документированию эволюции кодовой базы за время ее существования. Свою точку зрения хочу проиллюстрировать на примере моего самого любимого описания.

Этот коммит относится ко времени, когда я работал в Government Digital Service. Его автором является разработчик по имени Dan Carley, и у него довольно непримечательное заглавие: «Конвертировал шаблон в US-ASCII, чтобы исправить ошибку».

«Я внедрил несколько тестов в ветку feature для соответствия содержимому `/etc/nginx/router_routes.conf`. Они хорошо работали, если запускались командами `bundle exec rake spec` или `bundle exec rspec modules/router/spec`. Но при запуске `bundle exec rake` каждый should-блок завершался с ошибкой:

    ArgumentError:
      invalid byte sequence in US-ASCII

В конечном итоге я обнаружил, что после исключения выражения `.with_content(//)` все ошибки уходят. Что в файле спецификации нет никаких странных символов. А также то, что его можно воспроизвести, вызвав Puppet в том же интерпретаторе:

    rake -E 'require "puppet"' spec

Этот шаблон, похоже, является единственным файлом в нашей кодовой базе с кодировкой ‘utf-8’. Все остальные файлы в ‘us-ascii’:

    dcarley-MBA:puppet dcarley$ find modules -type f -exec file --mime {} \+ | grep utf
    modules/router/templates/routes.conf.erb:                                         text/plain; charset=utf-8

Попытка перекодировать его в US-ASCII завершилась неудачно из-за одного символа, выглядящего как пробел:

    dcarley-MBA:puppet dcarley$ iconv -f UTF8 -t US-ASCII modules/router/templates/routes.conf.erb 2>&1 | tail -n5
      proxy_intercept_errors off;
 
      # Set proxy timeout to 50 seconds as a quick fix for problems
      #
    iconv: modules/router/templates/routes.conf.erb:458:3: cannot convert

После его замены (вручную) файл снова стал ‘US-ASCII’:

    dcarley-MBA:puppet dcarley$ file --mime modules/router/templates/routes.conf.erb
    modules/router/templates/routes.conf.erb: text/plain; charset=us-ascii

Теперь тесты работают! Целый час моей жизни не вернуть...»

В оригинале

Convert template to US-ASCII to fix error


I introduced some tests in a feature branch to match the contents of
`/etc/nginx/router_routes.conf`. They worked fine when run with `bundle exec
rake spec` or `bundle exec rspec modules/router/spec`. But when run as
`bundle exec rake` each should block failed with:

    ArgumentError:
      invalid byte sequence in US-ASCII

I eventually found that removing the `.with_content(//)` matchers made the
errors go away. That there weren't any weird characters in the spec file. And
that it could be reproduced by requiring Puppet in the same interpreter with:

    rake -E 'require "puppet"' spec

That particular template appears to be the only file in our codebase with an
identified encoding of `utf-8`. All others are `us-ascii`:

    dcarley-MBA:puppet dcarley$ find modules -type f -exec file --mime {} \+ | grep utf
    modules/router/templates/routes.conf.erb:                                         text/plain; charset=utf-8

Attempting to convert that file back to US-ASCII identified the offending
character as something that looked like a whitespace:

    dcarley-MBA:puppet dcarley$ iconv -f UTF8 -t US-ASCII modules/router/templates/routes.conf.erb 2>&1 | tail -n5
      proxy_intercept_errors off;

      # Set proxy timeout to 50 seconds as a quick fix for problems
      #
    iconv: modules/router/templates/routes.conf.erb:458:3: cannot convert

After replacing it (by hand) the file identifies as `us-ascii` again:

    dcarley-MBA:puppet dcarley$ file --mime modules/router/templates/routes.conf.erb
    modules/router/templates/routes.conf.erb: text/plain; charset=us-ascii

Now the tests work! One hour of my life I won't get back..



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

Почему мне нравится этот коммит


Бесчисленное число раз я приводил его как пример того, на что способны описания коммитов. Он в чем-то забавен из-за соотношения изменений в коде и размера описания, но нравится он мне вовсе не поэтому.

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

Раскрывает причину внесенных изменений


Лучшие описания коммитов не только повествуют о том, что изменилось, но и объясняют, почему. В нашем случае:

Я внедрил несколько тестов в ветку feature для соответствия содержимому `/etc/nginx/router_routes.conf`. Они хорошо работали, если запускались командами `bundle exec rake spec` или `bundle exec rspec modules/router/spec`. Но при запуске `bundle exec rake` каждый should-блок завершался с ошибкой:

    ArgumentError:
      invalid byte sequence in US-ASCII

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

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

Хорошо подходит для поиска


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

ArgumentError:
invalid byte sequence in US-ASCII

Любой человек, столкнувшийся с этой ошибкой, может выполнить поиск по кодовой базе, либо запустив git log --grep "invalid byte sequence", либо с помощью GitHub'овского поиска по коммитам. На самом деле, судя по результатам поиска, многие так уже поступили и выяснили, кто и когда сталкивался с этой проблемой и как ее решили в итоге.

Обеспечивает полноту картины


В сообщении к коммиту подробно рассказывается о том, как выглядела проблема, как проводилось ее исследование и устранение. Например:

В конечном итоге я обнаружил, что после исключения выражения `.with_content(//)` все ошибки уходят. Что в файле спецификации нет никаких странных символов. А также то, что его можно воспроизвести, вызвав Puppet в том же интерпретаторе.

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

Делает всех чуточку умнее


Дэн здесь сделал одну вещь, которую я очень ценю: привел все команды, которые выполнял на каждой стадии. Это отличный и доступный способ распространения знаний в команде. Читая его описание коммита, можно узнать много нового об инструментарии Unix:

  • в find можно передавать аргумент -exec, чтобы выполнять команду с каждым найденным файлом;
  • добавление \+ в конце команды делает нечто очень интересное (передает несколько имен файлов в команду file, а не выполняет команду по разу для каждого файла);
  • file --mime позволяет узнать MIME-тип файла;
  • существует утилита iconv.

Человек, просматривающий описание, может узнать обо всех этих вещах. Любой, кто наткнется на этот коммит впоследствии, также узнает об этих вещах. Если помножить подобный подход к коммитам на длительное время и достаточное их число, он может стать мощным стимулом-помощником для команды.

Развивает сопереживание и доверие


Теперь тесты работают! Целый час моей жизни не вернуть...

Последний параграф добавляет капельку человечности. Читая эти слова, трудно не почувствовать разочарование Дэна, которому пришлось потратить целый час на поиск скрытой ошибки, и удовлетворение от ее исправления.

Теперь представьте похожее сообщение, прикрепленное ко временному хаку или фрагменту кода-прототипа, который попал в production и «пустил там корни» (как это часто бывает с такими фрагментами). Подобное описание коммита напоминает всем, что за каждым изменением стоит человек, принимающий лучшее решение из возможных с учетом информации, доступной на тот момент.

Хорошие коммиты важны


Признаю, что это экстремальный пример, и не ожидаю, что все коммиты (особенно такого размаха) смогут похвастаться аналогичным уровнем детализации. Однако все же считаю, что это отличный пример объяснения причины изменения, помощи другим в познании нового и вклада в коллективную ментальную модель, связанную с кодовой базой.

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


P.S. от переводчика


Читайте также в нашем блоге:

Флант
744.33
Специалисты по DevOps и Kubernetes
Share post

Comments 92

    +33

    Русский менталитeт уже бомбанул в комментах на гитхабе, уж извините за шовинизм:


      +15
      И это не удивляет, к сожалению. Как вижу на github что кого-то бомбануло, смотрю профиль — очень часто ex-ussr. Даже горячие парни испанцы нервно курят в уголке.
        +35
        бородатый анекдот
        Чем отличаются русский, американский и еврейский форумы?
        — на американском форуме вы задаете вопрос и вам дают ответ
        — на еврейском форуме вы задаете вопрос и вам задают встречный вопрос
        — на русском форуме вы задаете вопрос и вам долго объясняют почему вы мудак

          +12
          Да, вот как раз мне в этом треде все объясняют, какой я мудак на русском форуме :) Только вот там не было вопросов
            +24

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


            Где ещё, кроме как на русском форуме, вам объяснят, кто тут на самом деле мудак?

              +2

              Комментарий добавлен в закладки

                –1
                Так ведь речь идет о российском менталитете, то есть только русские объясняют какой вы мудак, иностранцы тактично об этом умалчивают, ибо зачем отравлять общение. Даже испанцы-итальянцы кстати, вот в чем парадокс. Хорошая статья была на Хабре под названием «Почему мы злые?», я даже не помню, то ли ее и вовсе заминусовали, то ли еле-еле в плюс вывели, ибо казалось бы, можно тоже быть тактичнее, но многим просто изображение в зеркале не понравилось, но как говорится неча на зеркало пенять… Так что все логично, и ваш коммент оказался очень к месту как раз именно на российском ресурсе.
                0
                У вас там аж 4 вопроса
              0
              Скрин конечно обрезан интересно — там есть еще второй абзац, где идут конкретные претензии к такому подходу, и уже дальше они обсуждаются.
                  +3
                  При этом автор комментария всё равно не прав. Длинный коммит действительно сложнее гуглить, но так ли вообще надо гуглить коммиты? Нужно посмотреть историю файла — есть git log и git blame. Нужно посмотреть информацию о задаче — есть трекеры вроде Jira, где и должны решаться подобные вопросы.
                    +9

                    Я — автор комментария. Там в проекте 27к коммитов в проекте, а именно этот коммит был сделан на изменение одного символа. Вся информация в сообщении этого коммита без сомнения ценна и полезна, с деталями, с историей, однако она ничего не стоит, поскольку найти эту информацию будет невозможно, так как сообщение в коммите к изменению одного символа является труднодоступной информацией. Проект когда-то заплатил за эту информацию, но теперь она не стоит ничего, поскольку бесполезно барахтается в море из 27к коммитов. Сможет ли найти эту информацию будущий участник проекта, если столкнется с той же ошибкой? Сообщения к коммитам не гуглятся. А если воспользоваться поиском по гитхабу — то будет слишком много информации на выходе, можете попробовать. Вместо того, чтобы писать такое длинное труднодоступное сообщение (файла, к которому был сделан этот "мой любимый git-коммит" уже нет в проекте — modules/router/templates/, поэтому найти этот коммит еще сложнее), можно было бы написать тест, который проверит кодировку в проекте. Можно было бы написать где-то в readme топик с информацией о используемой кодировке и почему.

                      +13

                      Я уже несколько раз прочитал фразу "сообщения к коммитам не гуглятся", но до сих пор не могу её понять. Что это значит? Кто ищет коммиты в гугле? Если проблема возникает на проекте, в котором я работаю, то я буду искать информацию через сам git (git log --grep=...), и то же самое написано в статье. И в этом случае подробный commit message будет мне только на руку, т.к. он содержит много слов, потому будет попадать в большое число более-менее релевантных "запросов к git log". Это не "труднодоступность", а, наоборот, высокая доступность информации.

                        +3

                        Наверное, имеется в виду, что если искать решение какой-то проблемы в Гугле, то решение, если оно описано в сообщении коммита, никогда не будет показано.

                          0
                          И в этом случае подробный commit message будет мне только на руку, т.к. он содержит много слов
                          А зачем эти «много слов» нужны? Изначально программа выводила информацию, что ошибка связана с кодировкой. Это означает что надо не в гугле/гите информацию о проблеме искать, а кодировку проверять.
                            0

                            Большинство программистов при обнаружении проблем используют другой инструмент для поиска решений. Чаще всего это google, или stackoverflow. Очень малая часть программистов (я бы даже сказал, что это исключение из правила) использует git log --grep, когда у них произошла ошибка кодировки при выполнении скриптов в проекте.

                              0
                              Очень малая часть программистов (я бы даже сказал, что это исключение из правила) использует git log --grep, когда у них произошла ошибка кодировки при выполнении скриптов в проекте.
                              Это же ещё надо знать, что данная проблема уже рассматривалась
                              +1
                              Я думаю тут смысл в том что проще в ридми написать «у нас такая-то кодировка, иначе баги»
                              Вместо того чтобы оставлять эти знания где-то в истории комитов.
                              Hу и плюс вброс на обсуждение темы про нафига никому не нужную историю коммитов.
                          +15

                          Достаточно, чтобы увидеть грубость ("Are you crazy guys?") и сломанный английский.

                            +2
                            как ты думаешь, а твое замечание про «сломанный английский» не попахивает русским менталитетом?
                          0
                          Русский менталитeт уже бомбанул в комментах на гитхабе

                          Я всегда знал, что Линус Торвальдс русский!

                            0
                            Россия — родина слонов!
                            0
                            Человек пытается предотвратить неверный, по его мнению, путь развития отрасли — документация в комментах репозитория, вопросы и обсуждения в пулл-реквестах, подписка на закрытый msdn-репозиторий
                            +13
                            при разработке программ рядом с системой контроля версий всегда неизменно присутствует система отслеживания ошибок и обычно любое изменение, зафиксированное в системе контроля версий, сделано в рамках работы над какой либо задачей из системы отслеживания ошибок и хорошей практикой является указание в комментарии к коммиту номера задачи из багтрекера, а уже в описании задачи обычно подробно описано что надо исправит или сделать и почему и дублировать эту информацию ещё и в коммит кажется несколько избыточным, поэтому обычно в описании к коммиту приводится только то что было изменено в данном конкретном коммите
                              +23

                              Да, вот только баг-трекер потом меняют или закрывают, и в коммитах остаётся только череда ни о чём не говорящих коммитов типа "JIRA-1234", "JIRA-765" и т.д.
                              В данном случае мы имеем дело с ситуацией, когда лучше иметь некоторый избыток информации. Ничто не мешает продублировать её и в коммит, и в баг-трекер.

                                0
                                Все популярные хостинги кода github, gitlab, bitbucket имеют встроенный баг-трекер, есть даже система контроля версий fossil с баг-трекером встроенным напрямую в репозиторий. Всё сделано для того чтобы сохранить историю, но всё равно случается такое что история может потеряться.
                                Поэтому соглашусь что неплохо было бы иметь некоторый избыток информации, например добавить заголовок задачи, но копировать абсолютно всё из баг-трекера вплоть до комментариев это уже слишком.
                                  +1

                                  И вот в один прекрасный момент владелец хостинга в очередной раз решает тихо и незаметно поменять условия использования, и все оттуда потихоньку сваливают. Репозитории, конечно, остаются, ведь в распределённых системах полная копия есть у каждого, и вот её залили на гитлаб вместо гитхаба. А в коммитах — "fixed #123", но такого issue на новом месте нет, и ссылка ссылается в пустоту, по ней даже нельзя выяснить, где раньше лежал этот самый 123.

                                    0

                                    А в чем проблема импортировать тикеты из GitHub в GitLab с сохранением номеров тикетов? Посмотрите на туже Doctrine.

                                      0
                                      Просто потерявшаяся история — это только половина проблемы.

                                      У Magento репозиторий на гитхабе, и они помечают коммиты номером таска в своей _внутренней_ JIRA. Ну, то есть, ты видишь однострочный commit message «MC-12345 Починил вот такую пепяку» и гадаешь, ту ли они пепяку починили…
                                        +1

                                        Вот в этом разница между открытой разработкой проекта и проектом с открытым исходным кодом.

                                          0

                                          То есть вас смущает, то что проекте с открытым исходным кодом в коммите ссылаются на тикет который нельзя почитать? Как и сказал ilammy, это не проблема git или GitHub в частности.


                                          Какую альтернативу вы предложите в контексте обсуждаемой стати при использовании внутренней JIRA? Описывать в каждом коммите полный текст тикета? И даже если тикет на десятку, сотню или даже тысячу коммитов? А как на счет обсуждений тикета? Их тоже дублировать в сообщении к коммитам?

                                            0

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

                                    +19

                                    Ох, да. Я работаю сейчас над проектом, в котором большое количество legacy кода, несмотря на то, что он достаточно молодой. Порой в коде встречаются места, которые иначе как WTF не назовешь. Поэтому на автомате уже привык делать git blame, чтобы попытаться понять неочевидные моменты (особенно хорошо в Idea annotate, затем annotate previous version).


                                    Но увы, аутсорсеры, которые писали проект, помимо огромного количества спагетти-кода, все задачи писали в свою личную JIRA. И все коммиты содержат бессодержательные комментарии двух видов: «Updated code» и «JIRA-nnnn». А еще почти весь проект они сделали на git submodule. Перед отдачей репозитория заказчику они просто скопировали командой cp сабмодули в основное дерево и закоммитили с сообщением De-submodule. То есть 90% истории проекта просто потеряно.


                                    Вот даже не знаю. Трудно удержаться и не проявить «русский менталитет», как написано выше. Ну как можно быть такими «@$@#$@»?


                                    И это аутсорсер не из какой-нибудь страны третьего мира, а из Австралии. Все имена в git log — европейские. Я их теперь навсегда запомнил, и лично для меня теперь Австралия уравнялась со странами третьего мира. Потому что такую дичайшую невежественность как в коде, так и в организации процессов вокруг него, встречал очень редко.

                                      0
                                      насколько я помню, едвали не половина населения Австралии — иммигранты в 1-2 поколении, преимущественно из Азии. Не так давно собеседовался в компанию, где работает бывший коллега. HR была девочка из Индии. Собеседовали тоже 2 индуса и испанец. На фоне в офисе «этнических» белых австралийцев (естественно, я не о бушменамах), как-то тоже не фигурировало. Поэтому тут ничего удивительного.
                                        +6

                                        Увы, там все имена безошибочно европейские. Можно было бы написать книгу о количестве WTF-моментов, с которыми я там столкнулся. Например, у них есть отдельный человек, который занимается написанием HTML и стилей. То есть, по определению должен знать CSS и HTML. Однако, команда rg -t scss '!important' | wc -l возвращает 302. Почти каждый второй стиль содержит !important.


                                        В HTML этот товарищ не знает отличия блочных тегов от инлайновых. И у него в нескольких шаблонах в инлайновые теги вложено несколько блочных. А поскольку это не работало, он приспособил «гениальный» костыль, завернув блочные в тег <object>. И это вполне европейское имя. Вполне было бы понятно, если бы в git blame стояло «Раджив Кумар». Но там стоит вполне себе «Стив Ларссон», и я даже пытался комментировать его коммиты, на что получал только злобные огрызания (я доволно вежливо комментировал).


                                        А что собственно там творилось в коде… Написал бы, но в коммент не помесится, и у меня от воспоминаний об этом разливание желчи уже случилось.


                                        P.S. Из любопытства я почти всех их нашел в LinkedIn по именам и email из истории git. Да, австралийцы. Да, европейцы. Да, каким-то образом даже позаканчивали астралийские ВУЗы. Профили выглядят профессионально… Все из себя молодцы, с кучей достижений и похвал… Только 2+2 сложить не могут в коде без ошибки… Но этого LinkedIn не показывает.

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

                                            По моим наблюдениям, в реально богатых семьях детей пристраивают в какие-нибудь фонды. Человек и при деле, и всегда может сказать: «Я в Чаде боролся с чумой, в Нигерии со СПИДом, в Непале помогал строить систему здравоохранения». И ничего сложнее перекладывания бумажек из одной стопки в другую делать не надо. Зачем обрекать дитя на ужасы программирования?

                                              0
                                              Я не про реально богатые семьи, а просто про хорошие.
                                              Есть деньги на образование, интеллект более-менее присутствует. Куда? Программирование — стильно-модно-молодёжно. А дальше по накатанной — тут поработал год, там поработал два, вот уже опыт три года, завёл блог, пишешь о том, как важно создавать хороший код.
                                              В России такого тоже полным-полно, а приедь какой-нибудь таджик сюда, так ему для устройства программистом придётся много чего показывать и доказывать. Но здесь ещё туда-сюда деньги считают, а в богатых странах и с этим полегче.
                                            +1
                                            > Увы, там все имена безошибочно европейские
                                            Так себе показатель. Я сейчас работаю с офисом в Чикаго, из десяти человек, с которыми регулярно контактирую, шестеро — китайцы, и все они подписываются именами типа Dan, Chuck и Paul, потому что у них там так принято.
                                              +3
                                              Но там стоит вполне себе «Стив Ларссон»
                                              Напомнило анекдот
                                              В аэропорту пограничник проверяет паспорта прибывающих. В очереди стоит явный японец, и когда до него доходит очередь, пограничник обнаруживает в его паспорте ФИО «Свен Свантессон» 8-O Он спрашивает:
                                              — Вы выглядите как японец, а имя-фамилия у Вас типично скандинавские. Как такое вышло?
                                              — Понимаете, когда я иммигрировал к вам в страну, на иммиграционном контроле прямо передо мной стоял скандинав. А когда дошла очередь до меня, пограничник стал заполнять мои документы и спросил, какие у меня имя и фамилия, и я честно ответил: «Таки Еже».
                                              +4

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


                                              class Car:
                                                 transimission_type = enum(MANUAL, AUTO, ORANGE)
                                                 color = enum(RED, GREEN, WHITE, BLACK)

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


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


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


                                              Вот после этого Австралия ну очень низко пала в моих глазах.


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

                                                +2
                                                Похоже скорее просто на опечатку. Вместо ORANGE возможно должна быть роботизированная трансмиссия или вариатор. Ну или просто пример неудачный, раз вы изменили реальную суть объектов )
                                                  +1

                                                  Я переделал пример про машины, чтобы нельзя было догадаться о какой компании и области идет речь. В оригинале не авто и не трансмиссии. В оригинале другой признак и другие значения. Можно привести любой аналогичный пример, например: «пол: мужчина, женщина, русский» или «тапок: черный, белый, 44-го размера».


                                                  Суть в том, что в один атрибут объекта с взаимоисключающими значениями, они поместили два совершенно несвязанных признака. Поэтому в каждом месте, где данные попадают в систему, и где они выводятся (а также при поиске), стояла куча условий типа: «Если transmission_type = ORANGE, то используем дополнительную логику, чтобы вывести настоящий transmission_type и цвет из других атрибутов».


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


                                                  Самое главное, что это было абсолютно ненужно. Чуть позже я отрефакторил весь код, упорядочив атрибуты. Написал миграции, в которых в последний раз использовались эти нечеловеческие атрибуты. Это не знаняло много времени, код стал на порядки проще и понятнее, любые изменения в логику поиска и вывода стало вносить на порядки проще. Это стало занимать часы, тогда как ранее занимало дни и даже недели, т.к. любое незначительное изменение ломало половину предположений в остальных частях кода.


                                                  Это один из тех примеров, когда я до сих пор не могу понять, зачем это было сделано. Или непроходимая тупость, реально непроходимая. Или желание обеспечить себе job security, расчет, что потом их наймут на поддержку и можно будет годами вносить незначительные правки, зарабатывая кучу денег?.. Правду уже никак не узнать. Но склоняюсь к первому варианту, т.к. весь код просто отвратительного качества — видимо, по-другому просто не могли.

                                                  0
                                                  Извините, просто хочу для себя уяснить, в целях повышения образованности. В приведенном вами коде проблема в том, что трансмиссия авто может быть ручной, автоматической, а может быть оранжевым цветом?
                                                    +1
                                                    … и в форме котика.
                                                      0

                                                      Да, на один комментарий выше только что написал более подробное объяснение. Один атрибут хранил два взаимоисключающих несвязанных признака. Еще пример: «рост_человека: высокий, низкий, программист».

                                                  +1
                                                  Вот ещё пример замечательных австралицев, которые пишут свою личную JIRA
                                                  bitbucket.org/atlassian/atlaskit-mk-2/commits/all
                                                    +2
                                                    И это аутсорсер не из какой-нибудь страны третьего мира, а из Австралии. Все имена в git log — европейские. Я их теперь навсегда запомнил, и лично для меня теперь Австралия уравнялась со странами третьего мира. Потому что такую дичайшую невежественность как в коде, так и в организации процессов вокруг него, встречал очень редко.

                                                    Я вынужден вас огорчить. Как это не прискорбно, но профессиональная IT-культура России одна из топовых в мире. Я правда сравниваю только с Германией, но таких заморочек как в России тут нет и близко. Например, в России микросервисы уже пару лет как вышли из моды, а нам тут месяц назад устроили презентацию «Смотрите! Микросервисы! Как круто! Давайте попробуем?». Пробовать разумеется никто не будет…
                                                      0
                                                      Как это не прискорбно, но профессиональная IT-культура России одна из топовых в мире.

                                                      Например, в России

                                                      Есть 1С вообще и 1С-Битрикс в частности.
                                                        +3
                                                        Как это не прискорбно, но профессиональная IT-культура России одна из топовых в мире.

                                                        Тут подумалось, а не может ли это как-то быть связано с токсичностью русскоязычного комьюнити?

                                                          0
                                                          А что сейчас у нас в моде? (пилю микросервисы на grpc).
                                                      +5
                                                      Все зависит от контекста.
                                                      Все internal проекты — имеет смысл выносить в трекеры задач всю историю коммуникаций и поиска решения.
                                                      А публичные — очень полезно иметь один источник правды.
                                                        +5
                                                        хорошей практикой является указание в комментарии к коммиту номера задачи из багтрекера
                                                        Конечно, если коммит имеет отношение к какому-то тикету, номер тикета надо указывать, и это-то обычно не забывают делать. Но коммит не обязательно должен закрывать какой-то известный баг или реализовывать запланированную фичу; кроме того, если на каждый коммит надо глядеть в багзиллу и продираться через портянки комментариев, работать с таким кодом (заниматься археологией) становится очень тяжело.
                                                        дублировать эту информацию ещё и в коммит кажется несколько избыточным
                                                        Репозиторий — штука вполне самодостаточная, и не стоит гвоздями прибивать к нему багтрекер вместо того, чтобы просто писать нормальные логи. :-)
                                                        поэтому обычно в описании к коммиту приводится только то что было изменено в данном конкретном коммите
                                                        Что было изменено понятно и из диффа, зачем же дифф тупо переводить на английский? Хороший лог должен объяснять, почему были сделаны изменения, причем так, чтобы было понятно и без контекста, годы спустя. Собственно, за этим когда-то и придумали правило-совет про 30%-what-70%-why.

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

                                                        Тут ошибка выше уровнем. Какой-то код тупо ждет US-ASCII на вход, не умея в что-то сложнее 7 бит, и вот его и надо патчить так, чтобы понимал, скажем, комменты на французском. А разраб "просто" сделал так, что тесты проходят (что в принципе не так просто оказалось — найти 0xA0 среди 0x20 можно в хекс-редакторе, но не в большинстве обычных текстовых редакторов).

                                                          +7
                                                          А нужно ли? Всё зависит от проекта и его целей.

                                                          Это как снабдить стиралку функциями хлебопечки на случай, если кому-то понадобится засунуть туда тесто.
                                                            +1

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

                                                              +20

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


                                                              message = _('Your') + _('search') + _('returned') + ' ' + \
                                                                 results.count() + ' ' + _('results')

                                                              И это не преувеличение, увы. Они реально полагали, что это адекватный способ перевода. Потом пользователи просто мозг выели из-за того, что проект на нескольких языках, и во всех локалях, кроме английской, эта строка получалась корявой или вообще нечитаемой для носителей языка (учитывая еще, что таких мест много, потому каждое слово могло быть переведено в другом роде/падеже/склонении, т.к. встретилось переводчику в другом контексте). И потребовалось несколько месяцев (!) регулярной долбежки, чтобы объяснить им, что так писать нельзя.


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

                                                              +7
                                                              Это когда ты знаешь что искать…

                                                              А баг в примере из разряда чертовщины, которая вымораживают мозг просто своим присутствием.

                                                              Если не сталкивались, то трудно объяснить тот вагон эмоций, который возникает от ошибок такого рода: ошибка, которой не может быть потому, что не может быть в принципе.
                                                                +12
                                                                А ведь казалось бы, что мешает разработчикам компилятора либо парсера немного позаботиться о пользователях:

                                                                error: unknown start of token: \u{a0}
                                                                 --> src/main.rs:2:19
                                                                  |
                                                                2 |     println!("{}", 42);
                                                                  |                   ^
                                                                Unicode character ' ' (No-Break Space) looks like ' ' (Space), but it is not
                                                                  0
                                                                  А баг в примере из разряда чертовщины, которая вымораживают мозг просто своим присутствием.
                                                                  Вся такая чертовщина возникает на абсолютно ровном месте, из-за чьей-то. Некоторые технологии принципиально не приспособлены для задач для каких их используют. Но обвиняют почему-то чертовщину.
                                                                    +1

                                                                    А Вы ещё не выработали привычку, встретив баг при обработке текстовой строки, переключать редактор в HEX-режим, чтобы посмотреть, что за х...hex-ня в строке?

                                                                      0

                                                                      В Emacs есть очень хорошее сочетание клавиш, по-моему, C-x =, оно отображает в строке статуса символ и его коды в разных системах счисления. Жаль, давно перешел на vim, и до сих пор не знаю, есть ли в нем что-то аналогичное. Потому что C-x = действительно много раз выручал при поиске подобных ошибок. Хотя бы русский и английский символ c отличать, если в шрифте они одинаковые.

                                                                        +1
                                                                        > Жаль, давно перешел на vim, и до сих пор не знаю, есть ли в нем что-то аналогичное.

                                                                        ga
                                                                        0
                                                                        А Вы ещё не выработали привычку, встретив баг при обработке текстовой строки, переключать редактор в HEX-режим, чтобы посмотреть, что за х...hex-ня в строке?
                                                                        Анимешники не смотрят hex коды, анимешники просто читают заклинание
                                                                        grep --color='auto' -P -n "[^\x00-\x7F]" путь-к-файлу
                                                                          0

                                                                          А я просто открываю FAR, там это всё из коробки (и отображение кодов, и подсветка отсутствующих в текущей кодировке символов)

                                                                            0
                                                                            Лёгким движением руки пример выше можно заставить искать по всему проекту/нескольким файлам. FAR сможет сразу же показать эти символы, без прокручивания, или же сразу для нескольких файлов?
                                                                              0

                                                                              Пишете макрос, и будет вам ЩАСТЬЕ.

                                                                    0
                                                                    и вот его и надо патчить так, чтобы понимал, скажем, комменты на французском

                                                                    И эмодзи!
                                                                    +1
                                                                    всё же придерживаюсь мнения, что комментарий должен быть минималистичным, строго по сути и со ссылкой на соответствующий таск в трекере, где уже, по желанию, проблема и пути решения могут быть изложены высокохудожественным языком, с долей «человечности» и без ограничений по количеству символов.
                                                                    На ревью порой проще открыть таск и почитать, в чём была проблема, и потом воочию глянуть, как она была решена. А вот как раз имя таска в трекере должно отражать суть проблемы максимально точно.
                                                                      +3
                                                                      ИМХО лучше такие лонг-риды писать в PR description чем в коммит мессаг, а в коммит мессаге оставлять просто краткое описание и обязательно ссылку на issue (по которой можно будет найти впоследствии PR). Коммит мессаг в разы тяжелее ревьювить и править ремарками чем PR description.
                                                                        0

                                                                        Я сначала описываю изменения в комментариях к коммитам, потом из этих комментариев собирается описание пулл-реквеста, и в момент мерджа пулл-реквеста есть возможность дополнить и исправить комментарий, если во время обсуждения изменений появилась новая информация.

                                                                          +2

                                                                          Не все разработчики работают исключительно с GitHub. Даже open source проекты нередко используют его лишь как зеркало, а главные репозитории хранят у себя под замком. PR и issue — это внешние сущности по отношению к git. И в этом смысле они не сильно отличаются от внешнего баг-трекера.


                                                                          Ну и, опять же, удобство — это дело субъективное. Мне, например, часто удобнее смотреть код на своей локальной машине, а не через веб. Когда открываешь дифф, например, через git show <hash> | vim -, открываются приятные возможности. Например, большие коммиты можно смотреть по частям и удалять просмотренное. Или открывать в двух окнах редактора дифф и актуальную версию файла, чтобы они были рядом. Или прямо из диффа запускать поиск по Ctrl+]. Куча вариантов, в общем

                                                                            +1
                                                                            Ну и, опять же, удобство — это дело субъективное.

                                                                            Дело не в удобстве, дело в организации процесса. Польза от таких лонг ридов в первую очередь проявляется тогда, когда они ревьювятся вместе с кодом (иначе нет никакой гарантии что этому полотну текста вообще можно верить). Польза на ревью от этого двойная — во первых, ревьюерам не приходится гадать что означает та или иная ревью-дельта, вместо этого они сразу могут начать с чтения такой вот "документации", где оригинатор им все разъясняет, а потом сверять "что написано в доках" с тем "что написано в коде". Это резко увеличивает скорость и качество ревью. Во вторых, ревьюеры могут давать ремарки на "документацию", если им в ней что-то неясно. На выходе получается не просто проревьювленный код, а проревьювленный и полностью задокументированный солюшен.


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

                                                                            0
                                                                            Полностью поддерживаю. В комментарии ценна только первая строка — она видна в логе, остальное — шум.
                                                                            Да и все равно потом будет squash and merge (в нашей команде) и в коммите останется только ссылка на PR и его title.
                                                                              0
                                                                              У парня отняли час жизни и он решил отыграться на тех, кто будет читать этот коммит.
                                                                              +4
                                                                              Он был зафиксирован в одном из открытых репозиториев Government Digital Service — службы, занимающейся развитием цифровых услуг в Великобритании и поддерживающей проект GOV.UK
                                                                              Очень круто, кстати, что часть «государственного кода» выкладывается в опенсурс, причем не под какой-нибудь непонятной драконовской лицензией, а под простой MIT License.
                                                                                +6
                                                                                «За счёт людей (налогоплательщиков) и для людей».
                                                                                Конституционная монархия с Палатой Лордов часто оказывается более народной чем иные «демократии».
                                                                                +1
                                                                                Мы на внутреннем проекте пробуем использовать для таких описаний git notes
                                                                                  0

                                                                                  Представляю коллегу автора, которому нужно ревьювить по 20 коммитов в день.
                                                                                  Рассказ полезный, но место ему действительно в knowledge base и stack overflow.
                                                                                  Вряд ли кто будет искать текст ошибки в гитлоге, или посмотрит историю правок конфига столкнувшись с подобной ошибкой, и тем более вряд ли тут оно поможет поправить парсер.
                                                                                  Если же это было где-то опубликовано, стоит приложить ссылку — там могли откомментить люди с альтернативной точкой зрения или столкнувшиеся с похожей, но другой проблемой. Откомментить же этот опус по существу негде.

                                                                                    0
                                                                                    Попробуйте Conventional Commits. Писать в инфинитиве, без заглавных букв и точек.
                                                                                      0
                                                                                      Точки-то с заглавными буквами чем помешали? Да у них самих в примере «Commit message with both ! and BREAKING CHANGE footer» стоит точка в конце, настолько это бессмысленное требование.
                                                                                        0
                                                                                        В русской версии документации нет точки в строке с BREAKING CHANGE
                                                                                        Я сам сначала скептически отнесся к такому подходу, но когда попробовал разные варианты, нашел для себя эти требования удобными. Заглавные буквы и точки создают визуальный шум, например, при работе с GIT в IDE. Понятно, что это правило нельзя буквально распространять на всё, например, на имена классов.
                                                                                          0

                                                                                          Это как coding style: можно взять за основу то, что нравится и поменять то, то не нравится, и описать свой вариант.


                                                                                          Идея с префиксами мне нравится.

                                                                                            0
                                                                                            Идея с префиксами, как минимум, позволяет сократить длину заголовка без ущерба для понимания. Достаточно написать подряд десятка полтора коммитов в таком стиле, чтобы понять, что это еще и красиво.
                                                                                              0

                                                                                              Непонятно только, почему feat и fix — это префиксы коммитов, а не веток. Мой подход: делать бранчи в виде


                                                                                              feat/<scope>/<feature-name>-#<task-id>,
                                                                                              fix/<scope>/<issue-name>-#<issue-id>,


                                                                                              а в коммитах писать по образцу:


                                                                                              [+-*!] <project scope>: <why the change was made> [<task-or-issue-id>],


                                                                                              где [+-*!] — это метки о добавлении/удалении/изменении/важном изменении, <project scope> — какая часть проекта затронута.


                                                                                              Примеры веток:
                                                                                              fix/installation/windows-installer-#12345
                                                                                              feat/authentication/federated-auth-#54321


                                                                                              Примеры коммитов:
                                                                                              + Installer: components A was missing in Windows installation
                                                                                              - Installer: component Z is obsolete
                                                                                              * Authentication: user name format now conforms specs (#98765)

                                                                                                0
                                                                                                где [+-*!] — это метки о добавлении/удалении/изменении/важном изменении

                                                                                                Ну так это и есть ваш аналог префиксов feat, fix на коммитах

                                                                                                  0

                                                                                                  Нет, эти метки не говорят о том, фикс это или фича. Это лишь некое поверхностное (и опциональное) обобщение того, что человек увидет в diff-ах: было ли что-то добавлено, убрано или изменено. Фикс/фича — это сущности более высокого уровня, для них в идеале должен быть заведён тикет/таск, он может включать множество коммитов добавляющих/удаляющих/изменяющих код, и в идеале это должно происходить в отдельной ветке.

                                                                                                    0

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


                                                                                                    Поэтому префикс коммита сообщает разработчикам дополнительную информацию об изменениях. Вот, например, ваш коммит из примера:


                                                                                                     + Installer: components A was missing in Windows installation

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


                                                                                                    Другой коммит


                                                                                                     - Installer: component Z is obsolete

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

                                                                                                      0

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


                                                                                                      возможно, было бы правильнее объединить эти коммиты: так мы показываем, что они имеют отношение друг к другу

                                                                                                      Для логического объединения коммитов и предотвращения замусоривания бранчи и сделаны: называем ветку "fix/something", делаем в ней все нужные коммиты, потом сливаем рабочую ветку с мастер-веткой, и там будет коммит "Merged fix/something", по которому понятно, что произошло. Далее, хочешь — смотри только мастер, где "один коммит — один фикс/фича", без замусоривания, а хочешь лезь в ветку и смотри, какие конкретно шаги были сделаны, чтобы имплементировать этот фикс или фичу.


                                                                                                      Ну в принципе можно этот мердж-коммит описать по принципам Conventional Commits, а ветку удалить или схлопнуть до одного коммита, но мы обычно сохраняем их, потому что бывает полезно восстановить по коммитам ход мысли и работы.

                                                                                                        0
                                                                                                        потом сливаем рабочую ветку с мастер-веткой, и там будет коммит "Merged fix/something"

                                                                                                        Только, если включён режим no-ff

                                                                                        +1

                                                                                        Это не очень хороший коммит, включаю режим "разрешите докопаться" :)


                                                                                        внедрил несколько тестов

                                                                                        Каких? Почему бы не упомянуть здесь же хеши коммитов? А вдруг не в порядке именно тест — как мне в этом убедиться?


                                                                                        несколько тестов в ветку feature… Они хорошо работали… но при запуске… завершался с ошибкой

                                                                                        Т.е. в нашей идеальной сферической истории появился коммит, в котором сломался билд (добавлен неработающий тест). Появилось место, где git bisect будет спотыкаться, тесты падать. Фикс болтается отдельно. Отсюда вопрос: если так получилось потому что сломанный feature уже смерджили и squash' ить было поздно — то как-то? Если ещё не смерджили, то почему фикс не закоммитили вместе со сломанным тестом?

                                                                                          0
                                                                                          Целый час моей жизни не вернуть...

                                                                                          Всё оплачено работодателем.

                                                                                          Only users with full accounts can post comments. Log in, please.