Почему squash git фиксирует запросы на pull?

Почему каждый серьезный репозиторий Github я тяну запросы на то, что я хочу, чтобы я выкалывал свои коммиты в единую фиксацию?

Я думал, что журнал git был там, чтобы вы могли проверить всю свою историю и посмотреть, какие изменения произошли там, но раздавив ее, вытащил ее из истории и купил все это на одно коммит. В чем смысл?

Это также, похоже, идет вразрез с мантой «совершать раннее и совершать».

147 голосов | спросил hamstar 19 32014vEurope/Moscow11bEurope/MoscowWed, 19 Nov 2014 01:41:50 +0300 2014, 01:41:50

5 ответов


125

Итак, у вас есть четкая и краткая история git, которая четко и легко документирует сделанные изменения и причины.

Например, типичный «unsquashed» git log для меня может выглядеть следующим образом:

7hgf8978g9... Added new slideshow feature, JIRA # 848394839
85493g2458... Fixed slideshow display issue in ie
gh354354gh... wip, done for the week
789fdfffdf... minor alignment issue
787g8fgf78... hotfix for #5849564648
9080gf6567... implemented feature # 65896859
gh34839843... minor fix (typo) for 3rd test

Какой беспорядок!

В то время как более тщательно управляемый и объединенный журнал git с небольшим дополнительным фокусом на сообщения для этого может выглядеть так:

7hgf8978g9... 8483948393 Added new slideshow feature
787g8fgf78... 5849564648 Hotfix for android display issue
9080gf6567... 6589685988 Implemented pop-up to select language

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

Вы хотите совершать ранние и часто. Это лучшая практика по многим причинам. Я нахожу, что это приводит к тому, что у меня часто возникают коммиты, которые являются «wip» (незавершенное производство) или «часть A done» или «typo, minor fix», где я использую git, чтобы помочь мне работать и дать мне рабочие точки, которые Я могу вернуться к этому, если следующий код не работает, когда я продвигаюсь, чтобы заставить все работать. Однако мне не нужна эта история или она не нужна в финальной истории Git, поэтому я могу раздавить свои коммиты, но см. Примечания ниже о том, что это означает в ветке развития против хозяина.

Если есть основные этапы, которые представляют собой различные рабочие этапы, все равно можно использовать несколько коммитов для каждой функции /задачи /ошибки. Однако это может часто подчеркивать тот факт, что разрабатываемый билет «слишком велик» и его нужно разбить на более мелкие части, которые могут быть автономными, например:

8754390gf87... Implement feature switches

кажется «1 часть работы». Либо они существуют, либо нет! Кажется, не имеет смысла разоблачать. Однако опыт показал мне, что (в зависимости от организационного размера и сложности) более гранулированный путь может быть:

fgfd7897899... Add field to database, add indexes and a trigger for the dw group
9458947548g... Add 'backend' code in controller for when id is passed in url.
6256ac24426... Add 'backend' code to make field available for views.
402c476edf6... Add feature to UI

Маленькие кусочки означают более легкие обзоры кода, более легкое модульное тестирование, лучшую возможность qa, лучшее совмещение с принципом единой ответственности и т. д.

Для практичности того, когда на самом деле делать такие сквош, есть в основном два разных этапа, которые имеют свой собственный рабочий процесс

  • ваше развитие, например. тянуть запросы
  • ваша работа добавлена ​​в ветвь mainline, например. мастер литий>

Во время вашего развития вы совершаете «ранние и часто» и с быстрыми «одноразовыми» сообщениями. Возможно, вы захотите иногда сквош здесь, например. раздача сообщений в wip и todo. Внутри филиала нормально поддерживать несколько коммитов, которые представляют собой различные шаги, которые вы сделали в процессе разработки. Большинство кабачков, которые вы выбираете, должны находиться в этих ветвях признаков, пока они разрабатываются и до слияния для освоения.
При добавлении в ветвь mainline вы хотите, чтобы коммиты были краткими и правильно отформатированы в соответствии с существующей историей магистрали. Это может включать идентификатор системы Ticket Tracker, например. JIRA, как показано в примерах. Скриптинг действительно не применяется здесь, если вы не хотите «свертывать» несколько отличных коммитов на хозяине. Обычно вы этого не делаете.

Используя --no-ff, когда слияние с мастером будет использовать одно коммит для слияния, а также сохранить историю (в ветке). Некоторые организации считают это лучшей практикой. Подробнее см. https://stackoverflow.com/q/9069061/631619 . Вы также увидите практический эффект в git log, где фиксация --no-ff будет последней фиксацией вверху HEAD (когда это будет сделано), тогда как без --no-ff он может быть еще ниже в истории, в зависимости от дат и других коммитов.

ответил Michael Durrant 19 32014vEurope/Moscow11bEurope/MoscowWed, 19 Nov 2014 03:26:01 +0300 2014, 03:26:01
20

Потому что часто человек, занимающийся PR, заботится о сетевом эффекте коммитов «добавлена ​​функция X», а не о «базовых шаблонах, функции исправления ошибок X», добавляет функцию Y, фиксированные опечатки в комментариях, скорректированные параметры масштабирования данных, hashmap выполняет лучше, чем список "... уровень детализации

Если вы считаете, что ваши 16 коммитов лучше всего представлены 2 коммитами, а не 1 «Добавлена ​​функция X, переопределенная Z для использования X», то это, вероятно, прекрасно, чтобы предложить pr с 2 коммитами, но тогда это может быть лучше всего предложить 2 отдельных pr в этом случае (если репо все еще настаивает на одиночном фиксации pr)

Это не идет вразрез с мантой «совершать на ранней стадии и совершать», как в вашем репо, пока вы развиваетесь, у вас все еще есть детализированные детали, поэтому у вас есть минимальный шанс потерять работу, а другие люди могут просмотреть /вытягивать /предлагать pr против вашей работы, пока разрабатывается новый pr.

ответил Andrew Hill 19 32014vEurope/Moscow11bEurope/MoscowWed, 19 Nov 2014 02:25:56 +0300 2014, 02:25:56
10

Основная причина в том, что я вижу:

  • Пользовательский интерфейс GitHub для слияния запросов на тягу в настоящее время (октябрь 2015 г.) не позволяет вам редактировать первую строку сообщения фиксации, заставляя ее быть Merge pull request #123 from joebloggs/fix-snafoo
  • Пользовательский интерфейс GitHub для просмотра истории фиксации в настоящее время не позволяет просматривать историю ветки с точки зрения --first-parent
  • Пользовательский интерфейс GitHub для просмотра вины в файле в настоящее время не позволяет вам увидеть вину файла с точкой зрения --first-parent (обратите внимание, что это было исправлено в Git 2.6.2, так что мы могли бы простить GitHub за то, что у вас это не было)

Итак, когда вы объединяете все три вышеуказанные ситуации, вы получаете ситуацию, когда недочетные коммиты сливаются, выглядят уродливыми из пользовательского интерфейса GitHub.

Ваша история с раздавленными коммитами будет выглядеть примерно как

1256556316... Merge pull request #423 from jrandom/add-slideshows
7hgf8978g9... Added new slideshow feature
56556316ad... Merge pull request #324 from ahacker/fix-android-display
787g8fgf78... Hotfix for android display issue
f56556316e... Merge pull request #28 from somwhere/select-lang-popup
9080gf6567... Implemented pop-up to select language

В то время как без раздавленных записей история будет выглядеть примерно как

1256556316... Merge pull request #423 from jrandom/add-slideshows
7hgf8978g9... Added new slideshow feature, JIRA # 848394839
85493g2458... Fixed slideshow display issue in ie
gh354354gh... wip, done for the week
789fdfffdf... minor alignment issue
56556316ad... Merge pull request #324 from ahacker/fix-android-display
787g8fgf78... hotfix for #5849564648
f56556316e... Merge pull request #28 from somwhere/select-lang-popup
9080gf6567... implemented feature # 65896859
gh34839843... minor fix (typo) for 3rd test

Когда у вас много компромиссов в трассировке PR, в которой произошло изменение, может стать немного кошмаром , если вы ограничитесь использованием интерфейса GitHub .

Например, вы обнаруживаете, что нулевой указатель находится где-то в файле где-то в файле ... поэтому вы говорите: «Кто это сделал, и когда? какие версии версий затронуты?». Затем вы переходите к представлению о вине в пользовательском интерфейсе GitHub, и вы видите, что строка была изменена в 789fdfffdf ... ", но подождите секунду, эта строка просто изменила свой отступ, чтобы вписаться в с остальной частью кода ", поэтому теперь вам нужно перейти к состоянию дерева для этого файла в родительском коммите и повторно посетить страницу вины ... в конце концов вы найдете фиксацию ... это фиксация от 6 месяцев назад ... «Ох ****, это может повлиять на пользователей в течение 6 месяцев», вы говорите ... ах, но ждите, что фиксация действительно была в запросе Pull и была только слита вчера, и никто еще не отключил выпуск ... «Черт побери, вы, люди для слияния, не разрушая историю» - это крик, который обычно можно услышать после двух или трех экспедиций археологии кода через интерфейс пользователя GitHub

Теперь рассмотрим, как это работает, если вы используете командную строку Git (и супер-awesome 2.6.2, которая имеет исправление для git blame --first-parent)

  • Если вы используете командную строку Git, вы сможете полностью контролировать сообщение о фиксации слияния, и, таким образом, фиксация слияния может иметь хорошую итоговую строку.

Итак, наша история фиксации будет выглядеть как

$ git log
1256556316... #423 Added new slideshow feature
7hgf8978g9... Added new slideshow feature, JIRA # 848394839
85493g2458... Fixed slideshow display issue in ie
gh354354gh... wip, done for the week
789fdfffdf... minor alignment issue
56556316ad... #324 Hotfix for android display issue
787g8fgf78... hotfix for #5849564648
f56556316e... #28 Implemented pop-up to select language
9080gf6567... implemented feature # 65896859
gh34839843... minor fix (typo) for 3rd test

Но мы также можем сделать

$ git log --first-parent
1256556316... #423 Added new slideshow feature
56556316ad... #324 Hotfix for android display issue
f56556316e... #28 Implemented pop-up to select language

(Другими словами: Git CLI позволяет вам иметь торт и есть его тоже)

Теперь, когда мы сталкиваемся с проблемой нулевого указателя ... ну, мы просто используем git blame --first-parent -w dodgy-file.c, и нам немедленно дается точное коммитирование, где null указатель de-reference был введен в мастер-ветку, игнорируя простые изменения пробелов.

Конечно, если вы делаете слияния с использованием интерфейса GitHub, тогда git log --first-parent действительно дерьмова, благодаря GitHub, заставляющему первую строку сообщения слияния:

1256556316... Merge pull request #423 from jrandom/add-slideshows
56556316ad... Merge pull request #324 from ahacker/fix-android-display
f56556316e... Merge pull request #28 from somwhere/select-lang-popup

Итак, чтобы сократить длинную историю:

Интерфейс GitHub (октябрь2015) имеет ряд недостатков в том, как он объединяет запросы на тяну, как он представляет историю фиксации и как она атрибутизирует информацию обвинений. Нынешний лучший способ взломать эти недостатки в интерфейсе GitHub - попросить людей раздавить свои коммиты до слияния.

В Git CLI нет этих проблем, и вы можете легко выбрать, какой вид вы хотите увидеть, чтобы вы могли обнаружить причину, по которой было сделано определенное изменение (просмотрев историю неудачных коммитов) а также увидеть эффективно раздавленные коммиты.

Post Script

Конечная причина, часто приводимая для компрометации компромиссов, заключается в том, чтобы упростить backporting ... если у вас есть только один фиксатор для обратного порта (т. е. сжатый фиксатор), тогда легко вишневый выбор ...

Хорошо, если вы смотрите на историю git с помощью git log --first-parent, тогда вы можете просто выбрать вишню, чтобы зафиксировать слияние. Большинство людей сбивают с толку коммиты слияния вишни, потому что вам нужно указать опцию -m N , но , если вы получили фиксацию из git log --first-parent, то вы знаете, что это первый родитель, за которым вы хотите следовать, поэтому он будет git cherry-pick -m 1 ...

ответил Stephen Connolly 20 +03002015-10-20T12:18:18+03:00312015bEurope/MoscowTue, 20 Oct 2015 12:18:18 +0300 2015, 12:18:18
0

Я согласен с чувствами, выраженными в других ответах в этой теме, о том, чтобы показать четкую и краткую историю добавленных функций и исправлены ошибки. Однако я хотел бы обратиться к другому аспекту, который ваш вопрос ускользал, но явно не указал. Часть зависания, которую вы можете иметь о некоторых методах работы git, заключается в том, что git позволяет переписать историю, которая кажется странной при введении в git после использования других форм управления версиями, где такие действия невозможны. Кроме того, это также противоречит общепринятому принципу управления версиями, который, когда что-то совершается /проверяется на исходный контроль, вы должны иметь возможность вернуться к этому состоянию независимо от того, какие изменения вы сделаете после этого фиксации. Как вы подразумеваете в своем вопросе, это одна из таких ситуаций. Я думаю, что git - отличная система управления версиями; однако, чтобы понять это, вы должны понимать некоторые детали реализации и проектные решения, стоящие за ним, и в результате он имеет более крутую кривую обучения. Имейте в виду, что git предназначался для системы управления распределенной версией, и это поможет объяснить, почему дизайнеры позволяют переписывать историю git с помощью комков сквоша, являющихся одним из примеров этого.

ответил Fred Thomsen 22 62014vEurope/Moscow11bEurope/MoscowSat, 22 Nov 2014 23:21:14 +0300 2014, 23:21:14
0

Из-за перспективы ... Лучшая практика заключается в том, чтобы, если это было возможно, иметь единую фиксацию на одну проблему <<issue-management-system>>.

У вас может быть столько коммитов, сколько вы хотите, в своей собственной ветке /репозиции функций, но ваша история важна для того, что вы делаете сейчас для ВАШЕЙ перспективы ... это не он ИСТОРИЯ для всей КОМАНДЫ /ПРОЕКТА или приложение с их точки зрения, которое будет храниться через несколько месяцев ...

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

инструкции по быстрому обновлению ветки функций

    # set your current branch , make a backup of it , caveat minute precision
    curr_branch=$(git rev-parse --abbrev-ref HEAD); git branch "$curr_branch"--$(date "+%Y%m%d_%H%M"); git branch -a | grep $curr_branch | sort -nr

    # squash all your changes at once 
    git reset $(git merge-base develop $curr_branch)

    # check the modified files to add 
    git status

    # add the modified files dir by dir, or file by file or all as shown
    git add --all 

    # check once again 
    git log --format='%h %ai %an %m%m %s'  | less

    # add the single message of your commit for the stuff you did 
    git commit -m "<<MY-ISSUE-ID>>: add my very important feature"

    # check once again 
    git log --format='%h %ai %an %m%m %s'  | less

    # make a backup once again , use seconds precision if you were too fast ... 
    curr_branch=$(git rev-parse --abbrev-ref HEAD); git branch "$curr_branch"--$(date "+%Y%m%d_%H%M"); git branch -a | grep $curr_branch | sort -nr

    # compare the old backup with the new backup , should not have any differences 
    git diff <<old-backup>>..<<new-backup-branch>>


    # you would have to git push force to your feature branch 
    git push --force 
ответил Yordan Georgiev 10 PMpTue, 10 Apr 2018 12:14:08 +030014Tuesday 2018, 12:14:08

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132