Как вы осуществляете commit в git?
====================================

 Я всегда считал, что в процессе разработки проекта стоит осуществлять один `commit` для одного задания. Этот процесс приблизительно выглядит вот так:  
* Для нового задания создаем новую ветку на основе нашей тематической ветки `git checkout -b new_issue`.
* Осуществляем все `commit` в эту ветку.
* Когда разработка закончена, можно применить `squash` для этих `commit`, сжать их в один и сделать `rebase` в нашу тематическую ветку.
* Если что-то пошло не так, мы можем откатить этот `commit` и все станет по прежнему. Найти баг, исправить его и накатить сверху исправление. (Историю удаленного репозитория мы не изменяем).

  
  

Но возможен и такой подход:  
* Для нового задания создаем новую ветку на основе нашей тематической ветки `git checkout -b new_issue`.
* Осуществляем все `commit` в эту ветку.
* Потом `merge` этой ветки в тематическую ветку с флагом`--no-ff`, в этом случае у нас будет commit-слияние, который, если что-то пошло не так, мы тоже можем откатить, исправить и снова совершить `commit`.
* Но тут у нас есть один плюс, мы можем использовать команду`git bisect` для того, чтобы найти какой именно `commit` поломал все.

  
  
  

Используя подход 1, мы будем иметь хорошую историю в git, `commit` будет атомарной единицей, но при нахождении ошибки нам иногда придется пересмотреть кучу файлов.  
  
  

В подходе 2, мы будем иметь страшную историю, она будет длинной и запутанной, состоять из кучи commit-слияний. Но в этом случае мы сможем использовать магию `git bisect`, что позволит найти баг быстрее. (Возможно этот способ стоит использовать при исправлении legacy кода или рефакторинге).  
  
  

Я понимаю, что возможно, это вопрос больше о персональных предпочтениях, но хотелось бы узнать, какую практику предпочитаете вы? Какие ещё могут быть проблемы при таких подходах? Возможно вы можете предложит что-то другое?  
  
**UPD:** Друзья, предпочитающие делать много коммитов. Вам действительно легче находить баги в таком случае или это только плацебо для вас? Как вам это помогает? Пользуется ли кто-то реально `git bisect`? 

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

 Если над проектом Вы работаете один, то делайте так, как Вам удобнее (мне кажется, в этом случае удобно вести просто прямую линию разработки).   

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

И я не вижу пробел в большой количестве merge — да, история ветвистая, да, ее сложнее понимать какому-то стороннему человеку, зато видно все, и проект может без проблем для разработчиков масштабироваться.   

  

Могу порекомендовать Вам [вот эту статью](http://habrahabr.ru/post/147260/), для осмысления workflow. 

 Предпочитаю второй подход, потому что считаю полезною подробную историю и ясно видные места слияний.  

  

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

  

К числу таких проектов относится, например, [Node](http://nodejs.org/). 

 Пользуемся вторым способом. Если коммитер добросовестный и делал цельные коммиты в своей ветке — работать легко и приятно. Есть и такие, которые сделают один значимый коммит, а потом еще десяток сверху с комментарием fix (где может быть что угодно — от концептуальной доделки до пропущенной точки с запятой). Задавался в свое время аналогичными вопросами «как сделать красивую историю», то к чему пришли сейчас — устраивает совершенно. Чтобы удобнее было расползаться по древу гита, номер таска ставится не только в имя бранча, но и в начало каждого коммит мессаджа. Это реально упрощает жизнь при разборе полетов (и при анализе графа, и при git blame). Чтобы это работало, есть пара хуков — запретительный на пуш и вспомогательный, который подставляет номер таска в редактируемый коммит мессадж. 

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

 Используем второй метод. Таск — ветка, в ней может быть куча коммитов, потом — git merge --no-ff в основной бранч (develop), релизы вливаются в master и тегируются.  

  

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

 Просто коммитим в фичебранчи, а потом мерджим.  

Никакой потери истории, неважно каким инструментом пользоваться для мёрджа — хоть гуи, хоть коммандная строка, бисект работает — что еще надо? 

 Предпочитаю первый, с одним коммитом. 

 Используем первый вариант 

 Я наверное еще не владею гит-кунфу в полной мере, но когда я с git blame ищу кто изменил что-то в некой строке, то я рано сдаюсь когда приходится делать нечто вроде git blame -w abcdef~2^2. А еще порой мне не нужно знать что эта строка преображалась несколько раз во время одного целостного рефакторинга.  

  

Предпочитаю первый подход, и соответственно линейную историю. Имхо семь раз отмерь, один — сквош-смердж.