Максимальный приоритет техдолга лично мне нравится, но это может работать в личных пет-проектах и частично в опенсорсе, а при реализации коммерческих проектов приоритеты обычно совсем на другом.
Поэтому должна быть не "максимальный приоритет", а "гарантированная полоса ресурсов". Даже 10% лучше, чем ничего. Иногда, конечно, нужно больше.
Если требуется коммерческое обоснование - тут уже зависит от рельефа местности, но аналогии с затратами на уборщиц и на страховые выплаты должны показать направление.
Если вы под "принадлежит ветке" понимаете "сохранил id ветки в момент коммита", то да, разница есть. В Git не используется никакого такого автомата, а если надо указать, в рамках какой разработки сделан коммит, то это пишется явно в его сообщении.
Но это специфически-меркуриаловское понимание понятия "принадлежность ветке". Для слабограмотных разработчиков и отсутствия адекватного слежения за расстановкой таких указаний, согласен, полезно заводить такой автомат, потому что он будет давать хоть какие-то данные о том, откуда и зачем этот коммит.
Процесс именно что усложнился. Сейчас мне проще с той же целью (чтобы что проверил – то и закоммитил) закоммитить во временную ветку, вернуться на рабочую и по частям переносить из временной, собирая отдельные коммиты.
Это удобный вариант, но совсем не обязательный. Я в большинстве случаев обхожусь без временной ветки.
я в те времена ставил TortoiseHg, там работа с shelve (продвинутый аналог git stash) очень удобная.
Если ограничивать себя тем же уровнем функциональности и набором возможных flow, то и в гите их точно так же не нужно. Но Git позволяет сильно больше и гибче с минимумом усилий.
Самое приятное, что можно слиться с любой веткой из любой другой.
Я однажды сделал merge с совершенно другой кодобазой, и это сработало. О чём это говорит, кроме того, что я ошибся? ;)
Более того, любой коммит - всегда тег, который принадлежит ветке. Это сильно облегчает задачу поиска изменений.
В Git коммит тоже принадлежит ветке и имеет свой id. Что не так?
есть удобный инструмент для переноса их туда-обратно, вплоть до отдельных строк
А до правок текста тех строк, что отправляются (например, убрать комментарий типа "а вот тут главное")? Ну и это отдельный инструмент, а в Git оно в коробке.
Но я согласен в том, что проверять надо по уровню отправляемого коммита. Можно остальное скинуть в stash, но я предпочитаю делать `git co HEAD~1` или аналог, а потом вернуться. Stash он один на рабочую копию, а не на ветку.
Потому что процесс, аналогичный привычному, резко усложнился.
Там нет усложнения, просто надо делать чуть иначе. Для построчного stash я не знаю, а вот `add -i` и `add -e` решают задачу. А "набрать в индекс" желательно, чтобы проверить, что же собрал... ну или последовательно amendʼом набирать правки.
И эти сущности не пропадают только от того, что кто-то решил почистить список указателей от неактуальных.
Именно что пропадают. Вмержили в транк - осталась только запись в сообщении коммита.
Терять информацию - это в основе всегда неправильный вариант.
Верно. Поэтому сообщение коммита начинаем с "MOO-1234: Fix moo frequency for most cow breeds". По этому "MOO-1234" выясняется и всё остальное. А как ветка была локально названа у конкретного коммиттера - уже неважно, да хоть "херня которая не даёт выспаться".
Повторюсь, я "за" сохранение метаинформации об изменениях, если коммиттер хочет этого и предоставляет её. Но при той юзербазе, что есть, отсутствие этой возможности означает минимальную потребность в ней. Какой-нибудь целевой плагин тут был бы, конечно, в тему.
Как вам а) убедиться, что этот фикс не вызывает новых проблем в других проектах;
Ну давайте смотреть на процесс. Вот есть изменение в libmoo. У нас монорепа на 200k продуктов. Нам надо отловить те, которые зависят от libmoo напрямую - это шаг 1. Как мы будем это искать? Наверняка есть какой-то список. Вести его в монорепе или в разбросе - нет разницы, всё равно добавлять вручную. (В автопоиск по всему дереву - не верю.)
CI автомат? Ему точно так же нужен явный список. А после этого вытаскивать отдельные подветки толстой репы (не тащить же её целиком!) или отдельные маленькие репы - разницы нет, или второе даже проще.
На любой такой коммит CI должен всё проверить.
Шаг 2 - проекты, связанные с зависящими (типа сетевого взаимодействия) - тем более тоже на основании явно описанных связей.
Так для чего мудохаться с моно?
(На самом деле есть одна тонкость с субмодулями: для некоторых ситуаций нужно хукать замену URL к модулям. Но это в тысячи раз проще поддержки монореп.)
б) доставить этот фикс на другие проекты (и не когда-нибудь, а поскорее).
О, вот тут действительно интересный вопрос. Если сводный коммит на библиотеку и все её зависимости, типа добавили один аргумент в функцию её API.
Но это само по себе проблемно. И коммит такой анализировать сложно, и грануляция страдает, и атомарность изменения как раз может быть субмодулями исключена, просто не потерять плавный переход на новую версию.
В Gerrit существует уже 10 лет, типа такого: https://gerrit-review.googlesource.com/c/plugins/scripts/+/411660 см. "relation chain" и номера patchsetʼов: после правки в предыдущем в цепочке следующие надо обновить или локально с пушем, или через средства сервера. В Мете изобрели велосипед.
А если использовать gui, то можно и отдельные diff'ы в отдельных файлах включать в коммит. И в git и в hg.
Вот.
1. В Git для этого не нужен какой-то отдельный GUI, всё из коробки.
2. Git позволяет это делать (без GUI, `add --e`) даже не с отдельными диффами, а со строками. Критично, когда в таком диффе на 2 строки изменения, которые должны пойти на сервер, 3 на отладочную печать и 4 на комментарий для себя, что тут происходит и почему.
Может, для мелких дежурных правок такое и не нужно, но для задачи типа моей текущей сейчас, где сплошное "сигнал пошёл через обсервер в состояние вложенной FSM", мои комментарии "какого хера? уточнить это место" не должны идти в коммит даже если они на хинди.
3. После я пересобираю правки и, например, переименования идут в один коммит, doxygen-пояснения - в другой (если их не было, потому что вот такая кодобаза), а функциональные правки - в третий. И только после этого я выставляю это в виде чистого, аккуратного результата, который легко ревьюить сейчас, читать даже через пару лет, прогонять через CI или bisect в любой момент.
А с Mercurial и его "вам это не нужно" в коммиты шли бы грязь, грязь и грязь из разнородных изменений и "я тут ещё одно место добавил и заодно функции описал".
В hg неудобно переписывать историю на сервере, да.
Польза от staging возникает задолго до пуша на сервер.
В гите есть только указатели на коммиты. А бранчи все выдумывают пре-коммит хуками кто во что горазд.
Вы тут "бранчами" называете теги сообщения коммита, которые показывают, в рамках какой разработки был сделан коммит. Ни в Git ни, на самом деле, в Hg это не нужно, если есть возможность писать его в сообщении коммита - что всегда и делается в процессе уровня больше чем "я и моя собака".
Как сами меркуриаловцы признают, "The term branch is sometimes used for slightly different concepts. This may be confusing for new users of Mercurial." В результате получаются ситуации типа "Две ветки-2 в пределах ветки-1 (не путать с веткой-3)" (ветка-1 это его внутренний branch, ветка-2 это безымянная голова, ветка-3 это bookmark).
Я уж не говорю о том, что он каждыйпо коммит хранит целым снепшотом состояния репозитория, а не просто диффом изменённых файлов
А это _в основе_ единственно правильный вариант (ну не учитываем, что объекты могут представляться в виде дельт, это уже вопрос сжатия репы). Трекинг копирования/переименования должен делаться уже отдельно поверх него.
Представление, где каждый каталог и файл представляются хэшом и собственно найти изменённые файлы между коммитами - это очень экономная операция (все случаи разных хэшей отбрасываются из сравнения), позволяет как раз очень экономно определять набор тех файлов, в пределах которых надо вести трекинг уже по их содержимому.
Для сложных случаев типа "переместили 200000 файлов и при этом изменением `#include <moo/foo/boo/boo.h>` на `#include <util/moo/foo/boo/boo.h>` поменяли их хэши... ну да, можно было бы придумать какие-то подпорки. Но, насколько видим, это даже для крупных реп не составляет большой проблемы.
а для отображения диффа и мёржа ему приходится опять же угадывать, где какие были изменения сравнивая разные снепшоты.
Ну и очень хорошо угадывает.
Опять же, да, я иногда (раз в два года) предпочёл бы видеть возможность явно ему сказать "считай, что Foo переименован в Boo, а историю Moo, сделанного клоном из него, надо вести отдельно". В целом, не настолько проблема.
Стиль Github, GitLab, Bitbucket - это "разрешим работать с распределённой VCS ко ак с централизованной". Это не родное для Git.
Более адекватное приспособление к стилю собственно Git это Gerrit. Он используется как серверная база в самом гугле (с сильными внутренними подточками). Но у него нету CI и прочих удобств в едином флаконе, их надо довинчивать.
1. staging area. В Mercurial ничего подобного нет и не планируют. А это (вместе с interactive rebase) практически единственное, что позволяет легко делать чистые коммиты, а не такие, в которых намешало 100500 разных типов правок.
Для меня любая VCS, в которой этого нет, непригодна.
2. Отсутствие зажима на определённые процессы разработки - который в Mercurial выглядит как множественные головы, тяжело изменяемый статус коммита вроде draft/public, и т.п.
Mercurial выглядит как "сэмулируем централизованную VCS на базе распределённой, но так, чтобы людям не надо было думать, что они делают".
Умеет. Вы, наверно, git clone запускали. Потому что если сделать init + fetch, то докачка работает с момента обрыва. Не идеально, некоторые мета-части передаются заново, но есть сохранение принятого.
Можно. Были даже примеры простых игр (уровня Pacman) как (U)EFI бинарей.
Проблема в том, что это отдельная платформа со своей спецификой, и что-то большое разрабатывать под неё тупо нет смысла. Вам придётся сделать свой R/W драйвер целевой FS, свою поддержку мультипроцессности в нужном стиле, достаточно богатое API для работы такого сервиса, сделать все нужные драйвера включая сетевой (EFI может его не предоставлять)... сама модель EFI ориентирована на простоту (ну, как её понимает Intel) и надёжность процесса, а не на скорость... с какого-то момента будет понятно, почему если "за морем телушка - полушка, да рубль перевоз", то грузить Linux с диска дешевле во всех смыслах:)
Поэтому должна быть не "максимальный приоритет", а "гарантированная полоса ресурсов". Даже 10% лучше, чем ничего. Иногда, конечно, нужно больше.
Если требуется коммерческое обоснование - тут уже зависит от рельефа местности, но аналогии с затратами на уборщиц и на страховые выплаты должны показать направление.
Если вы под "принадлежит ветке" понимаете "сохранил id ветки в момент коммита", то да, разница есть. В Git не используется никакого такого автомата, а если надо указать, в рамках какой разработки сделан коммит, то это пишется явно в его сообщении.
Но это специфически-меркуриаловское понимание понятия "принадлежность ветке". Для слабограмотных разработчиков и отсутствия адекватного слежения за расстановкой таких указаний, согласен, полезно заводить такой автомат, потому что он будет давать хоть какие-то данные о том, откуда и зачем этот коммит.
Я видел и пробно использовал его. Даже близко не похоже и очень неудобно.
Эта штука ещё тупее, практически равна stash.
Групповой push тоже есть, но не рекомендуется.
Это удобный вариант, но совсем не обязательный. Я в большинстве случаев обхожусь без временной ветки.
А TortoiseGit не даёт того же?
Если ограничивать себя тем же уровнем функциональности и набором возможных flow, то и в гите их точно так же не нужно. Но Git позволяет сильно больше и гибче с минимумом усилий.
Я однажды сделал merge с совершенно другой кодобазой, и это сработало. О чём это говорит, кроме того, что я ошибся? ;)
В Git коммит тоже принадлежит ветке и имеет свой id. Что не так?
Вы допустили в фразе "кастрирован и импотентен" десяток ошибок.
Для безопасности в Git есть reflog и ветки, которые позволяют фиксировать любое состояние с возможностью его вернуть.
Потому что всех устраивает, что в коммитах всё перемешано?
А до правок текста тех строк, что отправляются (например, убрать комментарий типа "а вот тут главное")? Ну и это отдельный инструмент, а в Git оно в коробке.
Но я согласен в том, что проверять надо по уровню отправляемого коммита. Можно остальное скинуть в stash, но я предпочитаю делать `git co HEAD~1` или аналог, а потом вернуться. Stash он один на рабочую копию, а не на ветку.
Там нет усложнения, просто надо делать чуть иначе. Для построчного stash я не знаю, а вот `add -i` и `add -e` решают задачу. А "набрать в индекс" желательно, чтобы проверить, что же собрал... ну или последовательно amendʼом набирать правки.
Именно что пропадают. Вмержили в транк - осталась только запись в сообщении коммита.
Верно. Поэтому сообщение коммита начинаем с "MOO-1234: Fix moo frequency for most cow breeds". По этому "MOO-1234" выясняется и всё остальное. А как ветка была локально названа у конкретного коммиттера - уже неважно, да хоть "херня которая не даёт выспаться".
Повторюсь, я "за" сохранение метаинформации об изменениях, если коммиттер хочет этого и предоставляет её. Но при той юзербазе, что есть, отсутствие этой возможности означает минимальную потребность в ней. Какой-нибудь целевой плагин тут был бы, конечно, в тему.
Я плюсанул, но подозреваю, что дело в случае Меты не в лежащем внизу тулинге, а в желании гнать фичи на максимальной скорости...
Ну вот это можно уже изучать на предмет оптимизации, конечно, хотя бы плагинами...
А
rerere
в git не помогает? Вроде как раз для такого и задумана, после первой попытки, где надо таки разгрести вручную.Ну давайте смотреть на процесс. Вот есть изменение в libmoo. У нас монорепа на 200k продуктов. Нам надо отловить те, которые зависят от libmoo напрямую - это шаг 1. Как мы будем это искать? Наверняка есть какой-то список. Вести его в монорепе или в разбросе - нет разницы, всё равно добавлять вручную. (В автопоиск по всему дереву - не верю.)
CI автомат? Ему точно так же нужен явный список. А после этого вытаскивать отдельные подветки толстой репы (не тащить же её целиком!) или отдельные маленькие репы - разницы нет, или второе даже проще.
На любой такой коммит CI должен всё проверить.
Шаг 2 - проекты, связанные с зависящими (типа сетевого взаимодействия) - тем более тоже на основании явно описанных связей.
Так для чего мудохаться с моно?
(На самом деле есть одна тонкость с субмодулями: для некоторых ситуаций нужно хукать замену URL к модулям. Но это в тысячи раз проще поддержки монореп.)
О, вот тут действительно интересный вопрос. Если сводный коммит на библиотеку и все её зависимости, типа добавили один аргумент в функцию её API.
Но это само по себе проблемно. И коммит такой анализировать сложно, и грануляция страдает, и атомарность изменения как раз может быть субмодулями исключена, просто не потерять плавный переход на новую версию.
В Gerrit существует уже 10 лет, типа такого: https://gerrit-review.googlesource.com/c/plugins/scripts/+/411660
см. "relation chain" и номера patchsetʼов: после правки в предыдущем в цепочке следующие надо обновить или локально с пушем, или через средства сервера. В Мете изобрели велосипед.
Вот.
1. В Git для этого не нужен какой-то отдельный GUI, всё из коробки.
2. Git позволяет это делать (без GUI, `add --e`) даже не с отдельными диффами, а со строками. Критично, когда в таком диффе на 2 строки изменения, которые должны пойти на сервер, 3 на отладочную печать и 4 на комментарий для себя, что тут происходит и почему.
Может, для мелких дежурных правок такое и не нужно, но для задачи типа моей текущей сейчас, где сплошное "сигнал пошёл через обсервер в состояние вложенной FSM", мои комментарии "какого хера? уточнить это место" не должны идти в коммит даже если они на хинди.
3. После я пересобираю правки и, например, переименования идут в один коммит, doxygen-пояснения - в другой (если их не было, потому что вот такая кодобаза), а функциональные правки - в третий. И только после этого я выставляю это в виде чистого, аккуратного результата, который легко ревьюить сейчас, читать даже через пару лет, прогонять через CI или bisect в любой момент.
А с Mercurial и его "вам это не нужно" в коммиты шли бы грязь, грязь и грязь из разнородных изменений и "я тут ещё одно место добавил и заодно функции описал".
Польза от staging возникает задолго до пуша на сервер.
Угу - "даём работать с распределённой базой как с простой централизованной, но с плюшками".
Вы тут "бранчами" называете теги сообщения коммита, которые показывают, в рамках какой разработки был сделан коммит. Ни в Git ни, на самом деле, в Hg это не нужно, если есть возможность писать его в сообщении коммита - что всегда и делается в процессе уровня больше чем "я и моя собака".
Как сами меркуриаловцы признают, "The term branch is sometimes used for slightly different concepts. This may be confusing for new users of Mercurial." В результате получаются ситуации типа "Две ветки-2 в пределах ветки-1 (не путать с веткой-3)" (ветка-1 это его внутренний branch, ветка-2 это безымянная голова, ветка-3 это bookmark).
А это _в основе_ единственно правильный вариант (ну не учитываем, что объекты могут представляться в виде дельт, это уже вопрос сжатия репы). Трекинг копирования/переименования должен делаться уже отдельно поверх него.
Представление, где каждый каталог и файл представляются хэшом и собственно найти изменённые файлы между коммитами - это очень экономная операция (все случаи разных хэшей отбрасываются из сравнения), позволяет как раз очень экономно определять набор тех файлов, в пределах которых надо вести трекинг уже по их содержимому.
Для сложных случаев типа "переместили 200000 файлов и при этом изменением `#include <moo/foo/boo/boo.h>` на `#include <util/moo/foo/boo/boo.h>` поменяли их хэши... ну да, можно было бы придумать какие-то подпорки. Но, насколько видим, это даже для крупных реп не составляет большой проблемы.
Ну и очень хорошо угадывает.
Опять же, да, я иногда (раз в два года) предпочёл бы видеть возможность явно ему сказать "считай, что Foo переименован в Boo, а историю Moo, сделанного клоном из него, надо вести отдельно". В целом, не настолько проблема.
Ну зачем же так, всё проверяется:
Git: Initial release 7 April 2005
Mercurial: Initial release 19 April 2005
Стиль Github, GitLab, Bitbucket - это "разрешим работать с распределённой VCS ко ак с централизованной". Это не родное для Git.
Более адекватное приспособление к стилю собственно Git это Gerrit. Он используется как серверная база в самом гугле (с сильными внутренними подточками). Но у него нету CI и прочих удобств в едином флаконе, их надо довинчивать.
1. staging area. В Mercurial ничего подобного нет и не планируют. А это (вместе с interactive rebase) практически единственное, что позволяет легко делать чистые коммиты, а не такие, в которых намешало 100500 разных типов правок.
Для меня любая VCS, в которой этого нет, непригодна.
2. Отсутствие зажима на определённые процессы разработки - который в Mercurial выглядит как множественные головы, тяжело изменяемый статус коммита вроде draft/public, и т.п.
Mercurial выглядит как "сэмулируем централизованную VCS на базе распределённой, но так, чтобы людям не надо было думать, что они делают".
Умеет. Вы, наверно, git clone запускали. Потому что если сделать init + fetch, то докачка работает с момента обрыва. Не идеально, некоторые мета-части передаются заново, но есть сохранение принятого.
Ну и ещё есть https://github.com/johnzeng/ResumableGitClone и наверняка ещё десяток похожих проектов.
Можно. Были даже примеры простых игр (уровня Pacman) как (U)EFI бинарей.
Проблема в том, что это отдельная платформа со своей спецификой, и что-то большое разрабатывать под неё тупо нет смысла. Вам придётся сделать свой R/W драйвер целевой FS, свою поддержку мультипроцессности в нужном стиле, достаточно богатое API для работы такого сервиса, сделать все нужные драйвера включая сетевой (EFI может его не предоставлять)... сама модель EFI ориентирована на простоту (ну, как её понимает Intel) и надёжность процесса, а не на скорость... с какого-то момента будет понятно, почему если "за морем телушка - полушка, да рубль перевоз", то грузить Linux с диска дешевле во всех смыслах:)