а как в fossil при сохранении всей последовательной истории изменений разруливается ситуация с поломанным проектом между коммитами?
т.е. вот тот workflow что описал @angly мне как раз понятен, локально я могу сколько угодно и совершенно любых изменений делать, потом разбивать на логические коммиты и уже эту историю пушить в удаленный репозиторий. если требуется - засквошить всё что отдал другой разработчик и переразбить так, чтобы ни один коммит не ломал сборку.
а как это работает в fossil?
1) там принято test before commit как подход 2) а откуда вообще взялось требование "чтобы ни один коммит не ломал сборку" ? если я коммичу в свой локальный бранч, кому какое дело, что в этом бранче не из каждого коммита собирается? Еще в юности, когда я читал статью http://www.linuxlib.ru/prog/cvs/cvs.htm про системы управления версиями, мне очень понравилось в ней место: Старайтесь не фиксировать несколько ошибок одновременно (еще хуже -- в качестве журнального сообщения писать "Исправлено несколько ошибок" или "Куча исправлений"). В то же самое время есть еще одна часто встречающаяся ситуация: предположим, что вы несколько часов писали новый довольно большой модуль, он в основном работает, и осталось внести буквально несколько изменений (или, например, уже поздно и пора идти домой). В этом случае можно смело фиксировать недоделанный файл, а в качестве комментария ставить "почти работает". Оставшиеся доделки чрезвычайно удобно будет внести уже в новую ревизию, используя команду просмотра изменений относительно "почти работающей версии". По крайней мере, к ней всегда можно будет вернуться.
> если я коммичу в свой локальный бранч, кому какое дело, что в этом бранче не из каждого коммита собирается есть разные варианты организации истории. когда в истории есть merge commit - в принципе понятно где произошло слияние основной и "локальной" ветки (мы же не переписываем историю, в т.ч. локальную, верно? значит локальная ветка = ветка фичи, которая будет вмержена). это простой и понятный для многих вариант организации истории, при котором перед мержем всегда можно прогнать тесты и если что-то не работает - добавить еще один коммит с правками. но честно говоря с таким вариантом организации истории я иногда такие "рельсы" видел, что ни в одном железнодорожном депо не встречаются. даже в transport tycoon / openttd если же merge commit не используются (ff-only) - у нас любой коммит попадает в единую плоскую историю. и этот любой коммит может дальше стать точкой старта новой фичеветки, а баг может быть размазан по любому количеству коммитов. поэтому в случае плоской истории часто сквошат все промежуточные коммиты при мерже, что тоже не всегда удобно. вот где-то на пересечении этих двух подходов оно и появилось. на хабре еще ветка про rebase неплохая, не напрямую про это "требование", но про плоскую историю ну и как минимум стоит прочитать мысли Линуса на тему чистой истории (ссылка оттуда же)
а на тему принятого подхода "test before commit" - это утопия. автотесты-то (юниты, даже не e2e) не всегда / не на всё (своевременно) пишутся / правятся / запускаются (пока на CI принудительно прогон не настроен, но это уже не before commit), а если говорим про ручное тестирование - вообще всё выглядит как неконтролируемая и ненадежная конструкция. при таком сценарии человеческий фактор нужно дополнительно учитывать, когда и что сломается - неизвестно, но то что оно хоть раз сломается - факт.
> 2) а откуда вообще взялось требование "чтобы ни один коммит не ломал сборку" ? Это не требование, а хорошая практика. Вместо с атомарностью коммитов и плоской/полуплоской историей в случае регрессий позволяет делать быстрый и точный бисект (git bisect).
> В то же самое время есть еще одна часто встречающаяся ситуация: предположим, что вы несколько часов писали новый довольно большой модуль, он в основном работает, и осталось внести буквально несколько изменений (или, например, уже поздно и пора идти домой). В этом случае можно смело фиксировать недоделанный файл, а в качестве комментария ставить "почти работает". Оставшиеся доделки чрезвычайно удобно будет внести уже в новую ревизию, используя команду просмотра изменений относительно "почти работающей версии". По крайней мере, к ней всегда можно будет вернуться. Выглядит как плохая практика. Если есть требование в конце рабочего дня коммитить в удаленный репо свою работу (зачем, интересно), то я бы создал коммит с коммит-месседжем wip, потом бы доработал и сделал аменд с нормальным коммит-месседжем и форспушнул в свою фичеветку (которая только моя). Вижу небольшие плюсы сохранения истории в случае "сначала было сделано кое-как, а потом дочинили", но вижу и сильные минусы этого. Минусы: 1) в историю попадает мусор. Например, человек сделал фичу, а потом решил ее тут же полностью переписать. Первый вариант — мусор, не несущий пользы, занимающий место в репе, делающий косяки разраба видными всем имеющим доступ к репе, не позволяющий научиться из этих коммитов хорошему. 2) и что хуже — блейм (git blame) покажет, что какой-то код был внесен в коммите с названием типа wip (это случается куда чаще, чем вы думаете). В реальной работе я пришел на проект и хочу выяснить, в какой момент в проект была добавлена та или иная технология, подход или библиотека, а выхожу на коммит с многотысячным диффом и ничего не значащим коммит-месседжем, где было переписано полпроекта. А если бы автор потратил силы и разбил бы эту громадину на мелкие логически цельные коммиты , то будущим мейнтейнерам было бы проще разбираться в прошлом. Из плюсов: 1) уйдет меньше сил. 2) можно коммитить не напрягая мозг. В больших длительных проектах минусы значительно перевешивают плюсы, по моему опыту.
https://stackoverflow.com/questions/14023648/why-does-my-git-history-look-like-a-christmas-tree
Прочел мысли Линуса. Примерно так мы и делаем, но на уровне джентльменских соглашений договорились, что фичеветки, даже пушнутые, — это собственность автора, если он явно не дал разрешение другим людям что-нибудь с ней делать. Такой подход позволяет даже после исправлений на стадии кодревью держать историю в чистоте. Но это требует знаний и дополнительных усилий, опять же. Компромиссный вариант — сквош перед мержем. Но я предпочитаю не сквошить, потому что я могу :)
Человеческий фактор обычно стараются как раз везде исключать. Даже если это займет усилия. Добавление человеческого фактора в процесс, где его можно было избежать, — сомнительное решение. Разве что если его исключение стоило бы ОГРОМНЫХ трудозатрат
как будто кто-то запрещает делать bisect по основной ветке
Странные эти люди с "зачем в конце дня". Я однажды вот таким образом потерял неделю работы - винт сгорел. Собственно, одно это уже перевешивает все минусы. Работа системы контроля версий заключается в том, чтобы, собственно, хранить код и его историю, а не диктовать человеку, как именно вокруг неё поплясать с бубном. И соответственно она должна хранить код и его историю, а не всячески пытаться избегать этого процесса. Тем более, "минусы" опять перечислены исходя из странного предположения, что история полностью плоская без веток, а-ля общий ствол в svn (работал я в одной такой конторе с svn, гы), тогда как в большинстве нормальных контор (или проектов с pull request на гитхабе) принята та или иная вариация git flow.
напомнило цирк в https://github.com/dtschump/CImg/issues/316
Опять подменили тезис и боретесь с ним. Со сломанными коммитами бисект будет сложнее, а со сквошем будет менее точным. Мне проще, если в коммите с регрессией дифф на полсотни строк, а не на несколько сотен/тысяч. А вам?
Там не было такого предложения, опять вы перевираете :) А в случае потери недельной работы проблема в вашем неоптимальном воркфлоу, где фича делалась как минимум целую неделю. Без должной культуры это и приводит к подобным проблемам. Мы сейчас декомпозируем таски, разбивая их на итерации и/или параллельные кусочки, чтоб и избежать таких ситуаций, и чтоб ревью шло проще. А вы одним костылем затыкаете другой костыль, искренне считая при этом, что вы д'Артаньян.
Обсуждают сегодня