Как стать автором
Обновить

Комментарии 89

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

Если мне гит не нравится, то только из этой его способностью причесывать историю коммитов. Не надо так делать. Это плохая практика. История, она уже случилась. Гораздо полезнее, если история никак не меняется. Из-за этого я и использую fossil – если надо выбирать между правдой и эстетикой, я выбираю правду.

А как быть, если залил какой-то токен или пароль? (Реально интересно, т.к. о fossil ничего не слышал до этого)

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

Вот, есть статья в документации как следует поступать: Deleting Content From Fossil. Но там это считается ЧП и не так уж и легко сделать. Но можно, если совсем уж никуда.

А вот, токены и пароли надо просто менять если они засветились. Даже если и возможно их удалить из репозитория и вы их удалили, они уже скомпрометированные.

Причёсывать master — да, не надо. Причесать ветку перед пулреквестом — почему нет?

Неужели кто то на ревью обращает внимание на то, из каких коммитов складываются финальные изменения?

Если использовать поиск по истории - то commit message это довольна важная штука.

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

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

В истории мастера будет один коммит с детальным описанием фичи. Если недостаточно - останется локальный бранч с коммит мессаджем на каждый fixed typo in ...

Это если при принятии PR коммиты сквошатся. Что тоже является разновидностью переписывания истории.

При этом процессе вы создаёте "копию" изменений в другой ветке, реальная истрория остаётся на месте. Это больше похоже на cherry-pick.

Я не хочу чтобы в истории мастера были всякие "fix", "fix 2" и т.п. А сквошить весь пулл реквест в один коммит не всегда правильно.

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

Если вы о том что в коде очень много изменений, то мой ответ - с трудом.

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

PS Если отдельное изменение пару в строчек несёт какой то смысл (типа такого) - оно заслуживает отдельного review и коммита в мастер.

Если оно будет оформленно отдельной задачей - так и будет.

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

В теории стоит создать множество ревью.

Но я пока не видел удобного инструмента, как всё это обновлять когда есть комментарии к первому комиту. Ну и билды на CI запускаются сильно чаще.

Обычно делается review конкретной задачи, и очень часто в ней делается много изменений.

Конечно же было бы удобно несвязанные изменения выносить в отдельную задачу делать review отдельно, но не всегда это удается.

Например из-за того что продукт может быть не очень доволен тем что делая бизнес задачу я буду создавать множество побочных )

Если у вас проект на пару разрабов и не публичный - не надо.
Если у вас десяток разработчиков, внешние пользователи и все такое - безусловно. Вы прям таки хотите при случае разбираться в "fix", "fixed", "lol", "d", "review", "typo" и еще сотнях других абсолютно неинформативных коммитах? Я - нет.
Поэтому коммиты должны сопровождаться понятными и полезными комментами. А если их еще и не много - то вообще супер.

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

Но нет информации о том, что код в мастер попал именно из вашей ветки. И если вы свою ветку продолжите - при попытке сделать ещё один PR полезут конфликты.

Не надо продолжать. По хорошему надо автоматом делать ветку read-only после мёрджа с мастером, я просто сразу делаю новый бранч.

А откуда код попал в мастер - уже неважно, он должен быть самодостаточным для того, чтобы понять и развивать дальше.

А как быть тем, кто вынужден продолжать работу над новыми фичами, которые зависят от непринятого PR?

Так пока PR не принят, ветка не замёрджена. И по факту как то всегда находились независимые задачи - пока код на ревью, в этой части только фиксы согласно комментариям, основная работа над чем то другим.

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

Да, у меня гораздо больше времени проходит на обдумывание/эксперименты (и прочие задачи типа рисования слайдов), чем на написание кода. Возможно, если надо выдавать код тысячами строк, ситуация другая.

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

Есть разные трюки как, это упростить возвращения к задаче.

Маленькие ревью.
Хорошие описания.
Наличие тестов.
Автоматические проверки кода.

Все эти шаги могут уменьшить количество итераций. И упростят востановление контеста.

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

У меня много ревью проходят с первого раза. Обычно к мементу, когда я выкатываю фичу, у меня уже 5-10 мелких ревью замердженно

И вы работу над каждой фичей останавливаете по 5-10 раз в ожидании этого самого пройденного ревью?.. Сколько это времени занимает и как вообще такое терпят?

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

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

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

Иногда продолжаю, но чаще нет.

Обычно выделяю изменения которые я хочу замерджить в отдельную ветку (коприрую руками, cherry-pick, patch, git checkout branch -- <file> ). Ветка с фичей при этом остаётся не пушнутой.

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

А как быть тем, кто вынужден продолжать работу над новыми фичами, которые зависят от непринятого PR?

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

Как это влияет? Вы в нём попадаете на такой «промежуточный» коммит, а он не собирается. Фсё! :)

Если вы считаете полезным причесать свою ветку перед пулреквестом, то почему отказываете главному майнтайнеру в его право причесывать свою ветку, «master»?

Как минимум потому, что в средних и крупных командах в разные периоды времени разработчики "отпочковываются" от мастера и пилят таску в своей ветке. Если начать шатать мастер -- MR с обычными конфликтами слияния покажутся детским лепетом.

Но это как означает, что ветки нужно причесывать? А если не нужно но «можно», то зачем?

Тут очень просто понять, в каких случаях можно "причесывать", а в каких -- нельзя: просто представить к чему приведет классический форс-пуш в ветку, в которую "прихорашиваем".

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

Ну собсна потому же почему обычно мастер и дев ветки протектед. Если ты забыл лог убрать это одно дело, а если ты хочешь причесать сожрав какой нить хотфикс другое

Но соглашусь что в целом любое изменение истории комитетов такое себе. Но тут как бы все на уровне договоренности

Потому, что причёсывать shared branch как минимум технически чревато. Ну и менять достояние общественности, в принципе, тоже нелепо. А личное, пока оно не общее, почему нет?

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

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

В итоге просто сделал патчи и сделал новые ветки руками. Так-себе опыт.

только из этой его способностью причесывать историю коммитов. Не надо так делать.

Ну так это не обязательно же. Можно и не делать, если не нравится.

Это хорошая практика. Речь идет о локальной истории. До того, как ты сделал пуш, ты волен делать с локальными коммитами все, что угодно. И эта гибкость как раз полезна, потому как позволяет тебе чаще коммитить, фиксируя некоторые промежуточные успехи. А потом уже, по окончании смыслового куска работы, это все вдумчиво ребейзится, раскладываясь по тематическим коммитам "набело" и пушится.

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

Чтобы иметь возможность откатить часть изменений если в процессе работы что-то пошло не так.

Иногда за одной строчкой стоит какая то мысль, не хочется чтобы потерялось - так что лучше сразу git commit/git push, чтобы осталось в локальной ветке и реплицировалось на другие сервера.

Когда я написал статью с аналогичным смыслом мне влепили 50 минусов.

Про fixup слышу первый раз, думаю эта фишка не давно появилась. Идея красивая, все камиты с почеркушками слепляем в один камит вместе с камитом где мы эти почеркушки стерли. И всё шито крыто 👍

И судя по примеру результат такой же. Ладно бы hash оставался тем же, так нет.

Ну hash не может оставаться тем же - даже если просто сделать --amend без изменений (т.е. не изменяя контрольную сумму файлов) и под тем же пользователем, он все равно пересчитается.

Поэкспериментировав, добиться повторения хэша не получилось даже с пустым коммитом (--allow-empty), пустым сообщением (-m '' --allow-empty-message) и фиксированной датой (--date=$some_date) - видимо для подсчета хэша помимо файлов, автора, подписи, сообщения и даты есть еще какая-то соль

Время коммита («commiter date»), как минимум — оно отлично от времени создания коммита («author date») и на него не всегда легко повлиять вручную.

Вот тут можно почитать подробнее: https://stackoverflow.com/q/35430584

--amend --no-edit вы ж к последнему коммиту применяете. В примере мы меняем не последний коммит.

Да, к последнему

Если не к последнему, то обычно делаю коммит что-то вроде "fix" и интерактивным ребейзом его перемещаю, ставя fixup. Таким образом получается то же самое что и в примере, но без необходимости искать хэш нужного коммита через log.

Кажется что это все вопросы удобства - there are many ways to do this

Так вам же всё равно придётся его искать, только во время ребейза.

Ну и в GUI нет ничего проще чем указать коммит для fixup

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

GUI не пользуюсь, максимум lazygit если надо глубоко в историю зарыться, но это прям редкость

В любом случает - это все вопросы удобства и привыки

Так всё равно же ветка в истории останется, мы-то с вами про имидж говорим тут.

А зачем она?

Я их сразу удаляю (через опицию автоудаления при мердже) на сервере. И руками локально.

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

Я тоже удаляю. Напомню, что мы говорим о Git — распределённой VCS. Ничто не удаляется поистине.

Насколько я знаю refs удаляются вполне нормально. Ну а коммиты не привязанные ни к какому refs ужадить gc. Зависит от настроек сервера, но скорее всего он там есть.

Мы как-то забыли добавить репозиторий в автоматическую очистку. За сколько-то лет (может и за 10) история вырасла на один гигабайт. Сам репозиторий меньше мегабайта.

Я их сразу удаляю

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

Типа сделали фичу, не зашло, удалили, добавили новую фичу в одной ветке. А потом вернулись посмотреть на промежуточный результат? Если я буду оставлять все свои ветки, то я точно в них ничего не найду. Я бы наврено интерестные эксперименты сохранил в отдельной ветке. Может быть даже пушнул в draft review.

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

Промежуточной локальной истории просто нет.

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

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

Есть возможность пушнуть черновик, который вижу только я.

Выглядит так, что проще исследовать/девелопить на одной локальной ветке, с неё со сквошем кидать в другую, когда появляется окончательный вариант, и уже оттуда пушить.

Да, все ребейзы и магия до того как пушить изменения на ревью (GitHub, GitLab).

В моём случае других веток обычно несколько и часть из них мерджится раньше чем фича закончена.

Что вы делаете с локальной историей, не важно, но когда пушнули, то уже не трогайте.

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

Ну так ведь так делают обычно у лидов, которые прямо вот как будто неудовлетворённые вечно и создают проблемы в работе вместо советов по улучшению :))))) ребейс, форс-пуш, а дальше пусть сам вспоминает, что он там писал неделю назад.

Скрытый текст

Кажется, я спалил контору...

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

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

Скрытый текст

Кажется, я спалил контору...


Если на проекте настроить автоформатирование кода, линтеры и проверку орфографии (codespell), то придираться к коду станет намного сложнее.

Будет много комментариев от CI и прекомит хуков, но они вполне по делу и легко правятся.

Даже если вы не тимлид своего проекта, вы можете внедрить это. Я уже не первый раз, даю такие советы и у людей это получалось.

например на сложное ревью можно делать вместе, а не кидаться комментами

Простите, wat?

Gitlab успешно сохраняет привязку всех тредов даже после форс-пуша, мы всегда использовали в воркфлоу оные благодаря этому.

Команда git rebase -i --autosquash делает всю грязную работу: находит fixup-коммиты и запихивает их обратно в родительский коммит, словно ничего и не происходило.

Если бы ещё изменения апдейтов не отображались отдельно в Team Foundation services (Azure Devops) для каждой ветки по каждому пулл-реквесту, вообще бы цены не было у этих команд)...

Данные платформы записывают ваши действия в пулл-реквестах и изменения даже в том случае, если вы сделали git reset —hard до комммита и пропушили...

Я работаю с Gerrit. Там вообще одно ревью один коммит. Локально я постоянно историю переписываю. Так же как и Team Foundation, Gerrit хранить каждый пуш и можно по версиям переключаться и локально выкачать любую.

Требуется некоторые время на привыкание, но в общем удобно.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации