Re[22]: фиктивный мерж
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 23.02.22 12:41
Оценка:
Здравствуйте, Sharov, Вы писали:

S>Здравствуйте, netch80, Вы писали:


N>>Ты ж сам через ours делаешь фиктивный мерж — второй родитель есть в истории и игнорируется по факту.


S>Я что-то упустил, но почему merge с ours фиктивный? Обычный 3-way merge, просто при конфликтах выберут нашу версию.


Проверил на практике — не совсем.
Вот base: в файле 'a' — 'a', 'b' — 'b'.
Создал ветку 'aa' где в файле 'a' — 'aa'.
Создал ветку 'bb' где в файле 'b' — 'bb'.
Создал ветку 'do_merge' от 'aa' и сказал 'git merge bb'.
Если бы ours работало только при конфликте, то в 'b' было бы 'bb'. Но я вижу там 'b'.
Попробовал ещё и чтобы в ветке bb был файл b1. При таком же мерже — его не оказалось.

Вывод: таки фиктивный.

В доке у него разделяются _strategy_ "ours" и _option_ "ours" для merge strategy. Наверно, ты думал про второе.
The God is real, unless declared integer.
Re[22]: Git: rebase vs merge или линейная история против спа
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 23.02.22 12:48
Оценка:
Здравствуйте, ·, Вы писали:

N>>·>Я знаю, что можно таки добиться и делать без старых багов стоя в гамаке. Но это не самый простой способ.

N>>Если дифф правки переносится 1:1 — всё просто и проще чем с мержем вверх.
N>>Если нет, то в любом случае надо думать, как переносить исправление.
·>Не проще. И больше шанс нарваться на необходимость ручного разрешения конфликтов.

Если это то что ты писал в предыдущем сообщении, то это ерунда
Автор: netch80
Дата: 23.02.22
не имеющая отношения к реальности.

N>>>>Нифига себе у тебя искусственный интеллект завёлся.

N>>·>Да. У меня пайплайн мержит автоматом, я же уже писал.
N>>Такой автомат не умеет решать описанный мной вопрос. Ты опять уводишь в сторону.
·>Я вроде ответил. Повторюсь другими словами. По умолчанию автомат мержит. В редких случаях, если заранее известно, что авто-мерж не нужен, то мержим желаемым образом вручную и тогда автомат ничего не делает, т.к. ветки не будут diverged, мержить банально нечего. В очень редких случаях, если выяснилось, что мерж не нужен был, можно сделать реверт.

Реверт мержа? Ещё один усложнизм на ровном месте.

N>>·>Про ours я уже объяснял — это вообще редкость (не уверен, что наберётся хоть десяток за год). И решается либо предварительным явным мержем, либо ревертом.

N>>·>С черрипиками беда, что это происходит когда попало и в итоге приходится разрешать конфликты спустя недели, часто кому-то другому, кто не в теме. И не приходится разбираться — незачерипикали что-то нарочно или просто забыли.
N>>Вот именно что "когда попало" не происходит. Черипики во все активные ветки, куда нужно переправлять патч, посылаются сразу при исполнении тикета. Ты себе что-то такое непонятное прифантазировал про нас и делаешь из этого кривые выводы.
·>Автоматом? Как контролировать что ничего не забыли?

Человеком. Он выбирает, какие коммиты куда должны пойти. Ревьюеры проверяют комплектность со своей точки зрения. Часто оказывается, что для другой ветки что-то надо убрать, что-то добавить.
Финальную точку ставят тесты.
Но сделать ЧП на всю цепочку — для простого случая — это банальное действие.

N>>>>Не должна вся история там храниться. Код — это только код. Множество факторов, например, почему была выбрана такая архитектура и такая реализация, не могут храниться в коде.

N>>·>Может, конечно. Это обычно хранят в комментах коммита (как минимум туда помещают ссылку на вики, например).
N>>"Как минимум" там обязательная ссылка на тикет. А в тикете уже всё что нужно включая дискуссии, вики и всё такое.
N>>В сообщение коммита добавляется, конечно, описание, почему так, но без совсем уж тотальных подробностей.
·>Т.е. таки _могут_ храниться в коде. Погугли "git message best practices" или типа того. То что вы не храните — это ваша проблема.

Спасибо, с практиками знакомы. Но заменять сообщениями коммита всю ту информацию, что может быть в тикете, некорректно — там может быть тонна pdf'ок, логи, и много подобного.
Ты впал в режим Адмирала Ясен Хер и не просто думаешь, что ты главный кэп на форуме, а ещё и активно это пропагандируешь. Это тупо смешно.

·>Там большинство коммитов — мержи. Черрипики обычно для backporting — когда баг пофикшенный в последней версии очень надо запихать в предыдущую.


Именно.

N>>Ну а для транка я никогда такой подход и не предлагал. (Хотя иногда используем ЧП в направлении более свежих веток; нетипично, но допустимо).

·>Немного покопался и вот тебе ещё типичный пример: один и тот же коммит появляется в jdk-18+33 и в jdk-19+7 и т.д. Вот мерж-коммит из 18+33 в 19. Заметь как там разница merge conflict красиво рисуется. И вообще вся история как на ладони, в трекер лазить не надо.

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

N>>И всё равно это контекст транка: например, на нём сформировали и тегировали 5.10, вот в этот момент всем, кто ведёт разработку в доп. ветках, предлагают сделать merge (или rebase).

·>Ок, соглашусь, тут немного не о том пишут. Поищу на досуге более релевантное. Врочем, я не вижу причин почему эти рекомендации вдруг надо менять на противоположные в немного другом контексте. Рекомендаций к твоему подходу мне видеть пока не доводилось.

Значит, игнорировал в упор. Потому что их много.

·>От младших к старшим — это и есть естественное направление, DAG однако. У вас всё перевёрнуто, отсюда и мучения с черрипиками и бардак при мержах.


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

Но я запомню как странный вариант.

N>>ЧП даёт то же знание, что баг вылечился. Коммит с тегом тикета есть в истории, тикет содержит ссылки на исправленные ветки. Ещё и в сообщении коммита могут быть нужные слова.

·>Коммит не даёт. Вам даёт знание тикет, если, конечно, его правильно проапдейтили и ничего не перепутали.

В коммите есть базовое описание. Если его недостаточно, идём к тикету. Но такие ситуации встречаются уже когда требуется что-то более глубокое, чем просто анализ "когда это возникло", и тогда оно 100% требует анализа контекста, предусловий и т.п.

·>Ну так ты же мудохаешься с мержами зачем-то. Хинт: мержами пользоваться надо, а не мудохаться с ними.


Вот как раз не пользуемся — и поэтому не мудохаемся

N>>А так — мало ли что напоминает. Обвинить в ретроградстве тривиально, сложнее — доказать обвинение. Пока что у тебя не получается: ни достаточных аргументов, ни массового опыта такого подхода.

·>А ты меня тут в шарманстве обвиняешь.

???

N>>Даже в исконной обители git черипики — постоянная практика.

·>Постоянная, но не для того, для чего используете вы. Вы молотком забиваете шурупы. Оно, конечно, лучше, чем гвозди отвёрткой вркучивать, но... И вы даже однажды попробовали плоской отвёрткой закрутить шуруп с крестовой шляпкой, порезались, плюнули и перешли на молоток.

Плохая аналогия подобна котёнку с дверцей. Ещё и неадекватная.

N>>·>Угу. И так же при твоём варианте лесом пойдёт много вкусностей типа bisect.

N>>Нет, никуда bisect не уходит. Точно так же ЧП коммит будет опознаваем и бисектоспособен в истории.
·>Ты не понял. Баги пофиксенные в v1 не должны появляться при бисекте v1.2.3..v2.3.4, а черрипики будут.

Не будут. Потому что такого бисекта просто не будет. Он не адекватен и не нужен.

N>>>>Дадада. Вот и получается формально мерж, по факту не мерж.

N>>·>Не знаю что за факт такой.
N>>Ты ж сам через ours делаешь фиктивный мерж — второй родитель есть в истории и игнорируется по факту.
·>Я не знаю что такое фиктивный мерж. Можно сссылку на доки?

Это то, что ты делаешь с ключом ours. Одна сторона формально присутствует, по факту игнорируется.
The God is real, unless declared integer.
Re[3]: Git: rebase vs merge или линейная история против спагетти
От: halo Украина  
Дата: 23.02.22 14:27
Оценка: 15 (1)
Здравствуйте, Sharov, Вы писали:

S>Я не могу с topic-ветки на родительскую сделать rebase? git checkout parent, git pull; git checkout topic; git rebase parent

S>(или как-то так).
S>Что значит
S>

S>после предварительного git rebase topic-ветки.

S>?

Почему не можете? Именно так я и делаю, и именно об этом говорил в первом пункте, после чего -- git push --force, конечно. У нас с topic-ветками разрешены любые операции как локально (впрочем, кто запретит-то?), так и удалённо (потому что никто не заморачивается над их защитой). Но запрещено делать слияние в master-ветку без предварительного перебазирования topic-ветки на master (для упрощения будем считать, что единственной родительской веткой является master). Сама механика такой защиты реализуется в git серверными хуками, следуя определёнными правилами, принимающими или отклоняющими измения в ветках (точнее ссылках на фиксации) (правил множество: локально или удалённо пытаются подвинуть ветку; был ли это force-push; пытается ли кто-то откатить её назад; что там с топологией сливаемых изменений и т.д. и т.п., в чём может помочь git merge-base)).

Допустим, у меня локально было так (визуализацию ветки cool-feature для упрощения "согнул" вправо, хотя git log --graph выровняет её и прижмёт к левому краю, но, снова же, это не имеет значения):

  @ "Cool feature change 2" (<- refs/heads/cool-feature; refs/remotes/origin/cool-feature)
  * "Cool feature change 1"
  * "Cool feature change 0"
 /
* (<- refs/heads/master; refs/remotes/origin/master)
|\
| * "Basic feature change"
|/
*


Потом я узнаю, что на master-ветке произошли изменения и они были приняты на master (написали лично, пришло письмо, пропала кнопка "Merge" на том же GitLab). С этого момента, поскольку refs/remotes/origin/cool-feature больше не содержит фиксации, на которую в данный момент указывает refs/heads/master (с точки зрения удалённого репозитория), удалённый репозиторий не позволит принять изменения с ветки cool-feature на master. Локально синхронизируем новые изменения:

$ git checkout master
$ git pull # предпочитаю git fetch --prune && ​git merge --ff-only @{U}


@ "Merge basic-feature-fix into master" (<- refs/heads/master; refs/remotes/origin/master)
|\
| * "Basic feature fix"
|/
| ​@ "Cool feature change 2" (<- refs/heads/cool-feature; refs/remotes/origin/cool-feature)
| ​* "Cool feature change 1"
​| ​* "Cool feature change 0"
​|/
* "Merge basic-feature into master"
|\
| * "Basic feature"
|/
*


Делаем git rebase:

$ git checkout cool-feature
$ git rebase master


  ​@ "Cool feature change 2" (<- refs/heads/cool-feature)
  ​* "Cool feature change 1"
​  ​* "Cool feature change 0"
​ /
@ "Merge basic-feature-fix into master" (<- refs/heads/master; refs/remotes/origin/master)
|\
| * "Basic feature fix"
|/
| @ "Cool feature change 2" (<- refs/remotes/origin/cool-feature)
| ​* "Cool feature change 1"
​| ​* "Cool feature change 0"
​|/
* "Merge basic-feature into master"
|\
| * "Basic feature"
|/
*


Уведомляем удалённый репозиторий о своих изменениях:

$ git push -f


  ​@ "Cool feature change 2" (<- refs/heads/cool-feature; refs/remotes/origin/cool-feature)
  ​* "Cool feature change 1"
​  ​* "Cool feature change 0"
​ /
@ "Merge basic-feature-fix into master" (<- refs/heads/master; refs/remotes/origin/master)
|\
| * "Basic feature fix"
|/
* "Merge basic-feature into master"
|\
| * "Basic feature"
|/
*


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

$ git checkout "$TARGET_REF"
$ git merge --no-ff --no-squash "$SOURCE_REF"
... исполнение проверок в ./git/hooks/pre-merge-commit ...
$ test ! -z "$DELETE_SOURCE_REF" && git branch -d "$SOURCE_REF"


Тогда локально:

$ git checkout master
$ git pull
$ git branch -d cool-feature


@ "Merge cool-feature into master" (<- refs/heads/master; refs/remotes/origin/master)
|\
| ​* "Cool feature change 2" (<- refs/heads/cool-feature) (если ветка на удалённом репозитории не удалена и не было git fetch --prune)
| ​* "Cool feature change 1"
​| ​* "Cool feature change 0"
​|/
* "Merge basic-feature-fix into master"
|\
| * "Basic feature fix"
|/
* "Merge basic-feature into master"
|\
| * "Basic feature"
|/
*


По такой схеме легко увидеть некоторую закономерность. Поэтому:

* --no-ff -- создание отдельной фиксации для слияния ("Merge ... into master"), иначе git на удалённой машине просто переместит refs/heads/master на последнее изменение в cool-feature
__* мотивация 1: упрощение отслеживания времени сливания ветки, иначе имело бы тупо линейный вид как trunk в Subversion;
__* мотивация 2: отчёт лога изменений от версии к версии прямиком из merge-фиксаций с помощью тупого git log --format --merges (но это, к сожалению, если при git merge на удалённом репозитории можно указать свои сообщения)
* контраргумент: "нравится линейность, merge-фиксации засоряют граф" -- можно визуализировать историю с помощью git log --no-merges
* --no-squash -- запретить сжимать все фиксации между master и cool-feature в одно изменение перед слиянием
__* мотивация 1: отслеживание изменений на ветке по отдельности;
__* мотивация 2: возможность git revert отдельного изменения в случае необходимости, если каждая фиксация содержит логически атомарное и завершённое изменение
__* контраргумент: "мне нравится squash, так как он убирает весь промежуточный мусор" -- никто не запрещает регулярно пользоваться commit --amend или интерактивным rebase у себя на ветке по мере необходимости во время рабочего процесса, или позже самому сделать squashed-фиксацию с помощью git rebase -i и команд pick/fixup/squash.

Из минусов такого подхода могу назвать следующее:
* если есть множество открытых PR, каждый из них приходится перебазировать на только что обновлённый master вручную;
* автоматическая генерация сообщений вида "Merge ... into master" на удалённой системе, мягко говоря, малоинформативна, даже если включает в себя ссылки на тикеты в баг-трекерах и на pull-request-ы;
* на удалённом репозитории, если есть CI, это может занимать слишком продолжительное время;
* поскольку rebase это, в общем случае, о применении наборов патчей, со временем неизбежны конфликты с родительских веток в промежуточных изменениях, в то время, как merge просто будет пытаться слить только последние изменения на этих ветках (если не ошиюбаюсь, делая в некоторых случаях исключения) -- это общая проблема rebase, когда его сравнивают с merge; + ещё одна проблема rebase: если при git merge отрезолвили конфликт, при постоянном git rebase изменений, который ещё не слили в родительскую ветку, есть ненулевая возможность неправильно поправить конфликт и даже не заметить этого, что потом можно даже и не вспомнить (но, снова же, по-моему, это решается git rerere);
* иногда на master может попасть что-то нежелательное, что можно удалить только имея права прямой записи в такой master с локальной машины (например, на topic-ветке кто-то сделал commit, а тогда revert (вместо commit --amend, reset, rebase или любого другого способа, убирающего ненужное из истории), таким образом создав zero-diff из двух фиксаций, которые наверняка при review не заметят), при этом предупредив всех, что master придётся подправвить, что может повлиять на уже существующие изменения (как локально, так и удалённо, причём не важно в каком масштабе).

Понимаю, что выложил сумбурно, но как умею, и, надеюсь, это более развёрнуто отвечает на вопрос о применяемых практиках.
Re[23]: Git: rebase vs merge или линейная история против спа
От: · Великобритания  
Дата: 23.02.22 17:31
Оценка:
Здравствуйте, netch80, Вы писали:

N>>>Если дифф правки переносится 1:1 — всё просто и проще чем с мержем вверх.

N>>>Если нет, то в любом случае надо думать, как переносить исправление.
N>·>Не проще. И больше шанс нарваться на необходимость ручного разрешения конфликтов.
N>Если это то что ты писал в предыдущем сообщении, то это ерунда
Автор: netch80
Дата: 23.02.22
не имеющая отношения к реальности.

Да, действительно... извиняюсь. Пытаюсь быстренько нагуглить и натыкаюсь не на то. Вот тут есть чтиво про common ancestor и recursive merge: https://devblogs.microsoft.com/oldnewthing/20180315-00/?p=98245

N>>>Такой автомат не умеет решать описанный мной вопрос. Ты опять уводишь в сторону.

N>·>Я вроде ответил. Повторюсь другими словами. По умолчанию автомат мержит. В редких случаях, если заранее известно, что авто-мерж не нужен, то мержим желаемым образом вручную и тогда автомат ничего не делает, т.к. ветки не будут diverged, мержить банально нечего. В очень редких случаях, если выяснилось, что мерж не нужен был, можно сделать реверт.
N>Реверт мержа? Ещё один усложнизм на ровном месте.
Эээ? Что в этом сложного? Одна команда, не сложнее черрипика. А с учётом того, что на автоматизация заменяет сотни ручных черрипиков то один-два реверта ну никак на усложним не тянут. Или ты тоже панически боишься ревертов?

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

N>·>Автоматом? Как контролировать что ничего не забыли?
N>Человеком. Он выбирает, какие коммиты куда должны пойти. Ревьюеры проверяют комплектность со своей точки зрения. Часто оказывается, что для другой ветки что-то надо убрать, что-то добавить.
N>Финальную точку ставят тесты.
N>Но сделать ЧП на всю цепочку — для простого случая — это банальное действие.
Т.е. контроля нет. Вся надежда на внимательность человека.

N>·>Т.е. таки _могут_ храниться в коде. Погугли "git message best practices" или типа того. То что вы не храните — это ваша проблема.

N>Спасибо, с практиками знакомы. Но заменять сообщениями коммита всю ту информацию, что может быть в тикете, некорректно — там может быть тонна pdf'ок, логи, и много подобного.
N>Ты впал в режим Адмирала Ясен Хер и не просто думаешь, что ты главный кэп на форуме, а ещё и активно это пропагандируешь. Это тупо смешно.
Ты заявил глупую вещь, что "не могут храниться в коде", вот и пришлось покапинанствовать. Более того, при желании pdf-и и логи тоже можно класть в репу в виде git notes.

N>·>Там большинство коммитов — мержи. Черрипики обычно для backporting — когда баг пофикшенный в последней версии очень надо запихать в предыдущую.

N>Именно.
backporting — обычно происходит редко, и индикация бардака в проекте. А я гововрю о forward-porting, это идеал процесса разработки.

N>>>Ну а для транка я никогда такой подход и не предлагал. (Хотя иногда используем ЧП в направлении более свежих веток; нетипично, но допустимо).

N>·>Немного покопался и вот тебе ещё типичный пример: один и тот же коммит появляется в jdk-18+33 и в jdk-19+7 и т.д. Вот мерж-коммит из 18+33 в 19. Заметь как там разница merge conflict красиво рисуется. И вообще вся история как на ладони, в трекер лазить не надо.
N>OK, есть публичный пример, как люди работают в этой схеме.
Это не некий пример, мне лень искать, но полагаю большинство современных проектов идут по такой системе. Это то на что заточен git и прочие тулзы около него. Например, в том же github ты видишь список тегов и веток в которых лежит данный коммит, чп эту систему ломают.
Твоя система — это устаревший подход из всяких svn, которые мержить не умели.

N>>>И всё равно это контекст транка: например, на нём сформировали и тегировали 5.10, вот в этот момент всем, кто ведёт разработку в доп. ветках, предлагают сделать merge (или rebase).

N>·>Ок, соглашусь, тут немного не о том пишут. Поищу на досуге более релевантное. Врочем, я не вижу причин почему эти рекомендации вдруг надо менять на противоположные в немного другом контексте. Рекомендаций к твоему подходу мне видеть пока не доводилось.
N>Значит, игнорировал в упор. Потому что их много.
Ссылку в студию.

N>·>От младших к старшим — это и есть естественное направление, DAG однако. У вас всё перевёрнуто, отсюда и мучения с черрипиками и бардак при мержах.

N>Про мучения ты себе что-то нафантазировал.
N>Бардак при мержах был бы, если бы мы использовали твой подход с мержами. Но нет такого подхода — нет и бардака
Ага. В мелком тривиальном проекте типа jdk оно может и сработает, а в вашем исключительном проекте другие законы природы.

N>Но я запомню как странный вариант.

Да, запомните этот твит!

N>>>ЧП даёт то же знание, что баг вылечился. Коммит с тегом тикета есть в истории, тикет содержит ссылки на исправленные ветки. Ещё и в сообщении коммита могут быть нужные слова.

N>·>Коммит не даёт. Вам даёт знание тикет, если, конечно, его правильно проапдейтили и ничего не перепутали.
N>В коммите есть базовое описание. Если его недостаточно, идём к тикету. Но такие ситуации встречаются уже когда требуется что-то более глубокое, чем просто анализ "когда это возникло", и тогда оно 100% требует анализа контекста, предусловий и т.п.
Я не про описание коммита, а про положение коммита в графе истории.

N>·>Ну так ты же мудохаешься с мержами зачем-то. Хинт: мержами пользоваться надо, а не мудохаться с ними.

N>Вот как раз не пользуемся — и поэтому не мудохаемся
Вы мудохаетесь с чп.

N>>>А так — мало ли что напоминает. Обвинить в ретроградстве тривиально, сложнее — доказать обвинение. Пока что у тебя не получается: ни достаточных аргументов, ни массового опыта такого подхода.

N>·>А ты меня тут в шарманстве обвиняешь.
N>???
Ну что-то про девочки-шарман высказался по поводу каких-то "необычных" мержей.

N>>>Даже в исконной обители git черипики — постоянная практика.

N>·>Постоянная, но не для того, для чего используете вы. Вы молотком забиваете шурупы. Оно, конечно, лучше, чем гвозди отвёрткой вркучивать, но... И вы даже однажды попробовали плоской отвёрткой закрутить шуруп с крестовой шляпкой, порезались, плюнули и перешли на молоток.
N>Плохая аналогия подобна котёнку с дверцей. Ещё и неадекватная.
Что за котёнок — я не знаю. А моя аналогия очень точная. Использование черрипиков для forwardporting — типичное забивание шурупов молотком.

N>·>Ты не понял. Баги пофиксенные в v1 не должны появляться при бисекте v1.2.3..v2.3.4, а черрипики будут.

N>Не будут. Потому что такого бисекта просто не будет. Он не адекватен и не нужен.
Почему? Это какой-то закон природы? Чем ваш релиз 89 с десятком патчей так принципиально полностью отличается от релиза 90 с патчами? Неужели вы проект уже 90 раз с нуля переписывали?!!

N>·>Я не знаю что такое фиктивный мерж. Можно сссылку на доки?

N>Это то, что ты делаешь с ключом ours. Одна сторона формально присутствует, по факту игнорируется.
Я не знаю что это значит. Ну допустим ты наклеил ярлык "фиктивный". И? Ты говоришь как будто это что-то плохое.
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re[4]: Git: rebase vs merge или линейная история против спагетти
От: · Великобритания  
Дата: 23.02.22 21:54
Оценка:
Здравствуйте, halo, Вы писали:

h> $ git pull # предпочитаю git fetch --prune && ​git merge --ff-only @{U}

Можно просто git pull --ff-only или config pull.ff=only и будет по дефолту.

h> Делаем git rebase:

h> $ git checkout master
h> $ git pull
h> $ git checkout cool-feature
h> $ git rebase master

Не обязательно так сложно, просто сразу уже находясь в "cool-feature" сделать git pull -r origin master.
avalon/3.0.0
но это не зря, хотя, может быть, невзначай
гÅрмония мира не знает границ — сейчас мы будем пить чай
Re: Git: rebase vs merge или линейная история против спагетти
От: maxkar  
Дата: 24.02.22 21:13
Оценка: 5 (1)
Здравствуйте, vsb, Вы писали:

vsb>Каким подходом вы пользуетесь, как решаете проблемы (и считаете ли их проблемами)?


Мержи с причесанными сообщениями (не полностью автоматическими, а подправленными ручками). Потому что в этом случае есть выбор, какую историю смотреть. Можно смотреть весь граф если очень хочется. Можно смотреть только мастер и там будут красивые одиночные merge requests с прекрасным описанием. Мелкие проблемы с незнанием ключиков вроде --first-parent (и log, и bisect его поддерживают, что еще надо то?) решаются обучением.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.