Мы все были там: Вы работали над множеством изменений одновременно, некоторые из которых не имели ничего общего. Для удобства вы решили объединить все эти изменения в один коммит и на этом закончить. Но хотя это может показаться заманчивым, на самом деле это может привести к большим проблемам в дальнейшем. Большие коммиты могут:

  1. Затушевать источник ошибок или регрессий в будущем.

  2. Затруднить возврат нежелательных изменений без возврата желательных.

  3. Делать большие тикеты более перегруженными и сложными в управлении.

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

Оглавление

  • Атомарные коммиты и принцип единственной ответственности

  • Нет такого понятия, как слишком много коммитов

    • Сжимать или не сжимать?

  • Преимущества написания атомарных коммитов в Git

    1. Атомарные коммиты облегчают отслеживание регрессий

    2. Атомарные коммиты легче возвращать (revert), сбрасывать (drop) и исправлять (amend)

    3. Атомарные коммиты облегчают выполнение больших задач

  • Рекомендации по написанию чистых, атомарных коммитов

  • Крошечные изменения - большие победы

Атомарные коммиты и принцип единственной ответственности

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

Мы можем легко распространить этот принцип на Git, отдавая предпочтение атомарным коммитам, которые отвечают за документирование одной, полной единицы работы. Это не значит, что каждый коммит должен быть ограничен одним файлом или несколькими строками кода (но если это так, то пусть будет так). Скорее, это означает, что вы должны быть в состоянии описать свои изменения одним осмысленным сообщением, не пытаясь присовокупить к нему дополнительную информацию о какой-то несвязанной работе, которую вы сделали. Другой способ определить атомарный коммит - это коммит, который может быть отменён без каких-либо нежелательных побочных эффектов или регрессий, помимо тех, что вы ожидаете, основываясь на его сообщении. Если коммит удаляется из истории коммитов Git, но при этом удаляются другие легитимные изменения, значит, этот коммит не был атомарным.

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

Не существует такого понятия, как слишком много коммитов

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

Чтобы дать вам представление, вот краткий обзор количества коммитов для некоторых из самых популярных репозиториев всех времен на GitHub (цифры приведены на момент написания статьи и к тому времени, когда вы будете это читать, они будут гораздо выше):

  • Visual Studio Code: 82k

  • tensorflow: 110k

  • kubernetes: 100k

  • rust: 140k

  • Node.js: 33k

  • TypeScript: 32k

Вы поняли суть.

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

Сжимать или не сжимать?

В качестве компромисса некоторые команды следуют рабочему процессу squash-and-rebase, когда разработчики могут создавать любое количество коммитов в своей ветке, но перед слиянием пул-реквеста с целевой веткой эти коммиты объединяются в один с помощью процедуры git rebase --interactive.

Хотя это и делает вашу историю коммитов более компактной, я обнаружил, что такой рабочий процесс на самом деле вредит цели использования атомарных коммитов в первую очередь. Конечно, расширенное описание коммита в Git все еще будет содержать отдельные сообщения от всех сжатых коммитов, но эти коммиты больше похожи на артефакты - они не являются действительными ссылками в истории Git, если вы не восстановите их с помощью вашего локального git reflog. Другие разработчики не смогут откатить или переместиться во времени к этим коммитам в истории.

Обратите внимание, что сжатие (squash) имеет смысл, если некоторые из ваших промежуточных коммитов были сделаны случайно и на самом деле должны были быть частью другого коммита. В этом случае не имеет смысла оставлять эти коммиты отдельно. Вы также можете использовать сжатие для очистки шумных или бессмысленных коммитов, например, если вы пытаетесь запустить CI-пайплайн повторно (но лучше всего исправить последний коммит и принудительно отправить его в вашу ветку, а не делать коммиты вроде "test" или "y u no work").

Преимущества написания атомарных коммитов в Git

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

1. Атомарные коммиты облегчают отслеживание регрессий

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

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

Если вы сделаете атомарные коммиты и запустите git bisect, а Git сможет определить коммит-нарушитель, вы будете более уверены, что изменения в этом коммите действительно привели к появлению ошибки и что они не затронули другие области кода. Это может значительно сузить круг файлов, которые вам теперь придется изучать более тщательно, чтобы понять, что пошло не так. Более того, возможно, вам удастся обойтись только отменой этого коммита.

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

2. Атомарные коммиты легче возвращать (revert), сбрасывать (drop) и исправлять (amend)

Допустим, вы работаете над большой функцией. В ней много подвижных частей, и вам даже может понадобиться рефакторинг старого кода, чтобы приспособить его к новым изменениям. Когда вы наконец размещаете PR, некоторые рецензенты не согласны с некоторыми внесенными вами изменениями и просят отменить их. Звучит достаточно просто, верно?

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

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

Если бы вы вместо этого использовали атомарные коммиты для всей своей работы, вы смогли бы вернуть (или даже отбросить) несколько коммитов, связанных с запросами на изменения, и все было бы готово в течение нескольких минут. Pre-request review, и всё готово.

Однако это справедливо не только для запросов на изменения - пока вы работаете над тикетом, вы можете понять, что ваш текущий подход не идеален, и вам может понадобиться вернуться назад. Но если у вас в Git есть куча нефиксированных изменений - с несколькими пересекающимися проблемами и несколькими разными изменениями в одном файле, некоторые из которых нужны, а другие должны быть отброшены, - вам придется отменять свою работу вручную. Но если бы вы писали атомарные коммиты, вы могли бы отменить те, которые внесли изменения, и все (или, что еще лучше, выполнить rebase и полностью отказаться от этих коммитов).

3. Атомарные коммиты облегчают выполнение больших задач

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

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

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

Исходя из этого, мы видим, что атомарные фиксации имеют два преимущества:

  1. Они минимизируют когнитивную нагрузку при работе над большими тикетами.

  2. Они облегчают отслеживание и документирование вашего прогресса.

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

Рекомендации по написанию чистых, атомарных коммитов

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

  • Выберите время и придерживайтесь его. Я предпочитаю начинать с глагола в настоящем времени (например, Fix X).

  • Упомяните компонент, функцию или область кода, которая была изменена.

  • Упомяните ошибку, если таковая имеется, которую устраняет ваш коммит. Бонус: упомяните коммит с ошибкой.

  • Если возможно, укажите в сообщении о фиксации проблему, над которой вы работаете (например, This is a commit message (#1234)). Это создаст ссылку на проблему #1234 на GitHub, что облегчит другим разработчикам отслеживание тикетов и PR в будущем.

Пример из репозитория TypeScript, как этот последний совет может выглядеть на практике:

В некоторых коммитах упоминаются проблемы, на которые автоматически ставится гиперссылка.
В некоторых коммитах упоминаются проблемы, на которые автоматически ставится гиперссылка.

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

Крошечные изменения - большие победы

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

Комментарии (40)


  1. Konard
    19.12.2023 23:30

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

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

    А ещё это помогает в геймификации процесс программирования. К примеру я играю сам с собой в игру, мол, чем больше у меня зелёных квадратиков на GitHub и чем они зеленее, тем лучше. Лучшая стратегия победы в такой игре это делать каждый день минимум один коммит, и тогда ты точно побеждаешь, но вот реальность показывает что это делать не просто. И развивать самодисциплину - то ещё испытание. Но чем меньше коммиты тем проще это делать, тем проще себя мотивировать и проще получать удовольствие от того что коммиты сделаны :) А после этого хочется делать ещё коммитов и ещё :)

    А ещё это помогает следовать принципу атомарной ответственности в задачах, если привязывать каждый коммит к конкретной задаче (issue), никогда нельзя будет сделать так, чтобы в нём содержался код связанный с несколькими задачами, это тоже дополнительно дисциплинирует и делает процесс разработки максимально прозрачным. То есть можно будет потом сделать roadmap/project, из которого можно перейти на конкретные issues, а оттуда на конкретные коммиты которые делались в рамках этой задачи.


    1. comerc Автор
      19.12.2023 23:30

      Хе-хе. Я тоже играю в эту игру. Дофаминовый майнинг.


      1. Konard
        19.12.2023 23:30

        Тогда вот, хвастаюсь своими достижениями :)

        P.S.
        В моём первом комментарии опечатка: "коммент" "коммит"


        1. comerc Автор
          19.12.2023 23:30

          Круто, да. Но мой кумир - Андрей Ситник.


  1. teror4uks
    19.12.2023 23:30

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


    1. comerc Автор
      19.12.2023 23:30

      Так squash убивает машину времени. Меня, как археолога, это обламывает.


      1. nronnie
        19.12.2023 23:30

        На самом деле все прежние коммиты в git остаются - просто их так легко через git log <ref> не увидеть, но при желании отыскать их обратно несложно.


        1. Mingun
          19.12.2023 23:30

          Так ведь это до git gc, после чего уже не факт, что они останутся.


          1. aamonster
            19.12.2023 23:30

            Если оставлять именованные ветки – то останутся. Чисто для археологов.


            1. Mingun
              19.12.2023 23:30

              Если оставлять именованные ветки, то в чем смысл их сквашить в вливать одним коммитом? Зачем на ровном месте делать проблемы?


      1. nighthtr
        19.12.2023 23:30

        А я считаю нужно законодательно запретить плодить коммиты на каждое телодвижение и 100500 фиксов во время ревью/тестирования. Потом черт ногу сломит найти в истории что с чем связано.


        1. aamonster
          19.12.2023 23:30

          Запретите fast-forward merge в мастер или куда вы там вливаете изменения – и будет вам счастье: всегда достаточно посмотреть ровно один коммит с мёржем.


  1. volas
    19.12.2023 23:30

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

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

    Но может зависеть от репозитория, с которым вы работаете.


    1. Sazonov
      19.12.2023 23:30

      Сквош можно делать после ревью. Понятное дело, что сквош-ребейз-форспуш возможны только вместе, но тут уже зависит от нужной степени педантичности на проекте. Я когда-то на аутсорсе приложил руку к одному гугловому проекту и мне очень понравился подход одна фича - один коммит. Крайне удобно при нормальном CD делать автоматический changelog. Ну и при использовании blame сразу понятно, откуда растут ноги у кода.


      1. Mingun
        19.12.2023 23:30

        Вместо автоматического changelog-а лучше бы просто с каждым PR в него добавлять нужный текст, над которым гораздо больше контроля. И вы во фразе "одна фича - один коммит" пропустили слово merge :) "Одна фича - один merge-коммит".

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


        1. Sazonov
          19.12.2023 23:30

          Мерж коммиты не нужны. Fast forward справится после ребейза.

          Текст в changelog писать вручную, который будет дублировать историю в гите? Зачем? А если реверт или черри пик? А когда больше 1 человека будет править текстовый файл с историей - привет постоянные мерж конфликты? Не нужно усложнять :)


          1. Mingun
            19.12.2023 23:30

            С fast-forward после ребейза вы теряете информацию о том, какие коммиты к каким задачам относятся. Мердж-коммит как раз и содержит ссылку на задачу в трекере.

            Текст в changelog писать вручную, который будет дублировать историю в гите?

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

            А когда больше 1 человека будет править текстовый файл с историей - привет постоянные мерж конфликты?

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

            • Реализована фича X

            • ...

            • Revert "Реализована фича X"

            • ...

            • Опять реализована фича X, но без Y

            • ...

            • Исправление к реализации фичи X, добавили Z

            И как из этого понять, реализована фича X или нет?


            1. Sazonov
              19.12.2023 23:30

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

              При ребейзе у вас будут конфликты в ченджлоге, которые вы будете решать на каждый коммит.

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


  1. Fodin
    19.12.2023 23:30

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


    1. Mingun
      19.12.2023 23:30

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

      Поддержание собираемости -- это не оверхед, а инвестиции в будущее на упрощение разбора возможных неочевидных регрессий из-за ваших изменений.


  1. PuerteMuerte
    19.12.2023 23:30

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


    1. fshp
      19.12.2023 23:30

      Атомарный коммит ценен сам по себе.

      Проект на этой версии собирается, работает, тесты проходит.

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

      Но повторюсь, коммит должен быть рабочим. Иначе это херня на палочке.


      1. PuerteMuerte
        19.12.2023 23:30

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

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


        1. fshp
          19.12.2023 23:30

          Для меня атомарные коммиты ценны в первую очередь во время ревью. Это как аксиомы или теоремы, при доказательстве которых можно опираться на предыдущие.

          Можно сделать ревью одного коммита, в котором будет какой-то rest-клиент с кучкой бойлерплейта, json-кодеками, тестами и т.п.

          Это кстати может быть не обязательно один коммит. Например реализовано 3 метода. На каждый свой коммит. Это ещё лучше.

          И при ревью бизнес-логики уже не думать о клиенте. Я это смотрел там все хорошо. Или за меня кто-то уже посмотрел и там все хорошо.

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

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

          Другим разработчикам совсем не интересен полет вашей мысли. При ревью им не важно как вы к этому пришли, важен конечный результат. Так перепишите историю через rebase, разбив задачку на какие-то логические шаги. Универсального рецепта никто вам не даст.


          1. PuerteMuerte
            19.12.2023 23:30

            Для меня атомарные коммиты ценны в первую очередь во время ревью.

            А разве вы их детализируете во время ревью? Ревью ведь обычно делается уже по финальному результату, где все коммиты собраны в один pr, который знаменует собой какую-то стадию готовности


            1. fshp
              19.12.2023 23:30

              Я как и любой человек ленюсь и не всегда делаю МР как хотелось бы. Но если делаю, то предупреждаю коллег, что лучше по коммитам смотреть. Гитлаб не очень для этого приспособлен, но терпимо. Gerrit, например, как раз ориентирован на ревью коммитов.

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


          1. house2008
            19.12.2023 23:30

            Это как аксиомы или теоремы, при доказательстве которых можно опираться на предыдущие.

            По вашей логике аксиомы и теоремы были доказаны без предварительных ошибочных вычислений/мыслей ... то есть Пифагор такой сел за вечер и написал аксиому, я думаю он сначала сделал сотни ошибочных вычислений/набросков (в нашей терминологии коммиты) прежде чем получил верный результат (в нашей терминологии сложилась картина всей фичи + доехало финальное ТЗ). Я всегда раньше старался обновлять коммиты через амменд, потом форс пуш, но забил, ибо всё равно финальный МР показывает всё в одной куче и потом при мерже всё засквошится.

            Ваша мысль понятна на самом деле, просто это очень сложно соблюдать, банально код не собирается в вечер пятницы и такой полурабочий код пушишь в ремот на случай если винт отъедет на выходных, чтобы был бэкап на сервере, а в понедельник уже лень аммендить/форспушить/берейзить ))


            1. fshp
              19.12.2023 23:30

              По вашей логике аксиомы и теоремы были доказаны без предварительных ошибочных вычислений/мыслей

              А вы изучали только доказательство теоремы Пифагора или же еще все неудачные попытки ее доказать?


            1. inkelyad
              19.12.2023 23:30

              и такой полурабочий код пушишь в ремот на случай если винт отъедет на выходных, чтобы был бэкап на сервере, а в понедельник уже лень аммендить/форспушить/берейзить ))

              А вот это недостаток распространившейся модели использования git, которая стала чрезмерно централизованной. Кто мешает иметь 'чистовой' репозитарий + по репозитарию на каждого разработчика, куда он и будет пушать для бакапных целей? Ну или хотя бы просто еще один 'черновой'?

              И да, потому merge request слать так, как оно и задумывалось - из своего репозитария в репозитарий инженера по сборке и тестирования, чтобы он все это у себя собрал, протестировал и только после этого влил в 'чистовой'.
              Заодно 'чистовой' не будет засоряться всякими левыми ветками.


              1. house2008
                19.12.2023 23:30

                Первый раз такое вижу в рамках одного проекта внутри компании, а где такое практикуется если не секрет, чтобы на проекте у каждого разработчика были копии репозитория с которыми они работают и через него делают МР в основной репо ? Сам так делал только с публичными чужими проектами через форк, потом в нем фикс/фича и с него делал МР в основной репозиторий, но это скорее исключение из правил.


                1. inkelyad
                  19.12.2023 23:30

                  Я тоже не видел. Хотя оно часть описываемых проблем с замусориванием репы вполне бы решило.


  1. i360u
    19.12.2023 23:30

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


  1. KReal
    19.12.2023 23:30

    Имхо, здесь принцип common sense: скажем, 100500 файлов в одном коммите это беда. Но и 9000 коммитов это тоже беда. Благо есть каждодневные скрамы, до чего-то да можно договориться)


  1. house2008
    19.12.2023 23:30

    Тоже не совсем согласен. У нас подход атомарная фича ветка, если что-то пошло не так, то ее можно откатить. А коммиты в фиче ветке идут хаотично, потому что ТЗ меняется + QA может найти баги, но во время принятия МР/ПР в основную ветку это всё сквошится (квасится) средствами CI. Если что-то нужно добавить в фиче ветку не относящееся к ней, то заводится отдельный тикет-ветка и через основную подливается через мерж/рэбейз (кому как удобно).


    1. nronnie
      19.12.2023 23:30

      У нас подход атомарная фича ветка

      Неужели кто-то еще по-другому работает? Тут проблема часто в другом. Процесс написания кода для отдельной feature редко когда линейный. Какой-то отдельный кусок кода может переписываться несколько раз, или добавляться, а потом удаляться - и отправлять в PR всё это отдельными "атомарными" коммитами это как-то нехорошо (кому охота на ревью разбираться в этих твоих душевных метаниях , что были пока ты код писал). Но при этом еще часто в ветке есть коммиты которые к самой фиче не относятся (самый простой пример это форматирование уже имеющегося кода) и они идут вперемешку с "feature" коммитами. Поэтому простой squash ветки перед PR тоже, получается, идея не очень хорошая. Единственный вариант, который приходит на ум это делать еще одну вспомогательную ветку, потом накатывать в неё cherry-pick из рабочей feature-ветки так чтобы коммиты оказались логически упорядочены, а потом делать отдельные squash-и для отдельных, логически связанных цепочек коммитов. Но это может быть достаточно трудоёмкий процесс.

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


  1. skovoroad
    19.12.2023 23:30

    проекты разные, и нет единого понимания атомарности, и поэтому нет лучшего или худшего подхода

    1. Размер проекта

    2. Скорость разработки

    3. Сложность изменений

    4. Количество разработчиков и команд

    5. Распределение ответственности между ними

    6. Особенности тестирования

    7. И прочее


  1. Sap_ru
    19.12.2023 23:30

    Все круто, но рефакторинг. Переименование метода. Изменение сигнатуры функции. Разбиение класса на несколько или объединение классов. Изменение структуры исходного когда. Создание финики или наоборот избавление от неё. Изменение структуры наследования сложных объектов. Это всё атомарно? Ха! А отменить такое можно? А перенести такое изменение в другое место истории? А если рефакторинг делается периодически?


    1. comerc Автор
      19.12.2023 23:30

      В режиме "ковровое бомбометание" спасает "trunk based development".


      1. Sap_ru
        19.12.2023 23:30

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


  1. botyaslonim
    19.12.2023 23:30

    Без squash история проекта превращается в изрядную помойку. Когда у тебя на работе 25 микросервисов, можно просто утонуть в этих ваших "атомарных коммитах". Атомарной, то есть вполне понятной и завершённой, должна быть задача. И принцип "одна задача - один коммит в master/develop"