Git pull --rebase генерирует конфликтный цикл - PullRequest
0 голосов
/ 04 мая 2018

Я уверен, что делаю что-то не так, но вот что происходит.

У моей команды есть ветвь Develop , из которой мы разветвляемся, чтобы создать Feature Branch.

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

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

  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.

Я вытащил из него (без перебазирования) и столкнулся с БОЛЕЕ конфликтами, которые я решаю.

Теперь я могу нажать на функцию.

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

Что-нибудь, что я тут испортил?

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Я попытаюсь собрать воедино команды.

  • git checkout feature
  • git pull --rebase origin develop
  • исправьте конфликты, завершите ребазинг
  • git push

В этот момент вы получите что-то вроде этого.

To github.com:org/repo.git
 ! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to 'git@github.com:org/repo.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

Подсказка неверна , git pull здесь неправильно. Вместо этого вы должны git push --force перезаписать вышестоящий feature своим собственным. Это потому, что вы переписали ветку feature и она расходится с восходящей.

Вот что произошло более подробно. В начале все выглядело примерно так. Обратите внимание, что вышестоящий origin/feature и ваш локальный feature находятся на одном и том же коммите.

                      [origin/develop]
A - B - C - D - E - F [develop]
            \
             G - H - I [feature]
                       [origin/feature]

После того, как git pull --rebase origin develop и все конфликты были исправлены, ваш репозиторий выглядел следующим образом.

                    [origin/develop]
                    [develop]
A - B - C - D - E - F - G1 - H1 - I1 [feature]
            \
             G - H - I [origin/feature]

rebase не переписывает коммиты. Он создает новые и делает вид, что так было всегда. Теперь feature и origin/feature имеют расходящиеся , что означает, что один не является предком другого.

При попытке git push ваш feature Git отказывается. Это не просто вопрос перемещения origin/feature по нескольким коммитам, называемый «ускоренной перемоткой вперед». Потребуется объединение, и git push не сделает этого по соображениям безопасности. Ваша работа, похоже, отличается от от всех остальных. push рискует перевалить за работу других людей в той же ветке.

Вот почему git push --force необходим. В любом случае, он говорит Git сделать это, поставив origin/feature на commit I1. После git push --force у вас будет это.

                    [origin/develop]
                    [develop]
A - B - C - D - E - F - G1 - H1 - I1 [feature]
            \                        [origin/feature]
             G - H - I

Теперь все хорошо. Ваша feature работа такова, как если бы она была на вершине develop все время.

Если вы снова git pull --rebase origin develop и на develop нет новых коммитов, ничего не должно произойти. Если есть новые коммиты, вам придется иметь дело только с ними.

0 голосов
/ 04 мая 2018

Когда вы перебазируете ветку на другую ветку, вы обычно переписываете историю этой ветки. В результате нормальный push не удастся, потому что Git будет думать, что ваша ветвь отличается от того, что находится на удаленном компьютере. Вместо этого:

git push origin feature

Вы должны были сделать это:

git push --force origin feature

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

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

develop: ... A -- B
              \
feature:        C

Поскольку вы разветвились feature из develop, вы добавили новый C коммит. Кроме того, кто-то еще (возможно, вы тоже) добавил B коммит к develop. Теперь вы перебазируете feature на develop:

develop: ... A -- B
                   \
feature              C'

Сравните новый feature с тем, который вы использовали перед перебазированием. Ваш новый C' коммит теперь находится на вершине новой базы, B коммит, и когда вы нажмете, Git отклонит его. Git увидит общего A предка коммита, но не будет знать, как применить новый коммит, не без слияния, которое бы победило точку перебазирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...