Почему каждый серьезный репозиторий Github, который я выполняю, требует, чтобы я раздавил свои коммиты в один коммит?
Я думал, что журнал git был там, чтобы вы могли проверить всю свою историю и точно увидеть, где произошли какие-то изменения, но раздавив ее, вытащите ее из истории и объедините все в один коммит. Какой смысл?
Это также, кажется, идет вразрез с мантрой «давай рано и часто».
Ответы:
Так что у вас есть четкая и краткая история Git, которая ясно и легко документирует сделанные изменения и причины, почему.
Например, типичный «несокрушенный» журнал git для меня может выглядеть следующим образом:
Какой беспорядок!
Принимая во внимание, что более тщательно управляемый и объединенный журнал git с небольшим дополнительным вниманием к сообщениям для этого может выглядеть следующим образом:
Я думаю, что вы можете видеть суть фиксации коммитов в целом, и тот же принцип применяется для запросов на извлечение - читабельность истории. Вы также можете добавлять в журнал коммитов, который уже содержит сотни или даже тысячи коммитов, и это поможет сделать краткую и краткую историю роста.
Вы хотите совершить рано и часто. Это лучшая практика по многим причинам. Я обнаружил, что это приводит меня к тому, что у меня часто появляются коммиты, которые являются «wip» (незавершенным) или «part A done» или «опечатка, мелкое исправление», где я использую git, чтобы помочь мне работать и дать мне рабочие точки, которые Я могу вернуться к тому, если следующий код не работает, поскольку я прогрессирую, чтобы заставить вещи работать. Однако мне не нужна или не нужна эта история как часть окончательной истории git, поэтому я могу раздавить свои коммиты - но см. Примечания ниже относительно того, что это значит в ветке разработки против master.
Если существуют основные этапы, представляющие различные рабочие этапы, все равно можно использовать более одного коммита на функцию / задачу / ошибку. Однако это может часто подчеркивать тот факт, что разрабатываемая заявка является «слишком большой» и должна быть разбита на более мелкие части, которые могут быть автономными, например:
похоже на «1 часть работы». Либо они существуют, либо нет! Кажется, не имеет смысла разбивать это. Однако опыт показал мне, что (в зависимости от размера и сложности организации) более детальный путь может быть:
Маленькие кусочки означают более легкие проверки кода, более простое модульное тестирование, лучшую возможность проверки качества, лучшее согласование с принципом единой ответственности и т. Д.
Из практических соображений того, когда на самом деле делать такие сквош, в основном есть два отдельных этапа, которые имеют свой собственный рабочий процесс.
Во время разработки вы делаете «рано и часто» и быстро «одноразовыми» сообщениями. Иногда вы можете захотеть раздавить, например, сдавить в сообщениях wip и todo. В ветке можно сохранять несколько коммитов, которые представляют собой отдельные шаги, которые вы сделали в процессе разработки. Большинство сквошов, которые вы выбираете, должны находиться в пределах этих ветвей функций, пока они находятся в стадии разработки и до слияния с мастером.
При добавлении в ветку mainline вы хотите, чтобы коммиты были краткими и правильно отформатированными в соответствии с существующей историей mainline. Это может включать идентификатор системы Ticket Tracker, например, JIRA, как показано в примерах. Сквошинг здесь на самом деле не применяется, если вы не хотите «свернуть» несколько отдельных коммитов на мастере. Обычно нет.
Использование
--no-ff
при слиянии с мастером будет использовать один коммит для слияния, а также сохранит историю (в ветке). Некоторые организации считают это лучшей практикой. Подробнее на https://stackoverflow.com/q/9069061/631619. Вы также увидите практический эффект,git log
когда--no-ff
коммит будет последним коммитом, в верхней части HEAD (когда он только что сделан), тогда как без--no-ff
него может быть дальше в историю, в зависимости от дат и других коммитов.источник
Поскольку часто человек, занимающийся пиаром, заботится о сетевом эффекте коммитов «добавленная функция X», а не о «базовых шаблонах, функции исправления ошибок X, функции добавления Y, исправленных опечатках в комментариях, скорректированных параметрах масштабирования данных, hashmap работает лучше, чем список "... уровень детализации
Если вы считаете, что ваши 16 коммитов лучше всего представлены 2 коммитами, а не 1 «Добавлена функция X, перефакторинг Z для использования X», тогда, вероятно, было бы неплохо предложить pr с 2 коммитами, но тогда лучше всего предложить 2 отдельных PR в этом случае (если репо все еще настаивает на одном коммитном PR)
Это не идет вразрез с мантрой «заблаговременно и часто», как в вашем репо, когда вы разрабатываете, у вас все еще есть детальные детали, поэтому у вас минимальный шанс потерять работу, и другие люди могут просмотреть / вытащить / предложить PR против вашей работы, пока разрабатывается новый PR.
источник
Основная причина того, что я вижу, заключается в следующем:
Merge pull request #123 from joebloggs/fix-snafoo
--first-parent
точки зрения--first-parent
точки зрения (обратите внимание, что это было исправлено только в Git 2.6.2, поэтому мы могли бы простить GitHub за отсутствие этого доступный)Поэтому, когда вы объединяете все три вышеперечисленные ситуации, вы получаете ситуацию, когда несокращенные коммиты сливаются с помощью пользовательского интерфейса GitHub.
Ваша история с раздавленными коммитами будет выглядеть примерно так
Тогда как без раздавленных коммитов история будет выглядеть примерно так
Когда в отслеживании PR происходит много коммитов, когда произошли изменения, это может стать кошмаром, если вы ограничитесь использованием пользовательского интерфейса GitHub .
Например, вы обнаруживаете, что нулевой указатель разыменовывается где-то в файле ... поэтому вы говорите: «Кто это сделал и когда? На какие версии выпуска влияют?». Затем вы переходите к представлению «вина» в пользовательском интерфейсе GitHub и видите, что линия была изменена в
789fdfffdf
... «о, подождите секунду, в этой строке был изменен отступ, чтобы он соответствовал остальной части кода», так что теперь вам нужно перейти к состоянию дерева для этого файла в родительском коммите и повторно посетить страница с обвинениями ... в конце концов вы находите коммит ... это коммит 6 месяцев назад ... "о **** фактически был в запросе на извлечение и был объединен только вчера, и никто еще не сократил выпуск ... "Черт возьми, люди за объединение коммитов без истории" - это крик, который обычно можно услышать после примерно 2 или 3 экспедиций по археологии кода через GitHub UIТеперь давайте рассмотрим, как это работает, если вы используете командную строку Git (и супер-удивительный 2.6.2, в котором есть исправление
git blame --first-parent
)Таким образом, наша история коммитов будет выглядеть
Но мы также можем сделать
(Другими словами: Git CLI позволяет вам есть свой торт и есть его)
Теперь, когда мы сталкиваемся с проблемой нулевого указателя ... ну, мы просто используем,
git blame --first-parent -w dodgy-file.c
и нам сразу дается точный коммит, где в основной ветке была введена обратная ссылка нулевого указателя, игнорируя простые изменения пробелов.Конечно, если вы выполняете слияния с использованием пользовательского интерфейса GitHub, то
git log --first-parent
это действительно дерьмо благодаря GitHub, форсирующему первую строку сообщения коммита слияния:Короче говоря, короткая история:
Пользовательский интерфейс GitHub (октябрь 2015 г.) имеет ряд недостатков, связанных с тем, как он объединяет запросы на извлечение, как он отображает историю коммитов и как он приписывает информацию об обвинениях. В настоящее время лучший способ обойти эти недостатки в пользовательском интерфейсе GitHub - это попросить людей сдавить свои коммиты перед слиянием.
Git CLI не имеет этих проблем, и вы можете легко выбрать, какое представление вы хотите видеть, так что вы можете узнать причину, по которой было сделано конкретное изменение (просмотрев историю невыполненных коммитов), а также увидеть эффективно подавленные коммиты.
Post Script
Последняя причина, которая часто упоминается для коммитов на сжатие, состоит в том, чтобы упростить бэкпортинг ... если у вас есть только один коммит на бэк-порт (т.е. сдавленный коммит), тогда легко выбрать вишню ...
Ну, если вы смотрите историю git,
git log --first-parent
тогда вы можете просто выбрать коммиты слияния. Большинство людей запутываются в коммитах с вишневым выбором, потому что вы должны указать-m N
опцию, но если вы получили коммит,git log --first-parent
то вы знаете, что это первый родитель, которому вы хотите следовать, поэтому он будетgit cherry-pick -m 1 ...
источник
--first-parent
себя в порядок, чтобы выиграть спор против коммитов на сжатие ;-)Я согласен с мнением, высказанным в других ответах в этой теме, о показе четкой и краткой истории добавленных функций и исправленных ошибок. Я, однако, хотел бы затронуть еще один аспект, к которому ваш вопрос ускользнул, но прямо не указал. Часть зависания, которую вы можете иметь о некоторых методах работы git, заключается в том, что git позволяет вам переписывать историю, что кажется странным, когда вы знакомитесь с git после использования других форм контроля версий, где такие действия невозможны. Кроме того, это также идет вразрез с общепринятым принципом контроля версий, согласно которому после того, как что-то зафиксировано / возвращено в систему контроля версий, вы сможете вернуться в это состояние независимо от того, какие изменения вы вносите после этой фиксации. Как вы подразумеваете в своем вопросе, это одна из тех ситуаций. Я думаю, что git - отличная система контроля версий; однако, чтобы понять это, вы должны понимать некоторые детали реализации и конструктивные решения, лежащие в основе этого, и в результате у него есть более крутая кривая обучения. Имейте в виду, что git задумывался как распределенная система контроля версий, и это поможет объяснить, почему разработчики разрешают переписывать историю git с помощью коммитов сквоша, являющихся одним из примеров этого.
источник
git gc
не был запущен для удаления объектов, на которые нет ссылок .Из-за перспективы ... Лучшей практикой является,
<<issue-management-system>>
если возможно, один коммит на одну проблему.Вы можете иметь столько коммитов, сколько захотите, в своей собственной ветви / репозитории, но это ваша история, относящаяся к тому, что вы делаете сейчас для ВАШЕЙ перспективы ... это не ИСТОРИЯ для всей КОМАНДЫ / ПРОЕКТА или приложения от их перспектива будет сохраняться через несколько месяцев ...
Поэтому, когда вы хотите зафиксировать исправление ошибки или функцию в общем репозитории (этот пример относится к ветке разработки), вы можете сделать это следующим образом:
как быстро перенести вашу ветку
источник
Я бы посмотрел, станет ли код открытым или нет.
Когда проекты остаются частными:
Я бы порекомендовал не тыкать и посмотреть на изготовление колбасы. Если вы используете хорошие и маленькие коммиты, такие инструменты, как git bisect, очень удобны, и люди могут быстро определить регрессивные коммиты и увидеть, почему вы это сделали (из-за сообщения фиксации).
Когда проекты становятся публичными:
Сквош все, потому что некоторые коммиты могут содержать утечки безопасности. Например, пароль, который был зафиксирован и удален снова.
источник