не могу нажать на ветку после перебазирования


мы используем git и имеем главную ветвь и ветви разработчика. Мне нужно добавить новую функцию, а затем перебазировать коммиты на master, а затем нажать master на сервер CI.

проблема в том, что если у меня есть конфликты во время перебазирования, я не могу нажать на свою удаленную ветвь разработчика (на Github) после завершения перебазирования, пока я не вытащу свою удаленную ветвь. Это приводит к дублированию коммитов. Когда нет конфликтов, работает так, как ожидалось.

вопрос: после перебазирования и конфликтов разрешение, Как синхронизировать мои локальные и удаленные ветви разработчика без создания дубликатов коммитов

Setup:

// master branch is the main branch
git checkout master
git checkout -b myNewFeature

// I will work on this at work and at home
git push origin myNewFeature

// work work work on myNewFeature
// master branch has been updated and will conflict with myNewFeature
git pull --rebase origin master

// we have conflicts
// solve conflict
git rebase --continue

//repeat until rebase is complete
git push origin myNewFeature

//ERROR
error: failed to push some refs to 'git@github.com:ariklevy/dropLocker.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

// do what git says and pull
git pull origin myNewFeature

git push origin myNewFeature

// Now I have duplicate commits on the remote branch myNewFeature

EDIT

так что похоже, что это нарушит рабочий процесс:

developer1 работает над myNewFeature developer2 работает над своей новой жизнью оба используют master в качестве основной ветви

developer2 объединяет myNewFeature в hisNewFeature

developer1 перебазирует, разрешает конфликты, затем силой нажимает на удаленную ветку для myNewFeature

через пару дней developer2 снова сливает myNewFeature в hisNewFeature

это заставит других разработчиков ненавидеть developer1?

5 89

5 ответов:

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

o-----o-----o-----o-----o-----o       master
 \
   o-----o-----o                      devel0
                \
                  o-----o-----o       devel1

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

 git fetch origin
 git checkout master
 git merge --ff origin/master

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

затем, когда remote имеет изменения, и я быстро переадресовал к последнему, я перебазирую:

git checkout devel0
git rebase master
git push -f origin devel0

другие разработчики тогда знаю, что им нужно будет перебазировать свои ветви devel с моего последнего:

git fetch <remote>
git checkout devel1
git rebase <remote>/devel0

что приводит к гораздо более чистой истории:

o-----o                                 master
       \
         o-----o-----o                  devel0
                      \
                        o-----o-----o   devel1

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

также похоже, что другие разработчики могут делать коммиты для ваших ветвей devel. Вы можете это подтвердить?

единственное время для слияния-это когда ваша ветвь темы готова к принятию в master.

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

git branch 'my-name/devel-branch'

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

вам нужно заставить толчок, когда вы переместили коммиты дальше по линии, git ожидает, что вы добавите коммиты к кончику ветви. git push -f origin myNewFeature исправит вашу проблему.

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

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

тяга будет в основном делать две вещи: извлечение и слияние. Когда вы включаете --rebase, он будет делать rebase вместо слияния.

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

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

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

Это потребует от вас, чтобы нажать перебазированные изменения время от времени либо с помощью силы:

git push -f origin newfeature

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

git push origin :newfeature
git push origin newfeature

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

помните, что вы почти всегда можете отступить на Git GC, воспользовавшись:

git reflog

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

вам нужно выполнить принудительный толчок, т. е. git push -f origin myNewFeature

О, и вам лучше убедиться, что люди ничего не основывают на вашей ветке dev - обычно вы не должны публиковать ветви, где вы переписываете историю вообще (или, скорее, не переписываете историю после публикации). Один из способов будет использовать имя ветви, как wip/myNewFeature а потом отметить, что wip филиалы будут перебазированы в мастер время от времени.

общий ответ, который уже был дан - использовать git push -f origin myNewFeature при нажатии перебазированных изменений -- это хорошее место для начала. Я пишу этот ответ, чтобы обратиться к редактированию о том, нарушит ли он ваш рабочий процесс.

если мы предполагаем, что вы собираетесь использовать git pull --rebase ... (или некоторые вариации на этот счет) с последующим принудительным нажатием на удаленную ветку, то вещь, которая нарушает рабочий процесс в вашем примере developer2 сливается myNewFeature на hisNewFeature. Имеет смысл быть возможность перебазировать свою собственную ветвь функций, пока никто другой не работает над этой ветвью, поэтому вам нужны правила для демаркации территории ветви.

вы можете обойти это, установив правило, которое вы только когда-либо сливаете из master, или б) создание коллектива develop ветка, на которой вы основываете свой собственный myNewFeature филиала, и установить правило, что вы только когда-либо слиться с develop. master будут зарезервированы только для вех или релизов (или как еще вы хотите установить это вверх), и develop будет, где вы нажимаете каждую функцию, когда она будет готова к интеграции в другие ветви функций.

Я считаю, что это можно считать упрощенной версией рабочего процесса Gitflow.