Обновить

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

Сейчас в народе насколько распространено использование команд git через терминал? Пользовался ими, когда изучал документацию гита. Давно уже всё забыто, поскольку как-то быстро перешёл к использованию средств IDE, а потом на работе lazygit + kdiff3. Часто встречаю утверждения, что тру программист должен рулить гитом только через терминал.

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

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

- разрешение конфликтов,
- просмотр графа репозитория,
- diff по коммитам,
- иногда cherry-pick тоже удобнее из интерфейса дернуть.

Рядовые git add / commit / branch / checkout / merge / rebase - тольки из cli. Благо, что в Jetbrains появились автодополнения названий веток, например. Жаль, что не работают с кастомными баш алиасами (gb = git branch), ну да ладно.

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

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

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

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

P.S. Да не оскорбятся хранители чистоты языка за использование заимствований...

Есть несколько моментов. Допустим, на ветке 15 коммитов и она готова для merge-а. В общем случае, заранее неизвестно будут ли конфликты и в каком объеме. Если история коммитов не важна, то да, можно просто сквошить все 15 коммитов в один большой коммит, и там уже не важно merge или rebase, это будет один и тот же большой конфликт.

Но в большинстве случаев история отдельных коммитов важна, а точнее, их диффы и описание диффов. Однако каждый коммит может привести к отдельному конфликту при rebase. Обычно эти конфликты исправляются вручную по мере продвижения rebase-a, и целью является новый корректный код , что часто приводит к потере оригинального кода. Получается, что описание диффа старое, а код в нем новый, но это является нормой в классическом подходе. Из других минусов по сравнению с merge - нужно больше времени на исправление конфликтов и сложность в оценке суммарной работы.

Смысл данного метода в моментальной оценке работы по исправлению конфликтов и максимальная экономия времени на исправление, это достигается за счет merge-а. При этом сохраняется вся оригинальная история коммитов и оригинальный код, даже если он уже устарел. Это подходит не всем, и тогда нужен обычный rebase.

Обратный дифф не вычисляется, точнее после безусловного ребейза проект полностью заменяется корректным состоянием после сделанного merge-a, поэтому возникает дополнительный коммит. Но его легко убрать, соединив с предыдущим коммитом.

и там уже не важно merge или rebase

Как это не важно? Пока вы делали свою фичу, целевая ветка уже уехала: в неё влили пяток или десяток МРов. Если сделать merge, то история будет нелинейна. Откуда-то из небытия вдруг прилетает ветка. В то время, как все вливания веток должны идти строго друг за другом.

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

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

Утро начинается с ребэйза )

Я имел в виду, что работа по исправлению конфликтов становится одинаковой между merge и rebase в предельном случае, когда в ветке всего один коммит.

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

 Получается, что описание диффа старое, а код в нем новый, но это является нормой в классическом подходе.

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

Смысл данного метода в моментальной оценке работы по исправлению конфликтов и максимальная экономия времени на исправление, это достигается за счет merge-а. При этом сохраняется вся оригинальная история коммитов и оригинальный код, даже если он уже устарел. Это подходит не всем, и тогда нужен обычный rebase.

Вот тут я не понимаю. В чем разница в целях разных ребейзов?

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

А в при необычном ребейзе предложенным способом - что именно содержит моя история до искусственного коммита после ребейза? Оригинальные коммиты нахлобученные на апстрим как есть - тогда это в моменте ломает апстрим. И сохранив историю, мы оставим непредсказуемо поломанные состояния. Другой участник проекта не будет ожидать что коммиты в апстриме могут в какой-то момент нарушить гарантию качества апстрима с восстановлением гарантии где-то позже по истории отдельным коммитом.

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

Допустим, общая ветка (upstream) это develop, есть три варианта насколько строго требовать корректность коммитов в репозитории на сервере:

  1. develop должен быть корректным в любой момент времени.

  2. develop + feature ветки должны быть корректными в любой момент времени.

  3. все коммиты в истории всех веток должны быть корректными.

Первый вариант наиболее распространенный, дает больше свободы разработчикам и меньше давит на них.

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

Третий вариант самый строгий. В общем он естественный если только делать merge. Но в случае rebase всегда гарантировать синтаксическую и логическую корректность каждого rebase-нутого коммита становится очень сложно.

Мой метод rebase-а подходит для 1 и 2 вариантов: upstream всегда рабочий, все мерджи в upstream несут только корректный дифф, feature ветки тоже корректны в любой момент времени (можно сбилдить и протестировать).

Минус моего метода в том, что если сделать checkout какого-то промежуточного коммита, то он может не сбилдится, то есть 3 вариант отпадает. Только как правило в этом нет необходимости.

Понял, спасибо.

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

Я больше 10 лет работаю с гит исключительно в терминале. И на моей памяти от рибейса больше проблем потому что всегда кто-то умудряется похерить историю. Рибейс подразумевает форс пуш и это громадный минус.

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

Деыолтный конфиг, ff true, merge true, ort стратегия, минимум конфликтов, минимум резолвов при повторных синках.

На ттм надо ориентироваться в таких вещах с нашими инструментами.

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

И я согласен, что rebase требует большей квалификации и понимания, чем merge. И что rebase противоречит оригинальной идеологии git, что все коммиты должны быть иммутабельны.

Я бы конечно постарался обратить команду) но безусловно в присутствии таких противоречий , инструмент полезный, и тема важная и и статья хорошая, за что вам спасибо.

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

Публикации