Каковы преимущества сохранения линейной истории в git

Когда меня учили использовать git с центральным репо (проект на Gitorious), мне сказали всегда использовать rebase вместо merge, потому что мы хотим иметь линейную историю. Поэтому я всегда старался работать таким образом.

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

Есть два преимущества, которые приходят мне на ум прямо сейчас:

  • git bisect
  • возможность отправки истории с другой системой управления версиями, такой как SVN

Есть ли другие преимущества?

Ответ 1

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

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

  • Переписывание истории может включать стирание истории
  • Не каждый может даже перебазировать
  • Преимущества часто завышены

Теперь, давайте копаться в этом.

Переписывание истории может включать в себя удаление истории. Здесь проблема с перебазированием всех ваших коммитов, чтобы сохранить все красивым и линейным: перебазирование обычно не без потерь. information- есть реальные, реальные вещи, которые были сделаны разработчиком - которые могут быть сжаты из вашей истории, когда вы перебазируете. Иногда это хорошо. Если разработчик улавливает свою собственную ошибку, ему приятно сделать интерактивную перебазировку, чтобы исправить это. Выявленные и исправленные ошибки уже были обработаны: нам не нужна их история. Но некоторые люди работают с тем человеком, который, кажется, всегда приводит к конфликтам слияний. Лично я не знаю ни одного разработчика по имени Нил, так что скажем, парень по имени Нил. Нил работает над действительно сложным кодом дебиторской задолженности в функциональной ветке. Код, который Нил написал в своей ветке, на 100% верен и работает именно так, как мы этого хотим. Нил готовит свой код для слияния с мастером, только чтобы обнаружить, что сейчас есть конфликты слияния. Если Нил объединяет мастер с его веткой функций, у нас есть история того, чем изначально был его код, плюс то, как выглядел его код после разрешения конфликтов слияния. Если Нил делает перебаз, у нас есть только его код после перебазирования. Если Нил допустит ошибку при разрешении конфликтов слияния, будет гораздо проще устранить неполадки первого, чем второго. Но что еще хуже, если Нил испортит свой ребаз достаточно неудачным способом (возможно, он сделал git checkout --ours, но он забыл, что в этом файле произошли важные изменения), мы можем навсегда потерять части его кода.

Я понимаю, я понимаю. Его юнит-тесты должны были поймать ошибку. Рецензент кода должен был поймать ошибку. QA должен был поймать ошибку. Он не должен был испортить разрешение конфликтов слияния в первую очередь. Бла, бла, пофиг. Нил на пенсии, финансовый директор в бешенстве, потому что наша бухгалтерская книга все испорчена, и если он скажет финансовому директору "в соответствии с нашей философией развития, этого не должно было случиться", я получу удар по лицу.

Не каждый может даже перебазировать, братан. Да, я слышал: вы работаете в какой-то стартап космической эры, и ваш журнальный столик IoT использует только самую крутую и современную реактивную рекуррентную нейронную сеть, основанную на цепочках, а технологический стек надоел! Ваш ведущий разработчик был буквально там, когда был изобретен Go, и все, кто там работает, были разработчиками ядра Linux с 11 лет. Мне бы хотелось услышать больше, но у меня просто нет времени на то, как часто я работаю. спросил "Как выйти из git diff???". Каждый раз, когда кто-то пытается выполнить ребазинг, чтобы разрешить свои конфликты с мастером, меня спрашивают: "Почему он говорит, что мой файл - это их файл", или "ПОЧЕМУ Я ТОЛЬКО ВИДУ ЧАСТЬ МОЕГО ИЗМЕНЕНИЯ", и все же большинство разработчиков могут справиться с объединением мастера в их ветка без происшествий. Может быть, это не должно быть так, но это так. Когда у вас есть младшие разработчики и стажеры, занятые люди и люди, которые не узнали, что такое контроль версий, пока они не были программистом в течение 35 лет в вашей команде, требуется много усилий, чтобы сохранить историю первозданной.

Преимущества часто завышены. Мы все были в одном проекте, где вы делаете git log --graph --pretty и вдруг ваш терминал был захвачен радужными спагетти. Но историю не трудно читать, потому что она нелинейная... Трудно читать, потому что она небрежная. Небрежная линейная история, где каждое сообщение коммита - "." не будет легче читать, чем относительно чистая нелинейная история с продуманными сообщениями коммита. Наличие нелинейной истории не означает, что вам нужно несколько раз сливать ветки назад и вперед друг с другом, прежде чем вы достигнете мастера. Это не значит, что ваши ветки должны жить 6 месяцев. Случайная ветвь на вашем графике истории - это не конец света.

Я также не думаю, что делать git bisect намного сложнее с нелинейной историей. Опытный разработчик должен иметь возможность придумать множество способов сделать свою работу. Вот одна статья, которая мне нравится, с приличным примером того, как это сделать. https://blog.smart.ly/2015/02/03/git-bisect-debugging-with-feature-branches/

TL;DR; Я не говорю, что ребаз и линейная история не велики. Я просто говорю, что вам нужно понять, на что вы подписываетесь, и принять обоснованное решение о том, подходит ли это вашей команде. Совершенно линейная история не обязательна и, конечно, не бесплатна. Это может определенно сделать жизнь прекрасной в правильных обстоятельствах, но это не будет иметь смысла для всех.

Ответ 2

Линейная история Git (предпочтительно состоящая из логических шагов) имеет много преимуществ. Помимо двух уже упомянутых вещей, есть также ценность в:

  1. Документация для потомков. За линейной историей обычно легче следить. Это похоже на то, как вы хотите, чтобы ваш код был хорошо структурирован и документирован: всякий раз, когда кому-то нужно иметь дело с ним позже (кодом или историей), очень важно иметь возможность быстро понять, что происходит.
  2. Повышение эффективности и эффективности проверки кода. Если ветвь темы разделена на линейные логические шаги, ее гораздо проще просмотреть по сравнению с просмотром извилистой истории или раздавленного монолита изменений (который может быть подавляющим).
  3. Когда вам нужно изменить историю позже. Например, при возврате или выборе вишни целиком или частично.
  4. Масштабируемость. Если вы не стремитесь сохранять свою историю линейной, когда ваша команда становится больше (например, сотни участников), ваша история может стать очень раздутой из-за слияний между ветвями, и всем участникам может быть трудно отслеживать, что происходит.

В целом, я думаю, что чем менее линейна ваша история, тем она менее ценна.

Ответ 3

С линейной историей вы можете легко отслеживать историю для одного файла по переименованиям с помощью git log --follow. Цитирование документации по параметру log.follow :

Если true, git log будет действовать так, как если бы опция --follow использовалась, когда одиночный & lt; путь & gt; дано. Это имеет те же ограничения, что и --follow, то есть он не может быть использован для отслеживания нескольких файлов и не работает должным образом по нелинейной истории.