Правильный способ продолжения, когда вверх по течению идет впереди от неполного PR?
ВСТУПЛЕНИЕ
Я разветкил репозиторий, который следует за так называемым "потоком git" и должен развить /master/factory branch. Теперь я расскажу о своей вилке как о origin
а о главном репозитории - о upstream
.
После открытия вопроса и обсуждения/согласования нескольких вещей с сопровождающим репо я начал над этим работать. Первое, что я сделал, это создание отслеживания ветвей функций (origin/develop).
После нескольких временных коммитов с временными отброшенными временными плохими именами я создал PR и нажал. Идея, которую я имел в виду, в конечном итоге раздавила все мои коммиты на одном, а затем предоставила правильное имя/описание фиксации, чтобы сопровождающий мог объединить все это для восходящего/развивающегося без каких-либо проблем, моя главная цель заключалась в том, чтобы весь процесс был как можно более гладким как для меня, так и для поддерживающего вверх по течению, после того как я слился, я бы с радостью удалил свою локальную ветку, работу, легкое peasy... :)
ПРОБЛЕМА
Я наивно думал, что это будет так гладко!
Я не специалист по git, и я ошибался, думая, что PR будет развиваться так гладко (это, как правило, происходит, когда вы не знаете, какие инструменты вы используете). В какой-то момент я прекратил работать над своим PR в течение нескольких дней, и, очевидно, вверх по течению/развитию продолжал развиваться и уходить далеко впереди моего PR, мой PR еще не проходил тесты, и весь PR все еще находился на рассмотрении незавершенной работы,
Несколько дней спустя я решил вернуться к этому PR и попытался возобновить свою работу, после того, как я собрал вверх/вверх, я видел, что многие предвыборные коммиты были уже далеко впереди от моего PR, и я действительно не знал, что было лучшим выбор в этой конкретной ситуации, я не знал, и я до сих пор не знаю, является ли слияние или переустановка лучшим выбором...
Не имея достаточных знаний о возможных последствиях слияния или переупаковки, я решил, что слияние не может быть настолько плохим, и в конечном итоге все можно будет убрать. Ну, в результате, после слияния и подталкивания еще нескольких временных моментов моя местная история стала немного беспорядочной, и я действительно не знаю, можно ли ее как-то очистить, не испортив историю восходящего потока.
Скажем, история выглядит примерно так: PR = c1-> c2 → c3-> upstream1 → upstream2-> upstream3 → c4-> c5. В этом примере c1..c6 будет моим локальным изменением, а вверх по потоку1. Upstream3 будет двигаться вперед от восходящего потока.
ВОПРОСЫ
- Было ли мое решение слиться с действительно плохим выбором, когда вверх по течению очень далеко от моего незавершенного PR? Что было бы лучшим способом в этом случае? Подумайте, что моя цель состоит в том, что один раздавленный коммит, объединенный в вверх по течению, в конечном итоге
- Как только вред будет нанесен, и я объединился после решения конфликтов и создал еще несколько коммитов, все равно можно было бы обеспечить чистый PR всего лишь одним разомкнутым фиксатором без перезаписи истории восходящего потока?
Я думаю, что весь поток можно было бы суммировать, спросив, как лучше всего действовать, когда восходящий поток удаляется от вашего незавершенного PR, который содержит несколько временных коммитов.
Ответы
Ответ 1
Я расскажу, что я делаю в таком случае. Этот подход очень практичен, и, возможно, разные люди имеют разные личные предпочтения.
Я также, как и вы, стараюсь, чтобы сквош фиксировал 1 фиксацию в PR.
Итак, скажем, есть ветвь dev
.
Когда я запускаю ветвь функции, я делаю:
>> git checkout dev
>> git pull
>> git checkout -b feature_branch
>> commitA
>> commitB
>> git push -u origin feature_branch // now there is origin/feature_branch available to everyone
>> and create a PR when I'm ready
Теперь процесс выглядит следующим образом:
Люди просматривают мою работу и комментируют, я делаю свои изменения и совершаю. Это своего рода цикл, он заканчивается тем, что мы все довольны этими изменениями и готовы объединить все
>> commitC
>> commitD
Итак, теперь я готов "раздавить свои коммиты в один". Так я и делаю:
>> // make sure I'm on feature_branch
>> git rebase -i HEAD~4
>> // at this point I have one 'beautiful' commit, lets_call it commit_TO_GO
>> git push -f //forcefully push my commits by overriding the current state of a remote branch in PR, this is not really important, only if I want to "preserve this state for backup or something
Пока эта ветка не слита, я не против делать это, это не имеет значения.
Предположим, что этот процесс занял некоторое время, а между тем есть некоторые новые коммиты в ветке origin/dev
(commitX, commitY и commitZ), сделанные другими товарищами по команде.
Итак, теоретически я могу теперь сделать следующее: Объединить, применяя регулярное трехстороннее слияние, если есть конфликты, мне придется сначала их разрешить.
Однако, поскольку меня беспокоит история коммитов (как и вы), я делаю следующее:
>> git fetch --all
>> git rebase origin/dev
>> // at this point The my commit_TO_GO is applied on top of commitX,commitY,commitZ.
>> // technically it has a different sha1 now, but it not really important, its
>> still my own branch, I do whatever I want there :)
>> git push -f // again forcefully push to origin/feature_branch
После этого шага origin/feature_branch
- это FF из origin/dev
, что классно, потому что я могу применить слияние, и он будет в режиме FF, даже объединение слияния не будет создано.
Конечно, если есть конфликты, rebase не будет работать, мне придется сначала разрешить конфликты. Я делаю это в своей среде IDE, а затем продолжаю rebase (git rebase --continue
), но разрешение конфликтов выходит за рамки этого вопроса
Теперь я готов объединить свое изменение обратно в origin/dev
Обычно я делаю это в пользовательском интерфейсе bitbucket/github.
После слияния история origin/dev
выглядит красиво:
commitX->commitY->commitZ->commit_TO_GO
Результат: никакое слияние не фиксируется вообще, моя единственная фиксация применяется последним
Один вопрос:
Его не стоит ничего переустанавливать из ветки dev даже во время вашего развития (пока вы работаете над feature_branch), просто чтобы убедиться, что он содержит последние изменения. Таким образом, вы можете пройти через цикл столько раз, сколько хотите:
>> git fetch --all
>> git rebase origin/dev
Я понимаю, что, возможно, у Гита есть более "короткие команды" вверх по рукавам, и, возможно, это объяснение было слишком подробным.
Ответ 2
Что касается конечных результатов, то слияние и перезагрузка одинаковы... Однако с точки зрения итоговой истории и того, насколько легко было бы перемещаться по вашей работе "изолированно", они различны... Если вы работаете, затем сливаетесь, затем работайте больше... Затем сливайтесь... Затем работайте еще и так далее, очень сложно увидеть все изменения, которые составляют работу этой функции в одиночку.
Все это сказать: просто перебазируйте. Что делать? Перейдите к контенту upstream/develop, cherry - выберите реальные версии, которые составляют работу функции (без слияний)... Таким образом, вы очистили ветку... Установите локальный указатель на эту точку и продолжайте работать... Если будет проведена дополнительная работа над восходящим/развивающимся, то переформатируйте ее поверх нее.
Ответ 3
Как упоминалось выше, я решил использовать git rebase
как git rebase
ниже.
topic
Ваш запрос тянуть и в то же время master
ветки участвует с другой фиксаций.
A---B---C topic
/
D---E---F---G master
rebase
означает изменение предыдущей базы, которая также изменяет историю вашей ветки.
A'--B'--C' topic
/
D---E---F---G master
В результате вам нужно принудительно нажать на удаленную ветку. Поскольку никто раньше не объединил ваш PR, он в порядке и не влияет на ваших сотрудников.
Вы можете прочитать более подробную информацию о rebase здесь: Pro Git v2, Git Branching - Rebasing и команда git-rebase.