LINUX.ORG.RU

Git: помогите освоить rebase

 ,


0

1

Сначала схема (стеклянного шара) к теме:

A=https://github.com/void-linux/void-packages
# master-------------------------------------------------|------>
#                                                        |
B=https://github.com/onlylunix/void-packages (FORK)      |
# master        25277 commits behind                     |>
# firebird3upd  1 commit ahead of, 25277 commits behind  |->

C=localhost
$ git config --get remote.origin.url
git@github.com:onlylunix/void-packages.git
Давным-давно из ветки firebird3upd создал Pull request #46672 И вот сейчас эта ветка конфликтует https://ibb.co/FLS3TdM3

Знаю в каком файле конфликт, но не понимаю как действовать дальше ЧТОБЫ НЕ ЗАКРЫЛСЯ Pull request #46672
Спрашиваю потому, что, на github.com уже ругали, и теперь боюсь те кнопки нажимать в их web-интерфейсе (далее WEB), т.к. всё ломается и PR-ы приходится закрывать и создавать новые.

С опаской предполагаю варианты действий:

Вариант 1:
В WEB кнопкой [Sync fork] обновляю ветку B:firebird3upd до A:master. При этом будет конфликт. В WEB редактирую конфликтный файл (Есть такой функционал?).
На localhost выполняю: git pull, что загрузит изменения Sync-нутые и сделанные в WEB при решении конфликта.

Вариант 2:
В WEB кнопкой [Sync fork] обновляю ветку B:firebird3upd до A:master. При этом будет конфликт. Ничего не редактирую.
На localhost выполняю:
git checkout firebird3upd
git fetch
nano 'конфликтный файл' # редактирую 'конфликтный файл'
git add 'конфликтный файл'
git commit --amend --no-edit
git push --force
Вариант 3:
Все действия на localhost-е:
git checkout firebird3upd
git pull --rebase upstream master
nano 'конфликтный файл' # редактирую 'конфликтный файл'
git add 'конфликтный файл'
git commit
git push --force
Повторю что ВАЖНО ЧТОБЫ НЕ ЗАКРЫЛСЯ PR #46672
Прошу помощи!

Эпилог: Git: помогите освоить rebase (комментарий) ...

★★★★★

Последнее исправление: superuser (всего исправлений: 15)
Ответ на: комментарий от annulen

PR это не публичная история, его можно и нужно редактировать

Похоже, мы с тобой смотрим в разные толковые словари и по-разному понимаем слово «публичный».

чтобы в публичной истории не было мусора

История это не мусор. Это раз. Но для такого случая у Гитхаба можно делать squash merge при слиянии ПР. Хоть, я и против такого, но очень часто его встречаю на работе.

В github, в отличие от, скажем, gerrit, pr нельзя обновить без force --push

Ты имел ввиду, в Gerrit нельзя без --force? Потому как в Github это делается легко.
У Гугла другие масштабы, там монорепа с миллионами коммитов в секунду. Возможно, этим продиктовано.

https://yarchive.net/comp/linux/git_rebase.html

In other words, you really shouldn't rebase stuff that has been exposed
anywhere outside of your own private tree. But *within* your own private
tree, and within the commits that have never seen the light of day,
rebasing is fine.


Линус тоже так считает.

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

urxvt ★★★★★
()
Ответ на: комментарий от Chiffchaff

Теоретически, да. На практике, в команде, очень маловероятно, что кто-то стянет твой ПР до того, как он проревьюен и смержен.

На моей регулярно.
0. Люди стягивают код с ПР чтобы просматривать его локально, в ИДЕ а не только в ГХ морде.
1. Кто-то не доделал работу и заболел, другой добавляет туда коммит и вливают ПР не дожидаясь автора ПР.
2. Вот прямо сейчас, коллега делает свою работу на основе ветки моего (ещё не влитого) ПР.

С rebase история будет выглядеть красивее и понятнее.

Возможно, красивей. Допустим. Но история не про красоту а про историю. Чтобы она была красивой достаточно не оглавлять коммиты «some fixes». Я уже писал выше, какие проблемы привносит эта красивая история.

urxvt ★★★★★
()
Ответ на: комментарий от ergo

Так конфликты в любом случае будут в командной разработке. Хоть merge используй, хоть rebase - от этого не зависит.

Чтобы не было конфликтов, пытаются придумать VCS на других основах: darcs, pijul. Не знаю, как там у них выходит.

Chiffchaff
()
Ответ на: комментарий от urxvt

С merge конфликтов меньше.

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

ergo ★★★
()
Ответ на: комментарий от static_lab

Но он же не делает push –force. Просто история в trunk-ветке становится более атомарной.

вы реально не знаете что на самом делает git merge --squash и как то же самое сделать другими командами? а git commit --amend - это тоже из разряда черной магии или как?

borisych ★★★★★
()
Ответ на: комментарий от urxvt

Так они упоротые, если разрешают только 1 коммит в ПР.

там у ТС изначально идея про то, что вот в этот void linux залить рецепты по сборке какого-то пакета, откуда там должно взяться более одного коммита-то? В одном коммите нужно написать эссе почему я решил добавить новый пакет, а в другом это самое добавление осуществить? Такая тема канает разве что в разработке и то не всегда: сначала добавляем провальные тесты - все видят, что они красные, потом с гордостью их чиним.

Мейнтейнер апстрима указал в каком виде он хочет видеть ПР - извольте соблюдать правила.

borisych ★★★★★
()
Ответ на: комментарий от borisych

вы реально не знаете что на самом делает git merge –squash и как то же самое сделать другими командами?

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

static_lab ★★★★★
()
Ответ на: комментарий от max_lapshin

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

В современной быстрой веб разработке оно неудобно, да.

masa ★★
()
Ответ на: комментарий от masa

Думаю, что даже в «серьёзных» приложениях (в т.ч. и больших веб-приложениях) в большинстве случаев это упрощённый git flow: есть некоторая trunk-ветка (master, develop), в которую вливаются фичи и багфиксы, и от которой периодически отделяются релизные ветки. То есть просто нет всегда стабильной ветки master.

static_lab ★★★★★
()
Ответ на: комментарий от masa

Давай слово «серьезный», особенно в применении к банковским приложениям уберем, как эмоции и заведомое манипулирование. «Всё плотно протестировать» - это вопрос к организации тестов. Если контора отсталая и там только ручные тесты, то им ничего не поможет. Если тесты делает робот, то гонять можно много раз в день.

Как откладывание мержа в мастер и увеличение импакта помогает работе? Ведь средний банковский разработчик - это не то чтобы очень вовлеченный человек, ему бы мастер в голове удержать, как он может 10 веток удерживать?

max_lapshin ★★★★★
()
Ответ на: комментарий от max_lapshin

Как откладывание мержа в мастер и увеличение импакта помогает работе? Ведь средний банковский разработчик - это не то чтобы очень вовлеченный человек, ему бы мастер в голове удержать, как он может 10 веток удерживать?

Там не так на самом деле: разработчик сделал свою фичу, её протестировали и влили в транк, а перед релизом всё ещё раз тестируется на отдельных стендах со всеми подготовленными релизными версиями бекендных компонентов.

static_lab ★★★★★
()
Ответ на: комментарий от max_lapshin

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

masa ★★
()
Ответ на: комментарий от max_lapshin

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

masa ★★
()
Ответ на: комментарий от borisych

откуда там должно взяться более одного коммита-то?

Да хоть новая версия пакета вышла пока ПР висел и теперь ее нужно в этом же ПР обновить.

Такая тема канает разве что в разработке и то не всегда: сначала добавляем провальные тесты - все видят, что они красные, потом с гордостью их чиним.

А тут не понял. При разработке ПРы чуть менее чем всегда дорабатываются в процессе code review.

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

При разработке ПРы чуть менее чем всегда дорабатываются в процессе code review.

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

borisych ★★★★★
()
Ответ на: комментарий от urxvt

Надо всегда делать rebase. Иначе история проекта превращается в нечитаемую лапшу, в которой никто никогда не сможет разобраться. История должна быть линейная. Либо просто добавлять все pull request-ы через fast-forward или squash. Либо делать один merge коммит в главную ветку, а рядом подвязывать оригинальную историю коммитов параллельной веткой.

--force использовать нежелательно для main ветки. Для других веток - можно. Над веткой работает один разработчик и делает с веткой что хочет.

vbr ★★★★★
()
Ответ на: комментарий от vbr

История должна отображать то, что происходило. Если задачу пилили в отдельной ветке месяц и по ходу дела менялось и ее понимание и требования то это должно отображаться в истории. А линейная ничего из этого не отображает.

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

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

Оно обычно также остаётся в системе, через которую ставятся задачи. У нас, например, изменение требований обязательно должно было отображаться в жире. По коммитам это всё равно затруднительно понять.

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

Chiffchaff
()
Ответ на: комментарий от Chiffchaff

Оно обычно также остаётся в системе, через которую ставятся задачи. У нас, например, изменение требований обязательно должно было отображаться в жире. По коммитам это всё равно затруднительно понять.

Всё равно, Джира это не код.

Хорошо. Вот вы (сторонники одного коммита ту рул зем ол) мне объясните как вы code review смотрите. Есть ПР на 1.5К строк. К нему добавили небольшие правки с помощью --amend. Как вы проверяете этот ПР снова?
Мне достаточно глянуть новый коммит на 10 строк.

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

Я выше писал, почему это плохо.

да вот как-то нет. там есть вот такой вот рассказ:

я просмотрел чей-то ПР, насыпал коментов, и потом захожу — а там нету оригинального кода. Как мне понять теперь, добавил ли он изменения согласно моим комментариям или нет???

оно во-первых, никакого отношения непосредственно к git не имеет, а больше к инфраструктуре, которая работает с этими ПР, во-вторых, тот же GitLab вполне себе переживает rebase и его производные и замечания не рушатся, ровно впрочем как и GitHub

borisych ★★★★★
()
Ответ на: комментарий от borisych

а там нету оригинального кода

Это не имеет отношения к git? Странно.

В Гитлабе можно увидеть удаленные коммиты и сравнить с новыми? Я с Гитлабом работал неоднократно, но у нас тогда историю не переписывал никто.

urxvt ★★★★★
()
Ответ на: комментарий от urxvt

Это не имеет отношения к git? Странно.

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

В Гитлабе можно увидеть удаленные коммиты и сравнить с новыми?

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

borisych ★★★★★
()
Ответ на: комментарий от urxvt

Есть ПР на 1.5К строк. К нему добавили небольшие правки с помощью –amend. Как вы проверяете этот ПР снова?

Такие вещи не делаются. У каждого есть понимание, что можно делать, а что - нельзя.

Если правится, например, замечание от линтера или от человека по стилю кода (типа CamelCase вместо snake_case), то допустимо во время ревью для этого использовать amend.

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

Chiffchaff
()
Ответ на: комментарий от borisych

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

Обсуждения есть в Github/Jira/email/Slack/бумажка. В них теперь ссылка на несуществующий коммит. :)

urxvt ★★★★★
()
|<------ Это мастер с кучей коммитов.
|   |<-- Вот это твоя ветка
o   |
o   |
|   | 
o   (2) Время шло, люди работали и комитили в master ветку
|   |          Накапливались конфликты с твой веткой
|   |
...   
|   |
|   o
o   o
o___/ 
o    \
|     (1) Когда-то ты создал ветку для новой фичи 

Теперь тебе надо просто взять и переместить свои старые комиты на верхушку текущего мастера:

Master
<Head>    =>     Твоя ветка
|                   |
o                   o
o          Master   o
|          <Head>__/ 
o               |         
|               o  
...             o
|   |           |
|   o           o
o   o           |
o___/     => 
o   Твоя             
|   ветка            

Это делает команда git rebase. Что тебе нужно выполнить:

git pull origin master # Поднять самые последние изменения в master
git checkout <твоя ветка>
git rebase master      # Переместить коммиты твоей текущей ветки на вершку мастера (как на рисунке выше)

# rebase накатывает твои коммиты на верхушку один за другим 
# как ты закомитил свои коммиты в той последовательности и накатывает (не все сразу).
# как только конкретный коммит содержит конфликт rebase приостанавливается и ожидает что разработчик решит конфликт

git status -sb         # Увидеть конфликты, конфликтные файлы будут помечены через UU.

# Исправить конфликты, используй какой-нибудь diff тулл

git add -A .
git commit --amend 

git rebase --continue # Ты сообщаешь гит что ты решил конфликт в одном коммите и теперь хочешь продолжить накатить оставшиеся.

# Если будут опять конфликты то повторить (status -sb, резолв и --continue)

# Если не хочешь продолжать есть rebase --abort чтоб все отменить.

Ну и про squash (слитие множества коммитов в один)

git rebase --interactive HEAD~<n>

Где - число коммитов в твоей ветке. Например у тебя 3 коммита и ты хочешь сделать из них один:

git rebase --interactive HEAD~3

Откроется твой любимый текстовый редактор в котором будут эти 3-е коммита

pick a5f4a0d Commit 1 Самый первый
pick 310154e Commit 2
pick f7f3f6d Commit 3 Самый последний

Вот тут заменяешь pick на squash во всех последующих последующих коммитах

pick a5f4a0d Commit 1 Самый первый
squash 310154e Commit 2
squash f7f3f6d Commit 3 Самый последний

Слово squash как раз и говорит git что нужно взять «Commit 2» слить в «Commit 1», затем взять «Commit 3» и опять слить в «Commit 1». Остается только «Commit 1» включающий в себя изменения из «Commit 2» и «Commit 3»

Сохраняешь изменения и выходишь. Git делает squash. Пушишь в свою ветку на ремоут.

anonymous
()
Ответ на: комментарий от urxvt

Обсуждения есть в Github/Jira/email/Slack/бумажка. В них теперь ссылка на несуществующий коммит. :)

ничего не понял… ссылки на коммиты в гитлабе хранятся до потери пульса, т.е. вне зависимости от того что там «чудит» котрибьютор, в гитлабе можно увидеть как именно он чудит. Меж тем ссылаться на них в багтрекере - идея так себе же: там завтра адреса поменяются, еще что и все протухнет, а мы тут переживаем за коммиты какие-то.

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

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

borisych ★★★★★
()